From c8541408fdaefcd3c05adfe59be2bdfa6e5081b5 Mon Sep 17 00:00:00 2001 From: Bilal Dieumegard Date: Sun, 1 Dec 2024 22:27:49 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20des=20requetes=20=C3=A0=20l'api=20des?= =?UTF-8?q?=20channels=20et=20de=20l'affichage=20dans=20la=20page=20chats.?= =?UTF-8?q?=20Ajout=20de=20la=20librairie=20socket.io.=20Modification=20le?= =?UTF-8?q?g=C3=A9re=20de=20l'api.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 11 +- pnpm-lock.yaml | 116 +++++----- prisma/schema.prisma | 26 +-- src/lib/components/ui/ChatItem.svelte | 7 +- src/lib/components/ui/CreateChat.svelte | 27 ++- src/lib/utils/date.ts | 51 +++++ src/routes/api/canal/[id]/+page.server.ts | 123 ----------- .../api/canal/[id]/messages/+page.server.ts | 149 ------------- src/routes/api/canals/+page.server.ts | 47 ---- src/routes/api/canals/+server.ts | 77 +++++-- src/routes/api/user/[id]/+page.server.ts | 200 ------------------ src/routes/api/user/[id]/+server.ts | 32 +-- src/routes/api/users/+page.server.ts | 87 -------- src/routes/api/users/+server.ts | 24 +++ src/routes/chats/+page.svelte | 12 +- src/routes/chats/+page.ts | 22 ++ vite.config.ts | 19 +- 17 files changed, 296 insertions(+), 734 deletions(-) create mode 100644 src/lib/utils/date.ts delete mode 100644 src/routes/api/canal/[id]/+page.server.ts delete mode 100644 src/routes/api/canal/[id]/messages/+page.server.ts delete mode 100644 src/routes/api/canals/+page.server.ts delete mode 100644 src/routes/api/user/[id]/+page.server.ts delete mode 100644 src/routes/api/users/+page.server.ts create mode 100644 src/routes/chats/+page.ts diff --git a/package.json b/package.json index 1b0a8e5..2b34912 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "prettier": "^3.3.2", "prettier-plugin-svelte": "^3.2.6", "prettier-plugin-tailwindcss": "^0.6.5", + "prisma": "^6.0.0", "svelte": "^5.0.0", "svelte-check": "^4.0.0", "tailwind-merge": "^2.5.5", @@ -36,14 +37,14 @@ "vite": "^5.0.3" }, "dependencies": { - "lucide-svelte": "^0.462.0", - "multer": "^1.4.5-lts.1", - "svelte-radix": "^2.0.1" - "@prisma/client": "^5.22.0", + "@prisma/client": "^6.0.0", "@types/node": "^22.10.1", "argon2": "^0.41.1", - "prisma": "^5.22.0", + "lucide-svelte": "^0.462.0", + "multer": "^1.4.5-lts.1", "redis": "^4.7.0", + "socket.io": "^4.8.1", + "socket.io-client": "^4.8.1", "svelte-radix": "^2.0.1", "winston": "^3.17.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8cc1f9b..cdd1989 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,24 +8,21 @@ importers: .: dependencies: - lucide-svelte: - specifier: ^0.462.0 - version: 0.462.0(svelte@5.2.7) - multer: - specifier: ^1.4.5-lts.1 - version: 1.4.5-lts.1 '@prisma/client': - specifier: ^5.22.0 - version: 5.22.0(prisma@5.22.0) + specifier: ^6.0.0 + version: 6.0.0(prisma@6.0.0) '@types/node': specifier: ^22.10.1 version: 22.10.1 argon2: specifier: ^0.41.1 version: 0.41.1 - prisma: - specifier: ^5.22.0 - version: 5.22.0 + lucide-svelte: + specifier: ^0.462.0 + version: 0.462.0(svelte@5.2.7) + multer: + specifier: ^1.4.5-lts.1 + version: 1.4.5-lts.1 redis: specifier: ^4.7.0 version: 4.7.0 @@ -78,6 +75,9 @@ importers: prettier-plugin-tailwindcss: specifier: ^0.6.5 version: 0.6.9(prettier-plugin-svelte@3.3.2(prettier@3.3.3)(svelte@5.2.7))(prettier@3.3.3) + prisma: + specifier: ^6.0.0 + version: 6.0.0 svelte: specifier: ^5.0.0 version: 5.2.7 @@ -374,29 +374,29 @@ packages: '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} - '@prisma/client@5.22.0': - resolution: {integrity: sha512-M0SVXfyHnQREBKxCgyo7sffrKttwE6R8PMq330MIUF0pTwjUhLbW84pFDlf06B27XyCR++VtjugEnIHdr07SVA==} - engines: {node: '>=16.13'} + '@prisma/client@6.0.0': + resolution: {integrity: sha512-tOBhG35ozqZ/5Y6B0TNOa6cwULUW8ijXqBXcgb12bfozqf6eGMyGs+jphywCsj6uojv5lAZZnxVSoLMVebIP+g==} + engines: {node: '>=18.18'} peerDependencies: prisma: '*' peerDependenciesMeta: prisma: optional: true - '@prisma/debug@5.22.0': - resolution: {integrity: sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==} + '@prisma/debug@6.0.0': + resolution: {integrity: sha512-eUjoNThlDXdyJ1iQ2d7U6aTVwm59EwvODb5zFVNJEokNoSiQmiYWNzZIwZyDmZ+j51j42/0iTaHIJ4/aZPKFRg==} - '@prisma/engines-version@5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2': - resolution: {integrity: sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==} + '@prisma/engines-version@5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e': + resolution: {integrity: sha512-JmIds0Q2/vsOmnuTJYxY4LE+sajqjYKhLtdOT6y4imojqv5d/aeVEfbBGC74t8Be1uSp0OP8lxIj2OqoKbLsfQ==} - '@prisma/engines@5.22.0': - resolution: {integrity: sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==} + '@prisma/engines@6.0.0': + resolution: {integrity: sha512-ZZCVP3q22ifN6Ex6C8RIcTDBlRtMJS2H1ljV0knCiWNGArvvkEbE88W3uDdq/l4+UvyvHpGzdf9ZsCWSQR7ZQQ==} - '@prisma/fetch-engine@5.22.0': - resolution: {integrity: sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==} + '@prisma/fetch-engine@6.0.0': + resolution: {integrity: sha512-j2m+iO5RDPRI7SUc7sHo8wX7SA4iTkJ+18Sxch8KinQM46YiCQD1iXKN6qU79C1Fliw5Bw/qDyTHaTsa3JMerA==} - '@prisma/get-platform@5.22.0': - resolution: {integrity: sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==} + '@prisma/get-platform@6.0.0': + resolution: {integrity: sha512-PS6nYyIm9g8C03E4y7LknOfdCw/t2KyEJxntMPQHQZCOUgOpF82Ma60mdlOD08w90I3fjLiZZ0+MadenR3naDQ==} '@redis/bloom@1.2.0': resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==} @@ -1076,7 +1076,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} @@ -1107,13 +1106,13 @@ packages: is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1481,9 +1480,9 @@ packages: prism-svelte@0.4.7: resolution: {integrity: sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==} - prisma@5.22.0: - resolution: {integrity: sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==} - engines: {node: '>=16.13'} + prisma@6.0.0: + resolution: {integrity: sha512-RX7KtbW7IoEByf7MR32JK1PkVYLVYFqeODTtiIX3cqekq1aKdsF3Eud4zp2sUShMLjvdb5Jow0LbUjRq5LVxPw==} + engines: {node: '>=18.18'} hasBin: true prismjs@1.29.0: @@ -1505,6 +1504,7 @@ packages: readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -1546,6 +1546,7 @@ packages: safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -1584,11 +1585,12 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - stack-trace@0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -1600,6 +1602,7 @@ packages: string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -1823,6 +1826,7 @@ packages: xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} + yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} @@ -2050,30 +2054,30 @@ snapshots: '@polka/url@1.0.0-next.28': {} - '@prisma/client@5.22.0(prisma@5.22.0)': + '@prisma/client@6.0.0(prisma@6.0.0)': optionalDependencies: - prisma: 5.22.0 + prisma: 6.0.0 - '@prisma/debug@5.22.0': {} + '@prisma/debug@6.0.0': {} - '@prisma/engines-version@5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2': {} + '@prisma/engines-version@5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e': {} - '@prisma/engines@5.22.0': + '@prisma/engines@6.0.0': dependencies: - '@prisma/debug': 5.22.0 - '@prisma/engines-version': 5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2 - '@prisma/fetch-engine': 5.22.0 - '@prisma/get-platform': 5.22.0 + '@prisma/debug': 6.0.0 + '@prisma/engines-version': 5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e + '@prisma/fetch-engine': 6.0.0 + '@prisma/get-platform': 6.0.0 - '@prisma/fetch-engine@5.22.0': + '@prisma/fetch-engine@6.0.0': dependencies: - '@prisma/debug': 5.22.0 - '@prisma/engines-version': 5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2 - '@prisma/get-platform': 5.22.0 + '@prisma/debug': 6.0.0 + '@prisma/engines-version': 5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e + '@prisma/get-platform': 6.0.0 - '@prisma/get-platform@5.22.0': + '@prisma/get-platform@6.0.0': dependencies: - '@prisma/debug': 5.22.0 + '@prisma/debug': 6.0.0 '@redis/bloom@1.2.0(@redis/client@1.6.0)': dependencies: @@ -2782,9 +2786,10 @@ snapshots: dependencies: '@types/estree': 1.0.6 - isarray@1.0.0: {} is-stream@2.0.1: {} + isarray@1.0.0: {} + isexe@2.0.0: {} jackspeak@3.4.3: @@ -3049,9 +3054,9 @@ snapshots: prism-svelte@0.4.7: {} - prisma@5.22.0: + prisma@6.0.0: dependencies: - '@prisma/engines': 5.22.0 + '@prisma/engines': 6.0.0 optionalDependencies: fsevents: 2.3.3 @@ -3075,9 +3080,12 @@ snapshots: process-nextick-args: 2.0.1 safe-buffer: 5.1.2 string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 + string_decoder: 1.3.0 util-deprecate: 1.0.2 readdirp@3.6.0: @@ -3138,6 +3146,7 @@ snapshots: mri: 1.2.0 safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safe-stable-stringify@2.5.0: {} @@ -3166,9 +3175,10 @@ snapshots: source-map-js@1.2.1: {} - streamsearch@1.1.0: {} stack-trace@0.0.10: {} + streamsearch@1.1.0: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -3184,6 +3194,7 @@ snapshots: string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -3422,6 +3433,7 @@ snapshots: strip-ansi: 7.1.0 xtend@4.0.2: {} + yallist@4.0.0: {} yaml@1.10.2: {} diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f8fda22..a020e2c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -14,26 +14,22 @@ datasource db { } model User { - id String @id @default(auto()) @map("_id") @db.ObjectId - username String @unique - surname String - name String - email String @unique - password String - channels Channel[] @relation(fields: [channelIDs], references: [id]) - channelIDs String[] @db.ObjectId - messages Message[] + id String @id @default(auto()) @map("_id") @db.ObjectId + username String @unique + surname String + name String + email String @unique + password String + messages Message[] @@map("users") // Table name in DB } model Channel { - id String @id @default(auto()) @map("_id") @db.ObjectId - name String - topic String - users User[] @relation(fields: [userIDs], references: [id]) - userIDs String[] @db.ObjectId - messages Message[] + id String @id @default(auto()) @map("_id") @db.ObjectId + name String @unique + messages Message[] + createdAt DateTime @default(now()) @@map("channels") // Table name in DB } diff --git a/src/lib/components/ui/ChatItem.svelte b/src/lib/components/ui/ChatItem.svelte index 5afb5ee..faa6d67 100644 --- a/src/lib/components/ui/ChatItem.svelte +++ b/src/lib/components/ui/ChatItem.svelte @@ -1,19 +1,20 @@ -
+

{title}

{lastMessage}

{time}

-
+ \ No newline at end of file + diff --git a/src/lib/components/ui/CreateChat.svelte b/src/lib/components/ui/CreateChat.svelte index 226be15..0f62da7 100644 --- a/src/lib/components/ui/CreateChat.svelte +++ b/src/lib/components/ui/CreateChat.svelte @@ -11,12 +11,31 @@ let chatName = ""; - const createChat = () => { + const createChat = async () => { if (chatName.trim()) { - alertMessage = `Le chat "${chatName}" a été créé avec succès.`; + try { + // Appel API pour créer le chat + const response = await fetch('/api/canals', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ name: chatName }), + }); + + if (response.ok) { + const data = await response.json(); + alertMessage = `Le chat "${data.name}" a été créé avec succès.`; + chatName = ""; // Réinitialiser + onClose?.(); // Fermer le composant après création + } else { + alertMessage = "Une erreur est survenue lors de la création du chat."; + } + } catch (err) { + alertMessage = "Erreur réseau ou serveur."; + } + showAlert = true; - chatName = ""; // Réinitialiser - onClose?.(); // Fermer le composant après création } else { alertMessage = "Veuillez entrer un nom pour le chat."; showAlert = true; diff --git a/src/lib/utils/date.ts b/src/lib/utils/date.ts new file mode 100644 index 0000000..d83945d --- /dev/null +++ b/src/lib/utils/date.ts @@ -0,0 +1,51 @@ +export function formatDate(dateString) { + const date = new Date(dateString); + return date.toLocaleString('fr-FR', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit', + hour12: false, // format 24 heures + }); +} + +//fonction qui renvoie le temps depuis la créetion du message à maintenant en fonction du temps on affichera le temps en secondes, minutes, heures, jours, semaines, mois, années +export function formatDistanceToNow(dateString) { + const date = new Date(dateString); + const now = new Date(); + const diff = now - date; + + const seconds = Math.floor(diff / 1000); + if (seconds < 60) { + return `${seconds} s`; + } + + const minutes = Math.floor(seconds / 60); + if (minutes < 60) { + return `${minutes} min`; + } + + const hours = Math.floor(minutes / 60); + if (hours < 24) { + return `${hours} h`; + } + + const days = Math.floor(hours / 24); + if (days < 7) { + return `${days} j`; + } + + const weeks = Math.floor(days / 7); + if (weeks < 4) { + return `${weeks} sem`; + } + + const months = Math.floor(days / 30); + if (months < 12) { + return `${months} mois`; + } + + const years = Math.floor(months / 12); + return `${years} ans`; +} \ No newline at end of file diff --git a/src/routes/api/canal/[id]/+page.server.ts b/src/routes/api/canal/[id]/+page.server.ts deleted file mode 100644 index cfdb6f3..0000000 --- a/src/routes/api/canal/[id]/+page.server.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { json } from '@sveltejs/kit'; -import prisma from '$lib/prismaClient'; -import redisClient from '$lib/redisClient'; // Assurez-vous d'importer le client Redis - -// Récupérer les informations du canal et le dernier message (avec cache Redis) -export async function GET({ params }) { - const canalId = parseInt(params.id); - - // Clé cache pour les informations du canal et le dernier message - const canalCacheKey = `canal:${canalId}:info`; - - try { - // Vérifier si les informations du canal et le dernier message sont dans le cache Redis - const cachedCanalData = await redisClient.get(canalCacheKey); - if (cachedCanalData) { - console.log('✅ Cache hit pour les informations du canal et le dernier message'); - return json(JSON.parse(cachedCanalData)); - } - - console.log('❌ Cache miss'); - // Si non, récupérer les informations du canal et le dernier message depuis Prisma - const canal = await prisma.canal.findUnique({ - where: { id: canalId }, - include: { - users: true, // Inclut les utilisateurs associés au canal - }, - }); - - if (!canal) { - return json({ error: 'Canal non trouvé' }, { status: 404 }); - } - - // Récupérer le dernier message - const lastMessage = await prisma.message.findFirst({ - where: { canalId }, - include: { - user: { select: { id: true, pseudo: true } }, - }, - orderBy: { createdAt: 'desc' }, // Trie par date décroissante, donc le dernier message est récupéré en premier - }); - - // Créer un objet combiné pour le canal et le dernier message - const canalData = { - canal, - lastMessage, // Inclure uniquement le dernier message - }; - - // Mettre en cache les informations du canal et le dernier message pendant 5 minutes - await redisClient.set(canalCacheKey, JSON.stringify(canalData), 'EX', 300); // Cache pendant 5 minutes - - console.log('❌ Cache miss - Mise en cache des résultats'); - return json(canalData); - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la récupération du canal ou du dernier message' }, { status: 500 }); - } -} - -// Supprimer un canal et invalider le cache associé -export async function DELETE({ params }) { - const canalId = parseInt(params.id); - - try { - // Supprimer le canal de la base de données - await prisma.canal.delete({ - where: { id: canalId }, - }); - - // Invalider le cache - await redisClient.del(`canal:${canalId}:info`); - - return json({ message: 'Canal supprimé avec succès' }); - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la suppression du canal' }, { status: 500 }); - } -} - -// Modifier un canal -export async function PUT({ params, request }) { - const canalId = parseInt(params.id); - const { nom, domaine } = await request.json(); // On suppose que ce sont les champs à mettre à jour - - // Clé cache pour les informations du canal et le dernier message - const canalCacheKey = `canal:${canalId}:info`; - - try { - // Mettre à jour les informations du canal dans la base de données - const updatedCanal = await prisma.canal.update({ - where: { id: canalId }, - data: { - nom, // Nom du canal - domaine, // Domaine du canal - }, - include: { - users: true, // Inclut les utilisateurs associés au canal - }, - }); - - // Récupérer le dernier message associé au canal après mise à jour - const lastMessage = await prisma.message.findFirst({ - where: { canalId }, - include: { - user: { select: { id: true, pseudo: true } }, - }, - orderBy: { createdAt: 'desc' }, - }); - - // Créer un objet combiné pour les nouvelles informations du canal et le dernier message - const canalData = { - canal: updatedCanal, - lastMessage, // Inclure uniquement le dernier message - }; - - // Mettre en cache les nouvelles informations pendant 5 minutes - await redisClient.set(canalCacheKey, JSON.stringify(canalData), 'EX', 60 * 5); // Cache pendant 5 minutes - - return json(canalData); - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la mise à jour du canal' }, { status: 500 }); - } -} diff --git a/src/routes/api/canal/[id]/messages/+page.server.ts b/src/routes/api/canal/[id]/messages/+page.server.ts deleted file mode 100644 index 9fd337b..0000000 --- a/src/routes/api/canal/[id]/messages/+page.server.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { json } from '@sveltejs/kit'; -import prisma from '$lib/prismaClient'; -import redisClient from '$lib/redisClient'; // Assure-toi d'importer ton client Redis - -export async function GET({ params, url }) { - const canalId = parseInt(params.id); - - // Gestion de la pagination avec des paramètres optionnels `page` et `limit` - const page = parseInt(url.searchParams.get('page')) || 1; - const limit = parseInt(url.searchParams.get('limit')) || 10; - const offset = (page - 1) * limit; - - // Générer une clé cache Redis unique en fonction du canal et des paramètres de pagination - const cacheKey = `canal:${canalId}:messages:page:${page}:limit:${limit}`; - - try { - // 1. Vérifier si les messages sont déjà dans le cache Redis - const cachedMessages = await redisClient.get(cacheKey); - if (cachedMessages) { - console.log('✅ Cache hit'); - return json(JSON.parse(cachedMessages)); // Si les données sont en cache, les retourner - } - - // 2. Si les messages ne sont pas en cache, récupérer depuis la base de données - const messages = await prisma.message.findMany({ - where: { canalId }, - include: { - user: { - select: { id: true, pseudo: true }, // Inclut uniquement l’ID et le pseudo de l’utilisateur - }, - }, - orderBy: { - createdAt: 'asc', // Trie par date croissante - }, - skip: offset, - take: limit, - }); - - // 3. Compter le nombre total de messages pour la pagination - const totalMessages = await prisma.message.count({ - where: { canalId }, - }); - - const response = { - messages, - pagination: { - page, - limit, - totalMessages, - totalPages: Math.ceil(totalMessages / limit), - }, - }; - - // 4. Mettre en cache les messages avec une expiration (par exemple 5 minutes) - await redisClient.set(cacheKey, JSON.stringify(response), 'EX', 60 * 5); // Cache pendant 5 minutes - - console.log('❌ Cache miss - Mise en cache des résultats'); - return json(response); // Retourner les données récupérées - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la récupération des messages' }, { status: 500 }); - } -} - -export async function POST({ params, request }) { - const canalId = parseInt(params.id); - const { userId, text } = await request.json(); - - try { - // Créer un nouveau message dans la base de données - const newMessage = await prisma.message.create({ - data: { - userId, - canalId, - text, - }, - include: { user: { select: { id: true, pseudo: true } } }, - }); - - updateCaches(); // Mettre à jour les caches après la création d’un nouveau message - - return json(newMessage, { status: 201 }); - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la création du message' }, { status: 500 }); - } -} - -export async function DELETE({ params }) { - const messageId = parseInt(params.id); - - try { - // Supprimer le message de la base de données - await prisma.message.delete({ - where: { id: messageId }, - }); - - updateCaches(); // Mettre à jour les caches après la suppression d’un message - - return json({ message: 'Message supprimé avec succès' }); - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la suppression du message' }, { status: 500 }); - } -} - -// Fonction pour mettre à jour tous les caches des messages -function updateCaches(canalId) { - // Mettre à jour tous les caches - // Mettre à jour toutes les pages dans le cache - let page : number = 1; - let limit : number = 10; - let offset : number = (page - 1) * limit; - while (true) { - const cacheKey = `canal:${canalId}:messages:page:${page}:limit:${limit}`; - const cachedMessages = await redisClient.get(cacheKey); - if (!cachedMessages) { - break; - } - const totalMessages = await prisma.message.count({ - where: { canalId }, - }); - const messages = await prisma.message.findMany({ - where: { canalId }, - include: { - user: { - select: { id: true, pseudo: true }, - }, - }, - orderBy: { - createdAt: 'asc', - }, - skip: offset, - take: limit, - }); - const response = { - messages, - pagination: { - page, - limit, - totalMessages, - totalPages: Math.ceil(totalMessages / limit), - }, - }; - await redisClient.set(cacheKey, JSON.stringify(response), 'EX', 60 * 5); - page++; - offset = (page - 1) * limit; - } -} diff --git a/src/routes/api/canals/+page.server.ts b/src/routes/api/canals/+page.server.ts deleted file mode 100644 index b154366..0000000 --- a/src/routes/api/canals/+page.server.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { json } from '@sveltejs/kit'; -import prisma from '$lib/prismaClient'; -import redisClient from '$lib/redisClient'; - -// GET: Liste tous les canaux -export async function GET() { - try { - const cachedCanaux = await redisClient.get('canaux'); - if (cachedCanaux) { - console.log('✅ Cache hit'); - return json(JSON.parse(cachedCanaux)); - } - - console.log('❌ Cache miss'); - const canaux = await prisma.canal.findMany({ - include: { users: true, messages: true }, // Inclut les relations - }); - - await redisClient.set('canaux', JSON.stringify(canaux), { EX: 600 }); // Met en cache - return json(canaux); - } catch (err) { - console.error(err); - return json({ error: 'Erreur serveur' }, { status: 500 }); - } -} - -export async function POST({ request }) { - const { nom, domaine, userIds } = await request.json(); - - try { - const canal = await prisma.canal.create({ - data: { - nom, - domaine, - users: { - connect: userIds.map((id) => ({ id })), // Associe des utilisateurs au canal - }, - }, - }); - - return json(canal, { status: 201 }); - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la création du canal' }, { status: 500 }); - } -} - diff --git a/src/routes/api/canals/+server.ts b/src/routes/api/canals/+server.ts index b154366..6ae1097 100644 --- a/src/routes/api/canals/+server.ts +++ b/src/routes/api/canals/+server.ts @@ -2,46 +2,89 @@ import { json } from '@sveltejs/kit'; import prisma from '$lib/prismaClient'; import redisClient from '$lib/redisClient'; -// GET: Liste tous les canaux +import { json } from '@sveltejs/kit'; +import prisma from '$lib/prismaClient'; +import redisClient from '$lib/redisClient'; + +// GET: Liste tous les canaux avec leur premier message export async function GET() { try { const cachedCanaux = await redisClient.get('canaux'); - if (cachedCanaux) { - console.log('✅ Cache hit'); - return json(JSON.parse(cachedCanaux)); - } + + console.log('❌ Cache miss'); - const canaux = await prisma.canal.findMany({ - include: { users: true, messages: true }, // Inclut les relations + + // Si le cache est invalide ou vide, on charge les données depuis la base de données + let canaux = await prisma.channel.findMany({ + include: { + messages: { + take: 1, // Récupère le dernier message + orderBy: { createdAt: 'desc' }, // Trie par date décroissante + }, + }, + }); + + canaux = canaux.sort((a, b) => { + const lastMessageA = a.messages[0]?.createdAt || a.createdAt ? a.createdAt : new Date(); + const lastMessageB = b.messages[0]?.createdAt || b.createdAt ? b.createdAt : new Date(); + return new Date(lastMessageB).getTime() - new Date(lastMessageA).getTime(); }); - await redisClient.set('canaux', JSON.stringify(canaux), { EX: 600 }); // Met en cache return json(canaux); + } catch (err) { - console.error(err); + console.error('Erreur lors de la récupération des canaux:', err); return json({ error: 'Erreur serveur' }, { status: 500 }); } } export async function POST({ request }) { - const { nom, domaine, userIds } = await request.json(); + console.log('Création d’un canal'); + const { name } = await request.json(); // Récupère le nom du canal depuis la requête try { - const canal = await prisma.canal.create({ + // 1. Créer le canal dans la base de données MongoDB avec Prisma + const canal = await prisma.channel.create({ data: { - nom, - domaine, - users: { - connect: userIds.map((id) => ({ id })), // Associe des utilisateurs au canal - }, + name, + createdAt: new Date(), }, }); + console.log('Canal créé dans MongoDB:', canal); + // 2. Récupérer les canaux existants du cache Redis + let canaux = await redisClient.get('canaux'); + + // Si le cache est vide, initialiser un tableau vide + if (canaux) { + try { + canaux = JSON.parse(canaux); // Parser la liste existante dans Redis + } catch (parseError) { + console.error('Erreur lors du parsing du cache Redis:', parseError); + canaux = []; // Réinitialiser si parsing échoue + } + } else { + canaux = []; + } + + // 3. Ajouter le nouveau canal à la liste des canaux en mémoire (Redis) + canaux.push(canal); // Ajoute le canal créé dans la base de données à la liste Redis + + // 4. Mettre à jour le cache Redis avec la liste des canaux + await redisClient.set('canaux', JSON.stringify(canaux), { EX: 600 }); // Le cache expire dans 10 minutes + console.log('Liste des canaux mise à jour dans Redis'); + + // 5. Retourner le canal créé dans la réponse return json(canal, { status: 201 }); + } catch (err) { - console.error(err); + // Gérer les erreurs et les retourner + console.error('Erreur lors de la création du canal:', err); return json({ error: 'Erreur lors de la création du canal' }, { status: 500 }); } } + + + diff --git a/src/routes/api/user/[id]/+page.server.ts b/src/routes/api/user/[id]/+page.server.ts deleted file mode 100644 index 3282d88..0000000 --- a/src/routes/api/user/[id]/+page.server.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { json } from '@sveltejs/kit'; -import redisClient from '$lib/redisClient'; -import prisma from '$lib/prismaClient'; -import multer from 'multer'; -import path from 'path'; -import fs from 'fs'; - -const destinationDir = '/uploads'; - -const storage = multer.diskStorage({ - destination: (req, file, cb) => { - cb(null, `.${destinationDir}'); // Dossier où les images sont stockées` - }, - filename: (req, file, cb) => { - cb(null, `${Date.now()}-${file.originalname}`); - }, - fileFilter(req, file, cb) { - const fileExtension = path.extname(file.originalname).toLowerCase(); - if (fileExtension !== '.jpg' && fileExtension !== '.jpeg' && fileExtension !== '.png') { - return cb(new Error('Seules les images JPG, JPEG et PNG sont autorisées.')); - } - cb(null, true); - } -}); - -const upload = multer({ storage }); - -export async function GET({ params }) { - const userId = params.id; - - try { - // Vérifier si l'utilisateur est dans le cache Redis - const cachedUser = await redisClient.get(`user:${userId}`); - if (cachedUser) { - console.log('✅ Cache hit'); - return json(JSON.parse(cachedUser)); - } - - console.log('❌ Cache miss'); - // Si non, récupérer depuis MongoDB via Prisma - const user = await prisma.user.findUnique({ - where: { id: parseInt(userId) }, - }); - - if (!user) { - return json({ error: 'Utilisateur non trouvé' }, { status: 404 }); - } - - // Mettre l'utilisateur en cache - await redisClient.set(`user:${userId}`, JSON.stringify(user), { EX: 3600 }); - - return json(user); - } catch (err) { - console.error(err); - return json({ error: 'Erreur serveur' }, { status: 500 }); - } -} - -// Mettre à jour un utilisateur avec PUT -export async function PUT({ params, request }) { - const userId = parseInt(params.id); - - const cachedUser = await redisClient.get(`user:${userId}`); - // Récupérer l'utilisateur à partir de la base de données - let existingUser; - - if (cachedUser) { - console.log('✅ Cache hit'); - // Si l'utilisateur est dans le cache, on le parse - existingUser = JSON.parse(cachedUser); - } else { - // Si l'utilisateur n'est pas dans le cache, on le récupère de la base de données - console.log('❌ Cache miss'); - existingUser = await prisma.user.findUnique({ - where: { id: userId }, - }); - - if (!existingUser) { - return json({ error: 'Utilisateur non trouvé' }, { status: 404 }); - } - - // Utilisation de multer pour récupérer l'image (si présente) - return new Promise((resolve, reject) => { - upload.single('profilePicture')(request.raw, request.raw, async (err) => { - if (err) { - console.error('Erreur de téléchargement:', err); - return reject(json({ error: 'Erreur lors du téléchargement du fichier' }, { status: 500 })); - } - - // Extraire les autres données (pseudo, nom, etc.) du body de la requête - const { pseudo, nom, prenom, email, password } = await request.json(); - - let updatedUserData = { - pseudo, - nom, - prenom, - email, - password, // Assurez-vous de bien sécuriser les mots de passe - }; - - // Si une nouvelle image est envoyée - if (request.file) { - // Vérifiez si l'utilisateur a déjà une image - if (existingUser.profilePictureUrl) { - // Supprimer l'ancienne image - const oldImagePath = `.${destinationDir}/${path.basename(existingUser.profilePictureUrl)}`; - if (fs.existsSync(oldImagePath)) { - fs.unlinkSync(oldImagePath); // Suppression du fichier - } - } - - // Ajouter la nouvelle image à la base de données - updatedUserData.profilePictureUrl = `${destinationDir}/${request.file.filename}`; - } else if (!request.file && existingUser.profilePictureUrl) { - // Si aucune image n'est envoyée, supprimer l'image actuelle - const oldImagePath = `.${destinationDir}/${path.basename(existingUser.profilePictureUrl)}`; - if (fs.existsSync(oldImagePath)) { - fs.unlinkSync(oldImagePath); // Supprimer l'ancienne image - } - - // Mettre à jour l'URL de l'image en null - updatedUserData.profilePictureUrl = null; - } - - try { - // Mettre à jour l'utilisateur dans la base de données - const updatedUser = await prisma.user.update({ - where: { id: userId }, - data: updatedUserData, - }); - - // Mettre à jour l'utilisateur dans le cache Redis - await redisClient.set(`user:${userId}`, JSON.stringify(updatedUser), 'EX', 3600); // Cache pendant 1 heure (3600 secondes) - - // Réponse avec l'utilisateur mis à jour - return resolve(json(updatedUser)); - } catch (error) { - console.error('Erreur lors de la mise à jour de l\'utilisateur:', error); - return reject(json({ error: 'Erreur lors de la mise à jour de l\'utilisateur' }, { status: 500 })); - } - }); - }); -} - - -export async function DELETE({ params }) { - const userId = parseInt(params.id); - - try { - // Vérifier si l'utilisateur est dans le cache Redis - const cachedUser = await redisClient.get(`user:${userId}`); - let userToDelete; - - if (cachedUser) { - console.log('✅ Cache hit'); - // Si l'utilisateur est dans le cache, on le parse - userToDelete = JSON.parse(cachedUser); - } else { - // Si l'utilisateur n'est pas dans le cache, on le récupère de la base de données - console.log('❌ Cache miss'); - userToDelete = await prisma.user.findUnique({ - where: { id: userId }, - }); - - if (!userToDelete) { - return json({ error: 'Utilisateur non trouvé' }, { status: 404 }); - } - - // Mettre l'utilisateur dans le cache Redis - await redisClient.set(`user:${userId}`, JSON.stringify(userToDelete), { EX: 3600 }); // Cache pendant 1 heure - } - - // Si l'utilisateur a une image de profil, la supprimer - if (userToDelete.profilePictureUrl) { - // Calculer le chemin du fichier à supprimer - const imagePath = `.${destinationDir}/${path.basename(userToDelete.profilePictureUrl)}`; - if (fs.existsSync(imagePath)) { - fs.unlinkSync(imagePath); // Supprimer le fichier image - } - } - - // Supprimer l'utilisateur de la base de données - await prisma.user.delete({ - where: { id: userId }, - }); - - // Supprimer l'utilisateur du cache Redis - await redisClient.del(`user:${userId}`); - - // Réponse après suppression réussie - return json({ message: 'Utilisateur et image supprimés avec succès' }); - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la suppression de l’utilisateur' }, { status: 500 }); - } -} - - - - diff --git a/src/routes/api/user/[id]/+server.ts b/src/routes/api/user/[id]/+server.ts index fed07c3..f6243fb 100644 --- a/src/routes/api/user/[id]/+server.ts +++ b/src/routes/api/user/[id]/+server.ts @@ -33,43 +33,19 @@ export async function GET({ params }) { } } -export async function POST({ request }) { - const { pseudo, nom, prenom, email, password } = await request.json(); - - try { - const user = await prisma.user.create({ - data: { - pseudo, - nom, - prenom, - email, - password, - }, - }); - - // Mettre le nouvel utilisateur dans le cache - await redisClient.set(`user:${user.id}`, JSON.stringify(user), { EX: 3600 }); - - return json(user, { status: 201 }); - } catch (err) { - console.error(err); - return json({ error: 'Erreur lors de la création de l’utilisateur' }, { status: 500 }); - } -} - // Mettre à jour un utilisateur avec PUT export async function PUT({ params, request }) { const userId = parseInt(params.id); - const { pseudo, nom, prenom, email, password } = await request.json(); // Assurez-vous d'envoyer tous les champs nécessaires dans le body + const { username, surname, name, email, password } = await request.json(); // Assurez-vous d'envoyer tous les champs nécessaires dans le body try { // Mettre à jour l'utilisateur dans la base de données const updatedUser = await prisma.user.update({ where: { id: userId }, data: { - pseudo, - nom, - prenom, + username, + surname, + name, email, password, // Attention à ne pas oublier de sécuriser le mot de passe avec bcrypt ou une autre méthode }, diff --git a/src/routes/api/users/+page.server.ts b/src/routes/api/users/+page.server.ts deleted file mode 100644 index 7444e4e..0000000 --- a/src/routes/api/users/+page.server.ts +++ /dev/null @@ -1,87 +0,0 @@ -// src/routes/api/users/+server.js -import { json } from '@sveltejs/kit'; -import redisClient from '$lib/redisClient'; -import prisma from '$lib/prismaClient'; -import multer from 'multer'; - -const destinationDir = '/uploads'; - -const storage = multer.diskStorage({ - destination: (req, file, cb) => { - cb(null, `.${destinationDir}'); // Dossier où les images sont stockées` - }, - filename: (req, file, cb) => { - cb(null, `${Date.now()}-${file.originalname}`); - }, - fileFilter(req, file, cb) { - const fileExtension = path.extname(file.originalname).toLowerCase(); - if (fileExtension !== '.jpg' && fileExtension !== '.jpeg' && fileExtension !== '.png') { - return cb(new Error('Seules les images JPG, JPEG et PNG sont autorisées.')); - } - cb(null, true); - } -}); - -export async function GET() { - try { - // Vérifier si les utilisateurs sont dans le cache Redis - const cachedUsers = await redisClient.get('users'); - if (cachedUsers) { - console.log('✅ Cache hit'); - return json(JSON.parse(cachedUsers)); - } - - console.log('❌ Cache miss'); - // Sinon, récupérer les utilisateurs depuis MongoDB - const users = await prisma.user.findMany(); - - // Mettre les utilisateurs en cache - await redisClient.set('users', JSON.stringify(users), { EX: 600 }); - - return json(users); - } catch (err) { - console.error(err); - return json({ error: 'Erreur serveur' }, { status: 500 }); - } -} - -export async function POST({ request }) { - return new Promise((resolve, reject) => { - // Utilisation de multer pour récupérer le fichier - upload.single('profilePicture')(request.raw, request.raw, async (err) => { - if (err) { - console.error('Erreur de téléchargement:', err); - return reject(json({ error: 'Erreur lors du téléchargement du fichier' }, { status: 500 })); - } - - // Récupérer les données du formulaire (sans le fichier) - const { pseudo, nom, prenom, email, password } = await request.json(); - - // L'URL de l'image sera le chemin relatif à partir du dossier uploads - const imageUrl = request.file ? `${destinationDir}/${request.file.filename}` : null; - - try { - // Créer un nouvel utilisateur avec l'URL de l'image - const user = await prisma.user.create({ - data: { - pseudo, - nom, - prenom, - email, - password, - profilePictureUrl: imageUrl, // Stocker l'URL de l'image - }, - }); - - // Mettre l'utilisateur dans le cache Redis - await redisClient.set(`user:${user.id}`, JSON.stringify(user), { EX: 3600 }); - - // Réponse avec les données de l'utilisateur - return resolve(json(user, { status: 201 })); - } catch (error) { - console.error('Erreur lors de la création de l\'utilisateur:', error); - return reject(json({ error: 'Erreur lors de la création de l\'utilisateur' }, { status: 500 })); - } - }); - }); -} diff --git a/src/routes/api/users/+server.ts b/src/routes/api/users/+server.ts index 0d7b259..a1bd3f1 100644 --- a/src/routes/api/users/+server.ts +++ b/src/routes/api/users/+server.ts @@ -25,3 +25,27 @@ export async function GET() { return json({ error: 'Erreur serveur' }, { status: 500 }); } } + +export async function POST({ request }) { + const { username, surname, name, email, password } = await request.json(); + + try { + const user = await prisma.user.create({ + data: { + username, + surname, + name, + email, + password, + }, + }); + + // Mettre le nouvel utilisateur dans le cache + await redisClient.set(`user:${user.id}`, JSON.stringify(user), { EX: 3600 }); + + return json(user, { status: 201 }); + } catch (err) { + console.error(err); + return json({ error: 'Erreur lors de la création de l’utilisateur' }, { status: 500 }); + } +} diff --git a/src/routes/chats/+page.svelte b/src/routes/chats/+page.svelte index 1cab2a3..26fe869 100644 --- a/src/routes/chats/+page.svelte +++ b/src/routes/chats/+page.svelte @@ -5,6 +5,8 @@ import ChatItem from "$lib/components/ui/ChatItem.svelte"; import ProfileCard from "$lib/components/ui/ProfileCard.svelte"; // Importer le composant ProfileCard import CreateChat from "$lib/components/ui/CreateChat.svelte"; // Importer le composant CreateChat + import { formatDistanceToNow } from "$lib/utils/date.js"; + import { io } from 'socket.io-client'; let showProfileCard = false; // État pour afficher ou masquer le ProfileCard let showCreateChat = false; // État pour afficher ou masquer CreateChat @@ -35,6 +37,11 @@ console.log('closeCreateChat'); showCreateChat = false; // Fermer le composant CreateChat } + + export let data; + export let channels = data.channels;// Assurez-vous que 'lastMessage' est facultatif si nécessaire + console.log(channels); +
@@ -67,8 +74,9 @@
- - + {#each channels as channel} + + {/each}
diff --git a/src/routes/chats/+page.ts b/src/routes/chats/+page.ts new file mode 100644 index 0000000..163999f --- /dev/null +++ b/src/routes/chats/+page.ts @@ -0,0 +1,22 @@ +export async function load({ fetch }) { + try { + // Appel API ou récupération de données + const res = await fetch('/api/canals', { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + }); + const channels = await res.json(); + + // Retourner les données à la page sous forme de props + return { + channels + }; + } catch (error) { + console.error('Erreur lors du chargement des canaux:', error); + return { + channels: [] + }; + } +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index bbf8c7d..65ff714 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,21 @@ import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig } from 'vite'; +import { type ViteDevServer, defineConfig } from 'vite'; + +import { Server } from 'socket.io' + +const webSocketServer = { + name: 'webSocketServer', + configureServer(server: ViteDevServer) { + if (!server.httpServer) return + + const io = new Server(server.httpServer) + + io.on('connection', (socket) => { + socket.emit('eventFromServer', 'Hello, World 👋') + }) + } +} export default defineConfig({ - plugins: [sveltekit()] + plugins: [sveltekit(), webSocketServer] });