diff --git a/thoughts-frontend/lib/api.ts b/thoughts-frontend/lib/api.ts index fd102a8..075a439 100644 --- a/thoughts-frontend/lib/api.ts +++ b/thoughts-frontend/lib/api.ts @@ -151,9 +151,13 @@ const API_BASE_URL = ? process.env.NEXT_PUBLIC_SERVER_SIDE_API_URL : process.env.NEXT_PUBLIC_API_URL; +type ApiFetchOptions = Omit & { + next?: { tags?: string[]; revalidate?: number | false } +} + async function apiFetch( endpoint: string, - options: RequestInit = {}, + options: ApiFetchOptions = {}, schema: z.ZodType, token?: string | null ): Promise { @@ -161,9 +165,11 @@ async function apiFetch( throw new Error("API_BASE_URL is not defined"); } + const { next, ...restOptions } = options; + const headers: Record = { "Content-Type": "application/json", - ...(options.headers as Record), + ...(restOptions.headers as Record), }; if (token) { @@ -171,8 +177,9 @@ async function apiFetch( } const response = await fetch(`${API_BASE_URL}${endpoint}`, { - ...options, + ...restOptions, headers, + ...(next ? { next } : {}), }); if (!response.ok) { @@ -202,7 +209,7 @@ export const loginUser = (data: z.infer) => // ── Current user ────────────────────────────────────────────────────────── export const getMe = (token: string) => - apiFetch("/users/me", {}, MeSchema, token); + apiFetch("/users/me", { next: { tags: ['me'] } }, MeSchema, token); export const updateProfile = (data: z.infer, token: string) => apiFetch("/users/me", { method: "PATCH", body: JSON.stringify(data) }, UserSchema, token); @@ -213,13 +220,13 @@ export const getMeFollowingList = (token: string) => // ── Users ───────────────────────────────────────────────────────────────── export const getUserProfile = (username: string, token: string | null) => - apiFetch(`/users/${username}`, {}, UserSchema, token); + apiFetch(`/users/${username}`, { next: { tags: [`profile:${username}`] } }, UserSchema, token); export const getFollowersList = (username: string, token: string | null) => - apiFetch(`/users/${username}/followers`, {}, z.object({ total: z.number(), items: z.array(UserSchema) }), token); + apiFetch(`/users/${username}/followers`, { next: { tags: [`profile:${username}`] } }, z.object({ total: z.number(), items: z.array(UserSchema) }), token); export const getFollowingList = (username: string, token: string | null) => - apiFetch(`/users/${username}/following`, {}, z.object({ total: z.number(), items: z.array(UserSchema) }), token); + apiFetch(`/users/${username}/following`, { next: { tags: [`profile:${username}`] } }, z.object({ total: z.number(), items: z.array(UserSchema) }), token); export const getTopFriends = (username: string, token: string | null) => apiFetch( @@ -330,7 +337,7 @@ export const getAllUsersCount = () => export const getFeed = (token: string, page: number = 1, pageSize: number = 20) => apiFetch( `/feed?page=${page}&per_page=${pageSize}`, - {}, + { next: { tags: ['feed'] } }, z.object({ items: z.array(ThoughtSchema), total: z.number(), page: z.number(), per_page: z.number() }) .transform((d) => ({ ...d, totalPages: Math.ceil(d.total / d.per_page) })), token @@ -339,7 +346,7 @@ export const getFeed = (token: string, page: number = 1, pageSize: number = 20) export const getUserThoughts = (username: string, token: string | null) => apiFetch( `/users/${username}/thoughts`, - {}, + { next: { tags: [`profile:${username}`] } }, z.object({ items: z.array(ThoughtSchema), total: z.number(), page: z.number(), per_page: z.number() }), token ); @@ -351,7 +358,7 @@ export const deleteThought = (thoughtId: string, token: string) => apiFetch(`/thoughts/${thoughtId}`, { method: "DELETE" }, z.null(), token); export const getThoughtById = (thoughtId: string, token: string | null) => - apiFetch(`/thoughts/${thoughtId}`, {}, ThoughtSchema, token); + apiFetch(`/thoughts/${thoughtId}`, { next: { tags: [`thought:${thoughtId}`] } }, ThoughtSchema, token); export const getThoughtThread = async (thoughtId: string, token: string | null): Promise => { const thoughts = await apiFetch(`/thoughts/${thoughtId}/thread`, {}, z.array(ThoughtSchema), token); @@ -375,7 +382,7 @@ export const getThoughtThread = async (thoughtId: string, token: string | null): export const getThoughtsByTag = (tagName: string, token: string | null) => apiFetch( `/tags/${tagName}`, - {}, + { next: { tags: [`tag:${tagName}`, 'feed'] } }, z.object({ tag: z.string(), items: z.array(ThoughtSchema), total: z.number(), page: z.number(), per_page: z.number() }), token ); @@ -391,7 +398,7 @@ export const getPopularTags = () => // ── Search ──────────────────────────────────────────────────────────────── export const search = (query: string, token: string | null) => - apiFetch(`/search?q=${encodeURIComponent(query)}`, {}, SearchResultsSchema, token); + apiFetch(`/search?q=${encodeURIComponent(query)}`, { next: { tags: ['search'] } }, SearchResultsSchema, token); // ── API Keys ──────────────────────────────────────────────────────────────