diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e82d916 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +backend/package-lock.json diff --git a/.zed/debug.json b/.zed/debug.json new file mode 100644 index 0000000..55e62c9 --- /dev/null +++ b/.zed/debug.json @@ -0,0 +1,15 @@ +[ + { + "label": "PHP: Listen to Xdebug", + "adapter": "Xdebug", + "request": "launch", + "port": 9003, + }, + { + "label": "PHP: Debug this test", + "adapter": "Xdebug", + "request": "launch", + "program": "vendor/bin/phpunit", + "args": ["--filter", "$ZED_SYMBOL"], + }, +] diff --git a/backend/.env.example b/backend/.env.example index 4b28161..0c08d0d 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -4,7 +4,7 @@ APP_KEY= APP_DEBUG=true APP_URL=http://localhost FRONTEND_URL="http://localhost:4200,http://127.0.0.1:4200" -SANCTUM_STATEFUL_DOMAINS="${FRONTEND_URL}" +SANCTUM_STATEFUL_DOMAINS=localhost:4200,127.0.0.1:4200 APP_LOCALE=en APP_FALLBACK_LOCALE=en diff --git a/backend/artisan b/backend/artisan index c35e31d..10e47c0 100755 --- a/backend/artisan +++ b/backend/artisan @@ -1,18 +1,18 @@ #!/usr/bin/env php handleCommand(new ArgvInput); +$status = $app->handleCommand(new ArgvInput()); exit($status); + diff --git a/backend/composer.json b/backend/composer.json index 6c680c0..a63e856 100644 --- a/backend/composer.json +++ b/backend/composer.json @@ -18,6 +18,7 @@ }, "require-dev": { "fakerphp/faker": "^1.23", + "larastan/larastan": "^3.0", "laravel/pail": "^1.2.5", "mockery/mockery": "^1.6", "nunomaduro/collision": "^8.6", diff --git a/backend/composer.lock b/backend/composer.lock index 0efcfc3..19b9857 100644 --- a/backend/composer.lock +++ b/backend/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ce000f2979a5d252cefadab87899a5fc", + "content-hash": "3edf1e72a6c813ae77e28811f4fa4c1e", "packages": [ { "name": "aws/aws-crt-php", @@ -6982,6 +6982,47 @@ }, "time": "2025-04-30T06:54:44+00:00" }, + { + "name": "iamcal/sql-parser", + "version": "v0.7", + "source": { + "type": "git", + "url": "https://github.com/iamcal/SQLParser.git", + "reference": "610392f38de49a44dab08dc1659960a29874c4b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/iamcal/SQLParser/zipball/610392f38de49a44dab08dc1659960a29874c4b8", + "reference": "610392f38de49a44dab08dc1659960a29874c4b8", + "shasum": "" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^1.0", + "phpunit/phpunit": "^5|^6|^7|^8|^9" + }, + "type": "library", + "autoload": { + "psr-4": { + "iamcal\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Cal Henderson", + "email": "cal@iamcal.com" + } + ], + "description": "MySQL schema parser", + "support": { + "issues": "https://github.com/iamcal/SQLParser/issues", + "source": "https://github.com/iamcal/SQLParser/tree/v0.7" + }, + "time": "2026-01-28T22:20:33+00:00" + }, { "name": "jean85/pretty-package-versions", "version": "2.1.1", @@ -7042,6 +7083,96 @@ }, "time": "2025-03-19T14:43:43+00:00" }, + { + "name": "larastan/larastan", + "version": "v3.9.6", + "source": { + "type": "git", + "url": "https://github.com/larastan/larastan.git", + "reference": "9ad17e83e96b63536cb6ac39c3d40d29ff9cf636" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/larastan/larastan/zipball/9ad17e83e96b63536cb6ac39c3d40d29ff9cf636", + "reference": "9ad17e83e96b63536cb6ac39c3d40d29ff9cf636", + "shasum": "" + }, + "require": { + "ext-json": "*", + "iamcal/sql-parser": "^0.7.0", + "illuminate/console": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/container": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/contracts": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/database": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/http": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/pipeline": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/support": "^11.44.2 || ^12.4.1 || ^13", + "php": "^8.2", + "phpstan/phpstan": "^2.1.44" + }, + "require-dev": { + "doctrine/coding-standard": "^13", + "laravel/framework": "^11.44.2 || ^12.7.2 || ^13", + "mockery/mockery": "^1.6.12", + "nikic/php-parser": "^5.4", + "orchestra/canvas": "^v9.2.2 || ^10.0.1 || ^11", + "orchestra/testbench-core": "^9.12.0 || ^10.1 || ^11", + "phpstan/phpstan-deprecation-rules": "^2.0.1", + "phpunit/phpunit": "^10.5.35 || ^11.5.15 || ^12.5.8" + }, + "suggest": { + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench", + "phpmyadmin/sql-parser": "Install to enable Larastan's optional phpMyAdmin-based SQL parser automatically" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Larastan\\Larastan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Can Vural", + "email": "can9119@gmail.com" + } + ], + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel", + "keywords": [ + "PHPStan", + "code analyse", + "code analysis", + "larastan", + "laravel", + "package", + "php", + "static analysis" + ], + "support": { + "issues": "https://github.com/larastan/larastan/issues", + "source": "https://github.com/larastan/larastan/tree/v3.9.6" + }, + "funding": [ + { + "url": "https://github.com/canvural", + "type": "github" + } + ], + "time": "2026-04-16T10:02:43+00:00" + }, { "name": "laravel/pail", "version": "v1.2.6", @@ -8165,6 +8296,59 @@ }, "time": "2026-01-25T14:56:51+00:00" }, + { + "name": "phpstan/phpstan", + "version": "2.1.54", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "reference": "8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2026-04-29T13:31:09+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "12.5.6", diff --git a/backend/phpstan.neon b/backend/phpstan.neon new file mode 100644 index 0000000..4cc5086 --- /dev/null +++ b/backend/phpstan.neon @@ -0,0 +1,17 @@ +includes: + - vendor/larastan/larastan/extension.neon + - vendor/nesbot/carbon/extension.neon + +parameters: + + paths: + - app/ + + # Level 10 is the highest level + level: 8 + +# ignoreErrors: +# - '#PHPDoc tag @var#' +# +# excludePaths: +# - ./*/*/FileToBeExcluded.php diff --git a/backend/routes/api.php b/backend/routes/api.php index 9aacac7..1ebca80 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -5,9 +5,9 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; -Route::get('/me', function (Request $request) { +Route::get("/me", function (Request $request) { return $request->user(); -})->middleware('auth:sanctum'); +})->middleware("auth:sanctum"); -Route::apiResource('chats', ChatController::class); -Route::apiResource('chats.messages', ChatMessageController::class); +Route::apiResource("chats", ChatController::class); +Route::apiResource("chats.messages", ChatMessageController::class); diff --git a/frontend/src/app/core/layout/sidebar/initials-pipe.spec.ts b/frontend/src/app/core/layout/sidebar/initials-pipe.spec.ts new file mode 100644 index 0000000..24b2e17 --- /dev/null +++ b/frontend/src/app/core/layout/sidebar/initials-pipe.spec.ts @@ -0,0 +1,8 @@ +import { InitialsPipe } from './initials-pipe'; + +describe('InitialsPipe', () => { + it('create an instance', () => { + const pipe = new InitialsPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/core/layout/sidebar/initials-pipe.ts b/frontend/src/app/core/layout/sidebar/initials-pipe.ts new file mode 100644 index 0000000..73db5fe --- /dev/null +++ b/frontend/src/app/core/layout/sidebar/initials-pipe.ts @@ -0,0 +1,17 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'initials', +}) +export class InitialsPipe implements PipeTransform { + transform(value: string, separator: string = ' ', wordCount: number = 1): string { + if (!value) return ''; + const parts = value.split(separator); + + let result = ''; + for (let i = 0; i < wordCount; i++) { + result += parts[i][0].toUpperCase(); + } + return result; + } +} diff --git a/frontend/src/app/core/layout/sidebar/sidebar.html b/frontend/src/app/core/layout/sidebar/sidebar.html index 62fc961..698dd3a 100644 --- a/frontend/src/app/core/layout/sidebar/sidebar.html +++ b/frontend/src/app/core/layout/sidebar/sidebar.html @@ -25,7 +25,7 @@