feat: introduce new app routes with modular structure and enhanced features

Added modular app routes including `login`, `dashboard`, `categories`, `trends`, and `upload`. Introduced reusable components such as `ContentList`, `ContentSkeleton`, and `AppSidebar` for improved UI consistency. Enhanced authentication with `AuthProvider` and implemented lazy loading, dynamic layouts, and infinite scrolling for better performance.
This commit is contained in:
Mathis HERRIOT
2026-01-14 13:52:08 +01:00
parent 0c045e8d3c
commit 0b07320974
41 changed files with 2341 additions and 43 deletions

View File

@@ -0,0 +1,22 @@
import api from "@/lib/api";
import type { LoginResponse } from "@/types/auth";
export const AuthService = {
async login(email: string, password: string): Promise<LoginResponse> {
const { data } = await api.post<LoginResponse>("/auth/login", { email, password });
return data;
},
async register(payload: any): Promise<any> {
const { data } = await api.post("/auth/register", payload);
return data;
},
async logout(): Promise<void> {
await api.post("/auth/logout");
},
async refresh(): Promise<void> {
await api.post("/auth/refresh");
},
};

View File

@@ -0,0 +1,14 @@
import api from "@/lib/api";
import type { Category } from "@/types/content";
export const CategoryService = {
async getAll(): Promise<Category[]> {
const { data } = await api.get<Category[]>("/categories");
return data;
},
async getOne(id: string): Promise<Category> {
const { data } = await api.get<Category>(`/categories/${id}`);
return data;
},
};

View File

@@ -0,0 +1,54 @@
import api from "@/lib/api";
import type { Content, PaginatedResponse } from "@/types/content";
export const ContentService = {
async getExplore(params: {
limit?: number;
offset?: number;
sort?: "trend" | "recent";
tag?: string;
category?: string;
query?: string;
}): Promise<PaginatedResponse<Content>> {
const { data } = await api.get<PaginatedResponse<Content>>("/contents/explore", {
params,
});
return data;
},
async getTrends(limit = 10, offset = 0): Promise<PaginatedResponse<Content>> {
const { data } = await api.get<PaginatedResponse<Content>>("/contents/trends", {
params: { limit, offset },
});
return data;
},
async getRecent(limit = 10, offset = 0): Promise<PaginatedResponse<Content>> {
const { data } = await api.get<PaginatedResponse<Content>>("/contents/recent", {
params: { limit, offset },
});
return data;
},
async getOne(idOrSlug: string): Promise<Content> {
const { data } = await api.get<Content>(`/contents/${idOrSlug}`);
return data;
},
async incrementViews(id: string): Promise<void> {
await api.post(`/contents/${id}/view`);
},
async incrementUsage(id: string): Promise<void> {
await api.post(`/contents/${id}/use`);
},
async upload(formData: FormData): Promise<Content> {
const { data } = await api.post<Content>("/contents/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
return data;
},
};

View File

@@ -0,0 +1,17 @@
import api from "@/lib/api";
import type { Content, PaginatedResponse } from "@/types/content";
export const FavoriteService = {
async add(contentId: string): Promise<void> {
await api.post(`/favorites/${contentId}`);
},
async remove(contentId: string): Promise<void> {
await api.delete(`/favorites/${contentId}`);
},
async list(params: { limit: number; offset: number }): Promise<PaginatedResponse<Content>> {
const { data } = await api.get<PaginatedResponse<Content>>("/favorites", { params });
return data;
},
};

View File

@@ -0,0 +1,19 @@
import api from "@/lib/api";
import type { User, UserProfile } from "@/types/user";
export const UserService = {
async getMe(): Promise<User> {
const { data } = await api.get<User>("/users/me");
return data;
},
async getProfile(username: string): Promise<User> {
const { data } = await api.get<User>(`/users/public/${username}`);
return data;
},
async updateMe(update: Partial<User>): Promise<User> {
const { data } = await api.patch<User>("/users/me", update);
return data;
},
};