wip
This commit is contained in:
parent
7a2c1f03fa
commit
9853c6128c
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
backend/package-lock.json
|
||||
15
.zed/debug.json
Normal file
15
.zed/debug.json
Normal file
@ -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"],
|
||||
},
|
||||
]
|
||||
@ -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
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Application;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
define("LARAVEL_START", microtime(true));
|
||||
|
||||
// Register the Composer autoloader...
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
require __DIR__ . "/vendor/autoload.php";
|
||||
|
||||
// Bootstrap Laravel and handle the command...
|
||||
/** @var Application $app */
|
||||
$app = require_once __DIR__.'/bootstrap/app.php';
|
||||
$app = require_once __DIR__ . "/bootstrap/app.php";
|
||||
|
||||
$status = $app->handleCommand(new ArgvInput);
|
||||
$status = $app->handleCommand(new ArgvInput());
|
||||
|
||||
exit($status);
|
||||
|
||||
|
||||
@ -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",
|
||||
|
||||
186
backend/composer.lock
generated
186
backend/composer.lock
generated
@ -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",
|
||||
|
||||
17
backend/phpstan.neon
Normal file
17
backend/phpstan.neon
Normal file
@ -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
|
||||
@ -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);
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
import { InitialsPipe } from './initials-pipe';
|
||||
|
||||
describe('InitialsPipe', () => {
|
||||
it('create an instance', () => {
|
||||
const pipe = new InitialsPipe();
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
});
|
||||
17
frontend/src/app/core/layout/sidebar/initials-pipe.ts
Normal file
17
frontend/src/app/core/layout/sidebar/initials-pipe.ts
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,7 @@
|
||||
<div class="flex items-center justify-between px-4 pt-5 pb-4 border-b border-[#1e2f4d]">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div
|
||||
class="w-8 h-8 rounded-full bg-linear-to-br from-[#00f2fe] to-[#4facfe] flex items-center justify-center font-semibold text-xl shadow-[0_0_20px_rgba(79,172,254,0.4)] animate-[pulse_2s_infinite]"
|
||||
class="w-8 h-8 rounded-full bg-linear-to-br from-[#00f2fe] to-[#4facfe] flex items-center justify-center font-semibold shadow-[0_0_20px_rgba(79,172,254,0.4)] animate-[pulse_2s_infinite]"
|
||||
>
|
||||
AI
|
||||
</div>
|
||||
@ -63,7 +63,7 @@
|
||||
<div class="px-3 pt-3 pb-2">
|
||||
<button
|
||||
(click)="newChat()"
|
||||
class="w-full flex items-center justify-center gap-2 py-2.5 px-4 rounded-xl bg-[#2d5be3] hover:bg-[#3468f0] text-white text-sm font-medium transition-all duration-200 shadow-md hover:shadow-[#2d5be3]/30 hover:shadow-lg active:scale-[0.98]"
|
||||
class="w-full flex items-center justify-center gap-2 py-2.5 px-4 rounded-xl bg-[#2d5be3] hover:bg-[#3468f0] text-white text-sm font-medium transition-all duration-200 shadow-md hover:shadow-[#2d5be3]/30 hover:shadow-lg"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -108,13 +108,15 @@
|
||||
<!-- Chat Items -->
|
||||
<div class="space-y-0.5">
|
||||
@for (chat of chatStore.chats(); track chat.id) {
|
||||
<button (click)="selectChat(chat)" [class]="chatItemClasses(chat)">
|
||||
<button (click)="selectChat(chat.id)" [class]="chatItemClasses(chat)">
|
||||
<!-- Active indicator -->
|
||||
@if(activeChatId() && activeChatId() === chat.id){
|
||||
<div
|
||||
class="absolute left-0 top-1/2 -translate-y-1/2 w-0.5 h-6 bg-[#2d5be3] rounded-r-full"
|
||||
></div>
|
||||
}
|
||||
|
||||
<div class="flex items-start gap-2.5 w-full min-w-0">
|
||||
<div class="flex items-center gap-2.5 w-full min-w-0">
|
||||
<!-- Icon -->
|
||||
<div [class]="chatIconClasses(chat)">
|
||||
<svg
|
||||
@ -135,7 +137,7 @@
|
||||
|
||||
<!-- Text -->
|
||||
<div class="flex-1 min-w-0 text-left">
|
||||
<p class="text-xs font-medium truncate text-white">{{ chat.attributes.title }}</p>
|
||||
<p class="text-xs font-medium truncate">{{ chat.attributes.title }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Time -->
|
||||
@ -173,39 +175,67 @@
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="border-t border-[#1e2f4d] px-3 py-3">
|
||||
<div class="flex items-center gap-2.5 transition-all duration-150 group">
|
||||
<div class="flex items-center gap-2.5 transition-all duration-150">
|
||||
@if(authStore.isLoading()) {
|
||||
<p>Loading...</p>
|
||||
} @else if(authStore.user() !== null){
|
||||
<div
|
||||
class="w-7 h-7 rounded-lg bg-linear-to-br from-[#2d5be3] to-[#1a3a9e] flex items-center justify-center text-white text-xs font-bold shrink-0"
|
||||
class="flex items-center hover:bg-black/9 px-4 py-2 rounded-xl w-full gap-2.5 transition-all duration-150"
|
||||
>
|
||||
K
|
||||
<div
|
||||
class="w-7 h-7 rounded-lg bg-linear-to-br from-[#2d5be3] to-[#1a3a9e] flex items-center justify-center text-white text-xs font-bold shrink-0"
|
||||
>
|
||||
{{authStore!.user()!.name | initials}}
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="text-xs font-medium text-[#c8d8f0] truncate">{{authStore!.user()!.name}}</p>
|
||||
<p class="text-[10px] text-[#3a5272] truncate">Free Plan</p>
|
||||
</div>
|
||||
|
||||
<div class="relative flex items-center">
|
||||
<button
|
||||
id="cog"
|
||||
(click)="toggleCogMenu()"
|
||||
class="bg-transparent border-none p-0 cursor-pointer flex items-center justify-center outline-none"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-3.5 h-3.5 text-[#3a5272] hover:text-[#5a80a8] transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
|
||||
/>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
@if(isCogMenuOpen()){
|
||||
<div
|
||||
id="cog-menu"
|
||||
class="bg-black/9 backdrop-blur-sm text-xs text-gray-400 min-w-30 px-2 py-2 rounded-xl absolute right-0 bottom-4"
|
||||
>
|
||||
<ul class="">
|
||||
<li>
|
||||
<button class="w-full py-2 rounded-xl hover:bg-white/4 hover:text-red-400">
|
||||
Logout
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="text-xs font-medium text-[#c8d8f0] truncate">Kushal Saha</p>
|
||||
<p class="text-[10px] text-[#3a5272] truncate">Free Plan</p>
|
||||
</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-3.5 h-3.5 text-[#3a5272] group-hover:text-[#5a80a8] transition-colors"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
|
||||
/>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
||||
/>
|
||||
</svg>
|
||||
} @else{
|
||||
<a
|
||||
routerLink="/user/login"
|
||||
|
||||
@ -3,11 +3,14 @@ import { CommonModule } from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { ChatStore } from '../../../chat/chat.store';
|
||||
import { AuthStore } from '../../../auth/auth.store';
|
||||
import { InitialsPipe } from './initials-pipe';
|
||||
import { JsonApiResource } from '../../types/api';
|
||||
import { Chat } from '../../../chat/chat.types';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sidebar',
|
||||
standalone: true,
|
||||
imports: [CommonModule, RouterModule],
|
||||
imports: [CommonModule, RouterModule, InitialsPipe],
|
||||
templateUrl: 'sidebar.html',
|
||||
styleUrl: 'sidebar.css',
|
||||
})
|
||||
@ -16,7 +19,9 @@ export class Sidebar implements OnInit {
|
||||
protected authStore = inject(AuthStore);
|
||||
|
||||
protected isOpen = signal(true);
|
||||
protected isCogMenuOpen = signal(false);
|
||||
protected searchQuery = signal('');
|
||||
protected activeChatId = signal<string | null>(null);
|
||||
|
||||
ngOnInit() {
|
||||
this.chatStore.fetchChats();
|
||||
@ -29,10 +34,11 @@ export class Sidebar implements OnInit {
|
||||
return this.isOpen() ? base + ' w-64' : base + ' w-0 border-none opacity-0';
|
||||
});
|
||||
|
||||
protected chatItemClasses(chat: any): string {
|
||||
protected chatItemClasses(chat: JsonApiResource<Chat>): string {
|
||||
const base =
|
||||
'relative w-full flex items-center px-2 py-2 rounded-lg transition-all duration-150 cursor-pointer group';
|
||||
return chat.isActive
|
||||
'relative w-full flex items-center justify-center px-2 py-2 rounded-lg transition-all duration-150 cursor-pointer group';
|
||||
|
||||
return this.activeChatId() && chat.id === this.activeChatId()
|
||||
? base + ' bg-[#13213d] text-white'
|
||||
: base + ' hover:bg-[#111a2e] text-[#6a8faf]';
|
||||
}
|
||||
@ -48,18 +54,16 @@ export class Sidebar implements OnInit {
|
||||
this.isOpen.update((v) => !v);
|
||||
}
|
||||
|
||||
protected toggleCogMenu(): void {
|
||||
this.isCogMenuOpen.update((v) => !v);
|
||||
}
|
||||
|
||||
protected newChat(): void {
|
||||
console.log('New chat triggered');
|
||||
}
|
||||
|
||||
protected selectChat(chat: any): void {
|
||||
// this.activeChatId.set(chat.id);
|
||||
// this.sections.update((sections) =>
|
||||
// sections.map((section) => ({
|
||||
// ...section,
|
||||
// chats: section.chats.map((c) => ({ ...c, isActive: c.id === chat.id })),
|
||||
// })),
|
||||
// );
|
||||
protected selectChat(chatId: string): void {
|
||||
this.activeChatId.set(chatId);
|
||||
}
|
||||
|
||||
protected onSearch(event: Event): void {
|
||||
|
||||
@ -14,3 +14,8 @@ body {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
background: radial-gradient(circle at top right, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
|
||||
}
|
||||
button:active {
|
||||
transform: scale(0.98);
|
||||
transition: scale;
|
||||
transition-duration: 200ms;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user