mirror of
https://github.com/R0m1k3/noteflow.git
synced 2026-10-22 14:48:18 +02:00
[dyad] wrote 4 file(s)
This commit is contained in:
1 parent
209c48ee6b
commit
0bcffed331
4 files changed
+142
-58
No files matched your search
+4
-1
@@ -28,7 +28,10 @@ const App = () => {
|
|||||||
// Vérifier le token au démarrage
|
// Vérifier le token au démarrage
|
||||||
const checkAuth = async () => {
|
const checkAuth = async () => {
|
||||||
try {
|
try {
|
||||||
await AuthService.checkTokenValidity();
|
// Vérifier si le token est valide
|
||||||
|
if (AuthService.getToken()) {
|
||||||
|
await AuthService.checkTokenValidity();
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error checking token validity:", error);
|
console.error("Error checking token validity:", error);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
+115
-50
@@ -12,6 +12,7 @@ import AuthService from "@/services/AuthService";
|
|||||||
import AdminService from "@/services/AdminService";
|
import AdminService from "@/services/AdminService";
|
||||||
import NotesService, { Note } from "@/services/NotesService";
|
import NotesService, { Note } from "@/services/NotesService";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { showError } from "@/utils/toast";
|
||||||
|
|
||||||
interface UserType {
|
interface UserType {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -30,27 +31,45 @@ const Index = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Récupérer l'utilisateur et vérifier l'authentification
|
||||||
const userFromAuth = AuthService.getUser();
|
const userFromAuth = AuthService.getUser();
|
||||||
if (userFromAuth) {
|
if (userFromAuth) {
|
||||||
setUser(userFromAuth);
|
setUser(userFromAuth);
|
||||||
loadNotes();
|
loadNotes().catch(err => {
|
||||||
|
console.error("Erreur lors du chargement des notes:", err);
|
||||||
|
showError("Erreur lors du chargement des notes");
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
navigate("/login");
|
navigate("/login");
|
||||||
}
|
}
|
||||||
}, [navigate]);
|
}, [navigate]);
|
||||||
|
|
||||||
const loadNotes = async () => {
|
const loadNotes = async () => {
|
||||||
const fetchedNotes = await NotesService.getNotes();
|
try {
|
||||||
setNotes(fetchedNotes || []);
|
const fetchedNotes = await NotesService.getNotes();
|
||||||
if (fetchedNotes && fetchedNotes.length > 0) {
|
if (Array.isArray(fetchedNotes)) {
|
||||||
setCurrentNote(fetchedNotes[0]);
|
setNotes(fetchedNotes);
|
||||||
|
if (fetchedNotes.length > 0) {
|
||||||
|
setCurrentNote(fetchedNotes[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors du chargement des notes:", error);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadUsers = async () => {
|
const loadUsers = async () => {
|
||||||
if (user?.is_admin) {
|
if (user?.is_admin) {
|
||||||
const fetchedUsers = await AdminService.getUsers();
|
try {
|
||||||
setUsers(fetchedUsers || []);
|
const fetchedUsers = await AdminService.getUsers();
|
||||||
|
if (Array.isArray(fetchedUsers)) {
|
||||||
|
setUsers(fetchedUsers);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors du chargement des utilisateurs:", error);
|
||||||
|
showError("Erreur lors du chargement des utilisateurs");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,28 +79,38 @@ const Index = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleCreateNote = async () => {
|
const handleCreateNote = async () => {
|
||||||
const newNote = await NotesService.createNote("Nouvelle note");
|
try {
|
||||||
if (newNote) {
|
const newNote = await NotesService.createNote("Nouvelle note");
|
||||||
setNotes([newNote, ...notes]);
|
if (newNote) {
|
||||||
setCurrentNote(newNote);
|
setNotes([newNote, ...notes]);
|
||||||
|
setCurrentNote(newNote);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la création de la note:", error);
|
||||||
|
showError("Erreur lors de la création de la note");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateNote = async (updatedFields: Partial<Note>) => {
|
const handleUpdateNote = async (updatedFields: Partial<Note>) => {
|
||||||
if (!currentNote) return;
|
if (!currentNote) return;
|
||||||
|
|
||||||
const updatedNote = {
|
try {
|
||||||
...currentNote,
|
const updatedNote = {
|
||||||
...updatedFields,
|
...currentNote,
|
||||||
todos: currentNote.todos || [],
|
...updatedFields,
|
||||||
images: currentNote.images || []
|
todos: currentNote.todos || [],
|
||||||
};
|
images: currentNote.images || []
|
||||||
|
};
|
||||||
|
|
||||||
const success = await NotesService.updateNote(updatedNote);
|
const success = await NotesService.updateNote(updatedNote);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
setCurrentNote(updatedNote);
|
setCurrentNote(updatedNote);
|
||||||
setNotes(notes.map(note => note.id === updatedNote.id ? updatedNote : note));
|
setNotes(notes.map(note => note.id === updatedNote.id ? updatedNote : note));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la mise à jour de la note:", error);
|
||||||
|
showError("Erreur lors de la mise à jour de la note");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,12 +118,17 @@ const Index = () => {
|
|||||||
if (!currentNote?.id) return;
|
if (!currentNote?.id) return;
|
||||||
|
|
||||||
if (window.confirm("Êtes-vous sûr de vouloir supprimer cette note ?")) {
|
if (window.confirm("Êtes-vous sûr de vouloir supprimer cette note ?")) {
|
||||||
const success = await NotesService.deleteNote(currentNote.id);
|
try {
|
||||||
|
const success = await NotesService.deleteNote(currentNote.id);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
const updatedNotes = notes.filter(note => note.id !== currentNote.id);
|
const updatedNotes = notes.filter(note => note.id !== currentNote.id);
|
||||||
setNotes(updatedNotes);
|
setNotes(updatedNotes);
|
||||||
setCurrentNote(updatedNotes.length > 0 ? updatedNotes[0] : null);
|
setCurrentNote(updatedNotes.length > 0 ? updatedNotes[0] : null);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la suppression de la note:", error);
|
||||||
|
showError("Erreur lors de la suppression de la note");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -108,9 +142,14 @@ const Index = () => {
|
|||||||
|
|
||||||
const isAdmin = window.confirm("Donner les droits administrateur ?");
|
const isAdmin = window.confirm("Donner les droits administrateur ?");
|
||||||
|
|
||||||
const newUser = await AdminService.createUser(username, password, isAdmin);
|
try {
|
||||||
if (newUser) {
|
const newUser = await AdminService.createUser(username, password, isAdmin);
|
||||||
loadUsers();
|
if (newUser) {
|
||||||
|
loadUsers();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la création de l'utilisateur:", error);
|
||||||
|
showError("Erreur lors de la création de l'utilisateur");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -118,24 +157,39 @@ const Index = () => {
|
|||||||
const password = prompt("Nouveau mot de passe:");
|
const password = prompt("Nouveau mot de passe:");
|
||||||
if (!password) return;
|
if (!password) return;
|
||||||
|
|
||||||
const success = await AdminService.updateUserPassword(userId, password);
|
try {
|
||||||
if (success) {
|
const success = await AdminService.updateUserPassword(userId, password);
|
||||||
loadUsers();
|
if (success) {
|
||||||
|
loadUsers();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la modification du mot de passe:", error);
|
||||||
|
showError("Erreur lors de la modification du mot de passe");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleToggleAdmin = async (userId: number, currentStatus: boolean) => {
|
const handleToggleAdmin = async (userId: number, currentStatus: boolean) => {
|
||||||
const success = await AdminService.toggleAdminStatus(userId, currentStatus);
|
try {
|
||||||
if (success) {
|
const success = await AdminService.toggleAdminStatus(userId, currentStatus);
|
||||||
loadUsers();
|
if (success) {
|
||||||
|
loadUsers();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la modification des droits:", error);
|
||||||
|
showError("Erreur lors de la modification des droits");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteUser = async (userId: number) => {
|
const handleDeleteUser = async (userId: number) => {
|
||||||
if (window.confirm("Êtes-vous sûr de vouloir supprimer cet utilisateur ?")) {
|
if (window.confirm("Êtes-vous sûr de vouloir supprimer cet utilisateur ?")) {
|
||||||
const success = await AdminService.deleteUser(userId);
|
try {
|
||||||
if (success) {
|
const success = await AdminService.deleteUser(userId);
|
||||||
loadUsers();
|
if (success) {
|
||||||
|
loadUsers();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la suppression de l'utilisateur:", error);
|
||||||
|
showError("Erreur lors de la suppression de l'utilisateur");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -150,7 +204,7 @@ const Index = () => {
|
|||||||
const filteredNotes = notes.filter(note =>
|
const filteredNotes = notes.filter(note =>
|
||||||
(activeTab === "all" || (activeTab === "archived" && note.archived)) &&
|
(activeTab === "all" || (activeTab === "archived" && note.archived)) &&
|
||||||
(searchQuery === "" ||
|
(searchQuery === "" ||
|
||||||
note.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
(note.title && note.title.toLowerCase().includes(searchQuery.toLowerCase())) ||
|
||||||
(note.content && note.content.toLowerCase().includes(searchQuery.toLowerCase())))
|
(note.content && note.content.toLowerCase().includes(searchQuery.toLowerCase())))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -185,7 +239,7 @@ const Index = () => {
|
|||||||
<Button variant="ghost" className="flex items-center gap-2">
|
<Button variant="ghost" className="flex items-center gap-2">
|
||||||
<Avatar className="h-8 w-8">
|
<Avatar className="h-8 w-8">
|
||||||
<AvatarFallback className="bg-primary/10 text-primary">
|
<AvatarFallback className="bg-primary/10 text-primary">
|
||||||
{user.username?.charAt(0).toUpperCase() || "U"}
|
{user.username ? user.username.charAt(0).toUpperCase() : "U"}
|
||||||
</AvatarFallback>
|
</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<span className="font-medium">{user.username}</span>
|
<span className="font-medium">{user.username}</span>
|
||||||
@@ -399,12 +453,18 @@ const Index = () => {
|
|||||||
className="hidden"
|
className="hidden"
|
||||||
onChange={async (e) => {
|
onChange={async (e) => {
|
||||||
if (e.target.files && e.target.files[0] && currentNote.id) {
|
if (e.target.files && e.target.files[0] && currentNote.id) {
|
||||||
const image = await NotesService.uploadImage(currentNote.id, e.target.files[0]);
|
try {
|
||||||
if (image) {
|
const image = await NotesService.uploadImage(currentNote.id, e.target.files[0]);
|
||||||
const updatedImages = [...(currentNote.images || []), image];
|
if (image) {
|
||||||
handleUpdateNote({ images: updatedImages });
|
const updatedImages = [...(currentNote.images || []), image];
|
||||||
|
handleUpdateNote({ images: updatedImages });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de l'upload de l'image:", error);
|
||||||
|
showError("Erreur lors de l'upload de l'image");
|
||||||
|
} finally {
|
||||||
|
e.target.value = '';
|
||||||
}
|
}
|
||||||
e.target.value = '';
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -426,10 +486,15 @@ const Index = () => {
|
|||||||
className="absolute top-1 right-1 h-6 w-6 rounded-full"
|
className="absolute top-1 right-1 h-6 w-6 rounded-full"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (image.id && currentNote.id) {
|
if (image.id && currentNote.id) {
|
||||||
const success = await NotesService.deleteImage(currentNote.id, image.id);
|
try {
|
||||||
if (success) {
|
const success = await NotesService.deleteImage(currentNote.id, image.id);
|
||||||
const updatedImages = (currentNote.images || []).filter((_, i) => i !== index);
|
if (success) {
|
||||||
handleUpdateNote({ images: updatedImages });
|
const updatedImages = (currentNote.images || []).filter((_, i) => i !== index);
|
||||||
|
handleUpdateNote({ images: updatedImages });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la suppression de l'image:", error);
|
||||||
|
showError("Erreur lors de la suppression de l'image");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@@ -495,7 +560,7 @@ const Index = () => {
|
|||||||
<CardContent className="p-4 flex items-center justify-between">
|
<CardContent className="p-4 flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Avatar>
|
<Avatar>
|
||||||
<AvatarFallback>{user.username.charAt(0).toUpperCase()}</AvatarFallback>
|
<AvatarFallback>{user.username ? user.username.charAt(0).toUpperCase() : "U"}</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium">{user.username}</p>
|
<p className="font-medium">{user.username}</p>
|
||||||
|
|||||||
@@ -19,7 +19,14 @@ class AdminService {
|
|||||||
throw new Error("Erreur lors de la récupération des utilisateurs");
|
throw new Error("Erreur lors de la récupération des utilisateurs");
|
||||||
}
|
}
|
||||||
|
|
||||||
return await response.json();
|
const users = await response.json();
|
||||||
|
|
||||||
|
// Vérifier que les données sont un tableau
|
||||||
|
if (!Array.isArray(users)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return users;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showError(error instanceof Error ? error.message : "Erreur serveur");
|
showError(error instanceof Error ? error.message : "Erreur serveur");
|
||||||
return [];
|
return [];
|
||||||
@@ -107,4 +114,6 @@ class AdminService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new AdminService();
|
// Créer une instance unique
|
||||||
|
const adminServiceInstance = new AdminService();
|
||||||
|
export default adminServiceInstance;
|
||||||
@@ -51,11 +51,16 @@ class AuthService {
|
|||||||
|
|
||||||
this.token = data.token;
|
this.token = data.token;
|
||||||
this.user = data.user;
|
this.user = data.user;
|
||||||
localStorage.setItem("token", this.token || "");
|
|
||||||
localStorage.setItem("user", JSON.stringify(this.user || {}));
|
|
||||||
|
|
||||||
showSuccess("Connexion réussie");
|
// Vérifier que les données sont valides avant de les stocker
|
||||||
return true;
|
if (this.token && this.user) {
|
||||||
|
localStorage.setItem("token", this.token);
|
||||||
|
localStorage.setItem("user", JSON.stringify(this.user));
|
||||||
|
showSuccess("Connexion réussie");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error("Données d'authentification invalides");
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showError(error instanceof Error ? error.message : "Erreur de connexion");
|
showError(error instanceof Error ? error.message : "Erreur de connexion");
|
||||||
return false;
|
return false;
|
||||||
@@ -91,4 +96,6 @@ class AuthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new AuthService();
|
// Créer une instance unique
|
||||||
|
const authServiceInstance = new AuthService();
|
||||||
|
export default authServiceInstance;
|
||||||
Reference in new issue
Block a user