This commit is contained in:
2026-07-04 13:19:56 +02:00
parent dc738a9d29
commit 54d1169888
4 changed files with 70 additions and 39 deletions
+30 -28
View File
@@ -1,35 +1,37 @@
<script lang="ts" setup> <script lang="ts" setup>
import {ref} from 'vue' import {onMounted, ref} from 'vue';
import {useRoute} from 'vue-router';
import {storeToRefs} from 'pinia'; // Import crucial
import {useMessageStore} from '@/stores/message';
// Exemple de données (à remplacer par vos données Pinia/API) const route = useRoute();
const messages = ref([ const messageStore = useMessageStore();
{
id: 1, // "messages" ici est une référence réactive liée au store
user: {name: 'Utilisateur 1', avatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg'}, const {messages, loading} = storeToRefs(messageStore);
content: 'Salut ! Comment ça va ?',
timestamp: 'Aujourd\'hui à 12:00' const newMessage = ref('');
},
{ const sendMessage = async () => {
id: 2, if (!newMessage.value.trim()) return;
user: {name: 'Utilisateur 2', avatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg'},
content: 'Je vais très bien, merci ! Et toi ?', const content = newMessage.value;
timestamp: 'Aujourd\'hui à 12:01' const channelId = route.params.id as string;
try {
await messageStore.sendMessage(channelId, content);
newMessage.value = ''; // On vide le champ après succès
} catch (e) {
// Gérer l'erreur (ex: notification toast)
} }
]) };
const newMessage = ref('') onMounted(() => {
const channelId = route.params.id as string;
const sendMessage = () => { if (channelId) {
if (!newMessage.value.trim()) return messageStore.fetchMessages(channelId);
// Logique d'envoi ici }
messages.value.push({ });
id: Date.now(),
user: {name: 'Moi', avatar: ''},
content: newMessage.value,
timestamp: 'À l\'instant'
})
newMessage.value = ''
}
</script> </script>
<template> <template>
+34 -6
View File
@@ -1,17 +1,45 @@
import {defineStore} from "pinia"; import {defineStore} from "pinia";
import {useApi} from "@/composables/useApi.ts"; import {useApi} from "@/composables/useApi.ts";
interface Message {
id: string;
content: string;
user: { name: string; avatar: string };
timestamp: string;
}
export const useMessageStore = defineStore("message", { export const useMessageStore = defineStore("message", {
state: () => ({ state: () => ({
messages: [] messages: [] as Message[],
loading: false,
}), }),
actions: { actions: {
async fetchMessages(channel_id: string) { async fetchMessages(channel_id: string) {
// todo : ici, les messages ne doivent pas être tous récupérés. Un filtre doit être appliqué. this.loading = true;
// pour ne récupérer que les messages du channel actif try {
let api = useApi(); const api = useApi();
let response = await api.get("/api/messages"); // Utilisation du paramètre pour cibler le channel
this.messages = await response.json(); const response = await api.get(`/api/messages/${channel_id}`);
this.messages = await response.json();
} catch (error) {
console.error("Erreur lors du chargement des messages:", error);
} finally {
this.loading = false;
}
},
async sendMessage(channelId: string, content: string) {
const api = useApi();
try {
// Envoi au serveur pour persistance
const response = await api.post(`/api/messages/${channelId}`, {content});
const newMessage = await response.json();
// Ajout local immédiat (optimistic update)
this.messages.push(newMessage);
} catch (error) {
console.error("Erreur lors de l'envoi du message:", error);
throw error;
}
}, },
reset() { reset() {
this.messages = []; this.messages = [];
+3 -3
View File
@@ -8,7 +8,7 @@ use axum::{
use axum_extra::extract::CookieJar; use axum_extra::extract::CookieJar;
use std::sync::Arc; use std::sync::Arc;
use std::time::Instant; use std::time::Instant;
use tracing::{info, Instrument}; use tracing::{debug, info, Instrument};
use uuid::Uuid; use uuid::Uuid;
use super::context::{CurrentUser, RequestContext}; use super::context::{CurrentUser, RequestContext};
@@ -92,7 +92,7 @@ pub async fn auth_middleware(
mut req: Request<Body>, mut req: Request<Body>,
next: Next, next: Next,
) -> Response { ) -> Response {
// Extraction du JWT : d'abord via le header Authorization, sinon via la query string "token" // Extraction du JWT : d'abord via le header Authorization, ou via le cookie, sinon via la query string "token"
let token = req let token = req
.headers() .headers()
.get(header::AUTHORIZATION) .get(header::AUTHORIZATION)
@@ -132,7 +132,7 @@ pub async fn auth_middleware(
// Mise à jour du RequestContext existant // Mise à jour du RequestContext existant
if let Some(user) = &user { if let Some(user) = &user {
info!(user_id = %user.id, username = %user.username, "User identified"); debug!(user_id = %user.id, username = %user.username, "User identified");
if let Some(ctx) = req.extensions_mut().get_mut::<RequestContext>() { if let Some(ctx) = req.extensions_mut().get_mut::<RequestContext>() {
ctx.user = Some(user.clone()); ctx.user = Some(user.clone());
} }
+2 -1
View File
@@ -9,7 +9,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt() tracing_subscriber::fmt()
.with_env_filter( .with_env_filter(
std::env::var("RUST_LOG") std::env::var("RUST_LOG")
.unwrap_or_else(|_| "info,sqlx=debug,sea_orm=debug,sea_orm_migration=info".into()), // .unwrap_or_else(|_| "info,sqlx=debug,sea_orm=debug,sea_orm_migration=info".into()),
.unwrap_or_else(|_| "info,sqlx=info,sea_orm=info,sea_orm_migration=info".into()),
) )
.with_target(true) .with_target(true)
.with_level(true) .with_level(true)