From 022b8e85c8e25a5adda5abaa45da36ff18f9d438 Mon Sep 17 00:00:00 2001 From: Izan Gil <66965250+SrIzan10@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:00:23 +0100 Subject: [PATCH] feat: courseworkmaterial viewer --- .../courses/courseWorkMaterial/[...ids].tsx | 82 ++++++++++++++++++- lib/clients/classroom.ts | 61 ++++++++------ 2 files changed, 118 insertions(+), 25 deletions(-) diff --git a/app/(app)/drawer/courses/courseWorkMaterial/[...ids].tsx b/app/(app)/drawer/courses/courseWorkMaterial/[...ids].tsx index 5349486..5cfeb2c 100644 --- a/app/(app)/drawer/courses/courseWorkMaterial/[...ids].tsx +++ b/app/(app)/drawer/courses/courseWorkMaterial/[...ids].tsx @@ -1,5 +1,85 @@ +import type { classroom_v1 } from '@googleapis/classroom' import { useLocalSearchParams } from 'expo-router' +import { useEffect } from 'react' +import { View } from 'react-native' +import { Surface, Text } from 'react-native-paper' -export default function CourseWorkViewer() { +import { useGetCourseWorkMaterial } from '@/lib/clients/classroom' +import Loading from '@/lib/ui/components/Loading' +import SimpleAttachment from '@/lib/ui/components/SimpleAttachment' + +// TODO: Unify both courseWork and courseWorkMaterial viewers into one. +// It doesn't really change much, just the query hook and the workType check. +export default function CourseWorkMaterialViewer() { const { ids } = useLocalSearchParams() as { ids: string[] } + const courseId = ids[0] + const courseWorkId = ids[1] + const { data, isLoading } = useGetCourseWorkMaterial(courseId, courseWorkId) + + useEffect(() => { + console.log('get course work material', data) + }, [data]) + + if (isLoading) return + + return ( + + + + {data?.title} + + + {data?.description && ( + <> + Description + {data?.description} + + )} + + {data?.materials && ( + <> + Attachments + {data.materials.map((material) => { + // TODO: Move to classroom utils file + const getAttachmentDetails = ( + material: classroom_v1.Schema$Material, + ) => { + if (material.driveFile) { + return { + title: material.driveFile.driveFile!.title!, + link: material.driveFile.driveFile!.alternateLink!, + } + } + if (material.youtubeVideo) { + return { + title: material.youtubeVideo.title!, + link: material.youtubeVideo.alternateLink!, + } + } + if (material.link) { + return { + title: material.link.title || material.link.url, + link: material.link.url!, + } + } + if (material.form) { + return { + title: material.form.title!, + link: material.form.formUrl!, + } + } + return { + title: 'Unknown Material Type', + link: '#', + } + } + + const { title, link } = getAttachmentDetails(material) + return + })} + + )} + + + ) } diff --git a/lib/clients/classroom.ts b/lib/clients/classroom.ts index 89f893c..496e28b 100644 --- a/lib/clients/classroom.ts +++ b/lib/clients/classroom.ts @@ -144,30 +144,6 @@ export function useCourseWorkMaterials(courseId: string) { }) } -async function postAnnouncement(courseId: string, text: string) { - const token = await getAuthToken() - const response = await fetch( - `${BASE_URL}/v1/courses/${courseId}/announcements`, - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, - }, - body: JSON.stringify({ - text, - state: 'PUBLISHED', - }), - }, - ) - - if (!response.ok) { - throw { message: response.statusText, status: response.status } as ApiError - } - - return response.json() -} - export function usePostAnnouncement(courseId: string) { return useMutation({ mutationFn: (text: string) => postAnnouncement(courseId, text), @@ -189,6 +165,19 @@ export function useGetCourseWork(courseId: string, courseWorkId: string) { }) } +export function useGetCourseWorkMaterial( + courseId: string, + courseWorkMaterialId: string, +) { + return useQuery({ + queryKey: keys.courses.courseWorkMaterial(courseId, courseWorkMaterialId), + queryFn: () => + fetchApi( + `/v1/courses/${courseId}/courseWorkMaterials/${courseWorkMaterialId}`, + ), + }) +} + // various api utils from now on export function classroomDateTimeToISO( date: classroom_v1.Schema$Date, @@ -249,3 +238,27 @@ async function enrichWithCreatorProfile(data: any): Promise { } return data as T } + +async function postAnnouncement(courseId: string, text: string) { + const token = await getAuthToken() + const response = await fetch( + `${BASE_URL}/v1/courses/${courseId}/announcements`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify({ + text, + state: 'PUBLISHED', + }), + }, + ) + + if (!response.ok) { + throw { message: response.statusText, status: response.status } as ApiError + } + + return response.json() +}