- Implemented Skeleton component for loading states. - Added Slider component using Radix UI for customizable sliders. - Created Toaster component for notifications with theme support. - Developed Switch component for toggle functionality. - Introduced Table component with subcomponents for structured data display. - Built Tabs component for tabbed navigation. - Added Textarea component for multi-line text input. - Implemented Toggle Group and Toggle components for grouped toggle buttons. - Created Tooltip component for displaying additional information on hover. - Added User Avatar component for displaying user images with fallback. - Implemented useIsMobile hook for responsive design. - Created API utility functions for user and thought data fetching. - Added utility function for class name merging. - Updated package.json with new dependencies for UI components and utilities. - Added TypeScript configuration for path aliasing.
59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import { z } from "zod";
|
|
|
|
export const UserSchema = z.object({
|
|
id: z.uuid(),
|
|
username: z.string(),
|
|
displayName: z.string().nullable(),
|
|
bio: z.string().nullable(),
|
|
avatarUrl: z.url().nullable(),
|
|
headerUrl: z.url().nullable(),
|
|
customCss: z.string().nullable(),
|
|
topFriends: z.array(z.string()),
|
|
joinedAt: z.coerce.date(),
|
|
});
|
|
|
|
export const ThoughtSchema = z.object({
|
|
id: z.uuid(),
|
|
authorUsername: z.string(),
|
|
content: z.string(),
|
|
visibility: z.enum(["Public", "FriendsOnly", "Private"]),
|
|
replyToId: z.uuid().nullable(),
|
|
createdAt: z.string().datetime(),
|
|
});
|
|
|
|
export type User = z.infer<typeof UserSchema>;
|
|
export type Thought = z.infer<typeof ThoughtSchema>;
|
|
|
|
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
|
|
|
|
async function apiFetch<T>(
|
|
endpoint: string,
|
|
options: RequestInit = {},
|
|
schema: z.ZodType<T>
|
|
): Promise<T> {
|
|
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
|
|
...options,
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
...options.headers,
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`API request failed with status ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
return schema.parse(data);
|
|
}
|
|
|
|
// --- User API Functions ---
|
|
export const getUserProfile = (username: string) =>
|
|
apiFetch(`/users/${username}`, {}, UserSchema);
|
|
|
|
export const getUserThoughts = (username: string) =>
|
|
apiFetch(
|
|
`/users/${username}/thoughts`,
|
|
{},
|
|
z.object({ thoughts: z.array(ThoughtSchema) })
|
|
); |