From 83c7000ff3da66565632c46dd8c2041b5d5f9e93 Mon Sep 17 00:00:00 2001 From: No767 <73260931+No767@users.noreply.github.com> Date: Fri, 14 Aug 2026 00:55:17 -0700 Subject: [PATCH] done --- src/routes/project/$projectId.tsx | 190 +++++++++++++----------------- src/types/kanae.gen.ts | 55 ++++++++- 2 files changed, 133 insertions(+), 112 deletions(-) diff --git a/src/routes/project/$projectId.tsx b/src/routes/project/$projectId.tsx index af1257bf..2594c8cf 100644 --- a/src/routes/project/$projectId.tsx +++ b/src/routes/project/$projectId.tsx @@ -17,19 +17,18 @@ import { } from "@/components/ui/carousel"; import { Skeleton } from "@/components/ui/skeleton"; import { cn } from "@/lib/utils"; -import { type FullProjects, type MediaRecord } from "@/types/kanae.gen"; +import { type MediaRecord, type ProjectDetails } from "@/types/kanae.gen"; export const Route = createFileRoute("/project/$projectId")({ component: Project, loader: async ({ context: { queryClient }, params: { projectId } }) => { await queryClient.ensureQueryData(projectDetailQueryOptions(projectId)); - await queryClient.ensureQueryData(projectMediaQueryOptions(projectId)); }, }); /// Types and Interfaces -type ProjectType = FullProjects["type"]; +type ProjectType = ProjectDetails["type"]; /// Module-scoped constants @@ -55,14 +54,13 @@ const FULL_DATE_FMT = new Intl.DateTimeFormat("en-US", { year: "numeric", month: const projectKeys = { all: ["project"] as const, detail: (projectId: string) => [...projectKeys.all, projectId, "detail"] as const, - media: (projectId: string) => [...projectKeys.all, projectId, "media"] as const, }; const projectDetailQueryOptions = (projectId: string) => queryOptions({ queryKey: projectKeys.detail(projectId), queryFn: async () => { - const { data } = await axios.get(`${API_BASE_URL}/projects/${projectId}`); + const { data } = await axios.get(`${API_BASE_URL}/projects/${projectId}`); return data; }, staleTime: 60_000, @@ -75,23 +73,6 @@ const projectDetailQueryOptions = (projectId: string) => refetchOnMount: false, }); -const projectMediaQueryOptions = (projectId: string) => - queryOptions({ - queryKey: projectKeys.media(projectId), - queryFn: async () => { - const { data, status } = await axios.get( - `${API_BASE_URL}/projects/${projectId}/media`, - { validateStatus: (code) => code === 200 || code === 401 || code === 403 }, - ); - return status === 200 ? data : []; - }, - staleTime: 60_000, - retry: false, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - refetchOnMount: false, - }); - /// Route Component function Project() { @@ -99,11 +80,10 @@ function Project() { const { data: project, isLoading: isProjectLoading } = useQuery( projectDetailQueryOptions(projectId), ); - const { data: media, isLoading: isMediaLoading } = useQuery(projectMediaQueryOptions(projectId)); const [lightboxIndex, setLightboxIndex] = useState(); - const mediaItems = useMemo(() => media ?? [], [media]); + const mediaItems = useMemo(() => project?.media ?? [], [project?.media]); const mediaEntries = useMemo( () => @@ -122,7 +102,6 @@ function Project() { const mediaSrc = useCallback((item: MediaRecord) => item.url, []); const meta = project ? PROJECT_TYPES[project.type] : undefined; - const showMediaSection = isMediaLoading || mediaEntries.length > 0; return (
@@ -288,7 +267,7 @@ function Project() {

- {showMediaSection ? ( + {mediaEntries.length > 0 ? (
@@ -301,91 +280,82 @@ function Project() {
- {isMediaLoading - ? Array.from({ length: 3 }, (_, i) => ( - - - - )) - : mediaEntries.map(({ item, onSelect }) => ( - - {item.kind === "video" ? ( -
- -
- - Video -
- -
- ) : ( - + {mediaEntries.map(({ item, onSelect }) => ( + + {item.kind === "video" ? ( +
+ +
+ + Video +
+ +
+ ) : ( + + )} +
+ ))}
diff --git a/src/types/kanae.gen.ts b/src/types/kanae.gen.ts index 77104f78..ee15e03c 100644 --- a/src/types/kanae.gen.ts +++ b/src/types/kanae.gen.ts @@ -2,7 +2,7 @@ export type ClientOptions = { baseUrl: - | `${string}://kanae_openapi_b5fe247856d61d12db945073906652366ae409a1.json` + | `${string}://kanae_openapi_c1d4ad2a4f89cc5b0ff0985a0a234a4f821956e0.json` | (string & {}); }; @@ -835,6 +835,57 @@ export type NotFoundResponse = { detail?: string; }; +/** + * ProjectDetails + */ +export type ProjectDetails = { + /** + * Id + */ + id: string; + /** + * Name + */ + name: string; + /** + * Description + */ + description: string; + /** + * Link + */ + link: string; + thumbnail?: ProjectThumbnail | null; + /** + * Media + */ + media: Array; + /** + * Members + */ + members: Array; + /** + * Type + */ + type: "independent" | "sig_ai" | "sig_swe" | "sig_cyber" | "sig_data" | "sig_arch" | "sig_graph"; + /** + * Tags + */ + tags?: Array | null; + /** + * Active + */ + active: boolean; + /** + * Join Policy + */ + join_policy: "open" | "request" | "closed"; + /** + * Founded At + */ + founded_at: string; +}; + /** * ProjectInvite */ @@ -2140,7 +2191,7 @@ export type GetProjectResponses = { /** * Successful Response */ - 200: FullProjects; + 200: ProjectDetails; }; export type GetProjectResponse = GetProjectResponses[keyof GetProjectResponses];