-
발표 제목 종합 피드백
+ {/*
발표 제목 종합 피드백
@@ -22,13 +28,24 @@ const TotalScore = () => {
- {/*
+
+
발표 연습 시작하기
+
+
*/}
+
+
+
발표 속도 피드백
+
평가 일시 : {formatDate(feedbackData.practiceDate)}
+
+
+
-
-
발표 연습 시작하기
+
+ 발표 연습 다시하기
diff --git a/src/app/(afterlogin)/(common_navbar)/feedback/[id]/_components/_charts/SpeedChart.tsx b/src/app/(afterlogin)/(common_navbar)/feedback/[id]/_components/_charts/SpeedChart.tsx
new file mode 100644
index 0000000..78859d6
--- /dev/null
+++ b/src/app/(afterlogin)/(common_navbar)/feedback/[id]/_components/_charts/SpeedChart.tsx
@@ -0,0 +1,79 @@
+'use client';
+import { ApexOptions } from 'apexcharts';
+import dynamic from 'next/dynamic';
+const ReactApexChart = dynamic(() => import('react-apexcharts'), { ssr: false });
+
+interface Props {
+ grade: string;
+}
+const SpeedChart = ({ grade }: Props) => {
+ let mainColor;
+ let gradationColor;
+ if (grade === 'Slow' || grade === 'Fast') {
+ mainColor = '#fe0062';
+ gradationColor = '#ffbad1';
+ }
+ if (grade === 'Good') {
+ mainColor = '#5a1df8';
+ gradationColor = '#d7c4fe';
+ }
+
+ const options: ApexOptions = {
+ chart: {
+ redrawOnWindowResize: false,
+ type: 'radialBar',
+ },
+ colors: [mainColor],
+
+ plotOptions: {
+ radialBar: {
+ startAngle: -115,
+ endAngle: 115,
+ dataLabels: {
+ name: {
+ show: false,
+ },
+ value: {
+ fontSize: '25px',
+ formatter: function () {
+ return `${grade}`;
+ },
+ offsetY: 10,
+ show: true,
+ },
+ },
+ hollow: {
+ margin: 15,
+ size: '70%',
+ background: '#fff',
+ position: 'front',
+ dropShadow: {
+ enabled: true,
+ top: 3,
+ left: 0,
+ blur: 4,
+ opacity: 0.24,
+ },
+ },
+ },
+ },
+ fill: {
+ type: 'gradient',
+ gradient: {
+ shade: 'dark',
+ type: 'horizontal',
+ gradientToColors: [gradationColor!],
+ stops: [1, 20, 80, 100],
+ },
+ },
+ stroke: {
+ lineCap: 'round',
+ },
+ };
+
+ const series = [100];
+
+ return
;
+};
+
+export default SpeedChart;
diff --git a/src/app/(afterlogin)/(common_navbar)/feedback/[id]/_svgs/GoalIcon.tsx b/src/app/(afterlogin)/(common_navbar)/feedback/[id]/_svgs/GoalIcon.tsx
index 6a17e6d..d5f7882 100644
--- a/src/app/(afterlogin)/(common_navbar)/feedback/[id]/_svgs/GoalIcon.tsx
+++ b/src/app/(afterlogin)/(common_navbar)/feedback/[id]/_svgs/GoalIcon.tsx
@@ -14,7 +14,7 @@ const GoalIcon = () => {
r="16.9583"
fill="white"
stroke="#DDDDDD"
- stroke-width="2.75"
+ strokeWidth="2.75"
/>
diff --git a/src/app/(afterlogin)/(common_navbar)/feedback/[id]/page.module.scss b/src/app/(afterlogin)/(common_navbar)/feedback/[id]/page.module.scss
index 2e7627b..fa07d43 100644
--- a/src/app/(afterlogin)/(common_navbar)/feedback/[id]/page.module.scss
+++ b/src/app/(afterlogin)/(common_navbar)/feedback/[id]/page.module.scss
@@ -1,5 +1,5 @@
.container {
- background-color: aqua;
+ min-width: 1320px;
display: flex;
justify-content: center;
}
diff --git a/src/app/(afterlogin)/(common_navbar)/feedback/[id]/page.tsx b/src/app/(afterlogin)/(common_navbar)/feedback/[id]/page.tsx
index 1849112..3cbe74e 100644
--- a/src/app/(afterlogin)/(common_navbar)/feedback/[id]/page.tsx
+++ b/src/app/(afterlogin)/(common_navbar)/feedback/[id]/page.tsx
@@ -1,9 +1,10 @@
-import { fetch_ServerAuth } from '@/services/server/fetchServer';
import CategoryFeedback from './_components/CategoryFeedback';
import MemorizeReview from './_components/MemorizeReview';
import TotalScore from './_components/TotalScore';
import styles from './page.module.scss';
import { serverFeedbackApi } from '@/services/server/feedback';
+import { HydrationBoundary, QueryClient, dehydrate } from '@tanstack/react-query';
+import { FeedbackInfoType } from '@/types/service';
interface Props {
params: {
@@ -12,15 +13,25 @@ interface Props {
}
const page = async ({ params }: Props) => {
const id = Number(params.id);
- const res = await serverFeedbackApi.getFeedbackInfo(id);
- console.log(await res.json());
+
+ const queryClient = new QueryClient();
+ const feedbackData = await queryClient.fetchQuery({
+ queryKey: ['feedback', 'info', id],
+ queryFn: async () => {
+ const response = await serverFeedbackApi.getFeedbackInfo(id);
+ return (await response.json()) as FeedbackInfoType;
+ },
+ });
+ const dehydratedState = dehydrate(queryClient);
return (
);
diff --git a/src/app/(afterlogin)/(common_navbar)/feedback/_utils/date.ts b/src/app/(afterlogin)/(common_navbar)/feedback/_utils/date.ts
new file mode 100644
index 0000000..a67e242
--- /dev/null
+++ b/src/app/(afterlogin)/(common_navbar)/feedback/_utils/date.ts
@@ -0,0 +1,11 @@
+export const formatDate = (dateString: string) => {
+ const date = new Date(dateString);
+ // if (!(date instanceof Date) || isNaN(date.getTime())) {
+ // throw new Error('유효한 Date 객체를 입력해야 합니다.');
+ // }
+ const year = date.getFullYear();
+ const month = (date.getMonth() + 1).toString().padStart(2, '0');
+ const day = date.getDate().toString().padStart(2, '0');
+
+ return `${year}.${month}.${day}`;
+};
diff --git a/src/app/(afterlogin)/(common_navbar)/feedback/list/page.tsx b/src/app/(afterlogin)/(common_navbar)/feedback/list/page.tsx
index e3b00c4..70852fe 100644
--- a/src/app/(afterlogin)/(common_navbar)/feedback/list/page.tsx
+++ b/src/app/(afterlogin)/(common_navbar)/feedback/list/page.tsx
@@ -14,7 +14,6 @@ export default async function Page() {
},
initialPageParam: 0,
});
- console.log(listResponse.pages[0].page);
const isEmpty = listResponse.pages[0].page.empty;
@@ -27,7 +26,7 @@ export default async function Page() {
) : (
-
+
)}
diff --git a/src/app/(afterlogin)/(common_navbar)/home/_hooks/presentationList.ts b/src/app/(afterlogin)/(common_navbar)/home/_hooks/presentationList.ts
index e354d3f..f4f3257 100644
--- a/src/app/(afterlogin)/(common_navbar)/home/_hooks/presentationList.ts
+++ b/src/app/(afterlogin)/(common_navbar)/home/_hooks/presentationList.ts
@@ -1,5 +1,7 @@
import { clientHomeApi } from '@/services/client/home';
+import { clientPptApi } from '@/services/client/upload';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
+import { useRouter } from 'next/navigation';
export const useGetLatestPresentation = () => {
const response = useQuery({
@@ -18,7 +20,7 @@ export const useDeletePresentation = (id: number) => {
const response = useMutation({
mutationKey: ['delete', id],
mutationFn: async () => {
- const response = await clientHomeApi.deletePresentationList({ presentationIds: [id] });
+ await clientHomeApi.deletePresentationList({ presentationIds: [id] });
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['home', 'list'] });
@@ -29,3 +31,23 @@ export const useDeletePresentation = (id: number) => {
});
return response;
};
+
+export const useStartPresentation = (presentationId: number, start: boolean) => {
+ const router = useRouter();
+ const response = useQuery({
+ queryKey: [presentationId, 'start'],
+ queryFn: async () => {
+ try {
+ const response = await clientPptApi.getPracticeStart(presentationId);
+ router.push(`/setting/${presentationId}`);
+ return await response.json();
+ } catch (e) {
+ if (e instanceof Error) alert(e.message);
+ }
+ },
+ staleTime: 0,
+ gcTime: 0,
+ enabled: !!start,
+ });
+ return response;
+};
diff --git a/src/app/(afterlogin)/(common_navbar)/home/page.tsx b/src/app/(afterlogin)/(common_navbar)/home/page.tsx
index b3f3dc1..3a704eb 100644
--- a/src/app/(afterlogin)/(common_navbar)/home/page.tsx
+++ b/src/app/(afterlogin)/(common_navbar)/home/page.tsx
@@ -37,7 +37,7 @@ export default async function Page() {
{latestResponse !== 'empty' && }
{/* */}
-
+
)}
diff --git a/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadMemo.module.scss b/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadMemo.module.scss
index d212e19..84dbc9f 100644
--- a/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadMemo.module.scss
+++ b/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadMemo.module.scss
@@ -20,6 +20,7 @@
border: 1px solid $gray-3;
padding-right: 16px;
border-radius: 16px;
+ background-color: white;
::-webkit-scrollbar {
width: 7px;
diff --git a/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadScript.module.scss b/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadScript.module.scss
index 14622f7..afafd2f 100644
--- a/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadScript.module.scss
+++ b/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadScript.module.scss
@@ -23,6 +23,7 @@
border: 1px solid $gray-3;
border-radius: 16px;
padding-right: 14px;
+ background-color: white;
::-webkit-scrollbar {
width: 7px;
diff --git a/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadTitle.module.scss b/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadTitle.module.scss
index ee76a40..0d56e38 100644
--- a/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadTitle.module.scss
+++ b/src/app/(afterlogin)/(common_navbar)/upload/[id]/_component/UploadTitle.module.scss
@@ -22,6 +22,7 @@
height: 72px;
border-radius: 16px;
border: 1px solid $gray-3;
+ background-color: white;
&.warning {
border: 2px solid $red-7;
diff --git a/src/app/(afterlogin)/(common_navbar)/upload/[id]/_hooks/presentation.tsx b/src/app/(afterlogin)/(common_navbar)/upload/[id]/_hooks/presentation.tsx
index 5ccca94..03cda2a 100644
--- a/src/app/(afterlogin)/(common_navbar)/upload/[id]/_hooks/presentation.tsx
+++ b/src/app/(afterlogin)/(common_navbar)/upload/[id]/_hooks/presentation.tsx
@@ -21,7 +21,7 @@ export const useGetPresentationData = (slug: number) => {
export const usePostPresentationData = (submitAction: 'save' | 'start') => {
const router = useRouter();
-
+ const queryClient = useQueryClient();
const { openToast } = useToastStore();
const openToastWithData = () =>
@@ -35,14 +35,26 @@ export const usePostPresentationData = (submitAction: 'save' | 'start') => {
},
onSuccess: async (response) => {
const { presentationId } = await response.json();
- if (submitAction === 'start') router.push(`/setting/${presentationId}`);
+ if (submitAction === 'start') {
+ try {
+ await queryClient.fetchQuery({
+ queryKey: [presentationId, 'start'],
+ queryFn: async () => {
+ return await clientPptApi.getPracticeStart(presentationId);
+ },
+ });
+ router.push(`/setting/${presentationId}`);
+ } catch (e) {
+ if (e instanceof Error) alert(e.message);
+ }
+ }
if (submitAction === 'save') {
router.push(`/upload/${presentationId}`);
openToastWithData();
}
},
- onError: () => {
- alert('저장하는 도중 문제가 발생했습니다.');
+ onError: (error) => {
+ alert(error.message);
},
});
@@ -52,7 +64,6 @@ export const usePostPresentationData = (submitAction: 'save' | 'start') => {
export const usePatchPresentationData = (submitAction: 'save' | 'start', slug: number | 'new') => {
const router = useRouter();
const queryClient = useQueryClient();
-
const { openToast } = useToastStore();
const openToastWithData = () =>
@@ -67,7 +78,23 @@ export const usePatchPresentationData = (submitAction: 'save' | 'start', slug: n
},
onSuccess: async (response) => {
const { presentationId } = await response.json();
- if (submitAction === 'start') router.push(`/setting/${presentationId}`);
+
+ if (submitAction === 'start') {
+ try {
+ await queryClient.fetchQuery({
+ queryKey: [presentationId, 'start'],
+ queryFn: async () => {
+ return await clientPptApi.getPracticeStart(presentationId);
+ },
+ staleTime: 0,
+ gcTime: 0,
+ });
+ router.push(`/setting/${presentationId}`);
+ } catch (e) {
+ if (e instanceof Error) alert(e.message);
+ }
+ }
+
if (submitAction === 'save') openToastWithData();
},
onError: (error) => {
diff --git a/src/app/(afterlogin)/_components/NavMenu.tsx b/src/app/(afterlogin)/_components/NavMenu.tsx
index 1e072d6..b4a34a6 100644
--- a/src/app/(afterlogin)/_components/NavMenu.tsx
+++ b/src/app/(afterlogin)/_components/NavMenu.tsx
@@ -1,6 +1,6 @@
'use client';
-import { EventHandler, MouseEventHandler, useMemo, useState } from 'react';
+import { MouseEventHandler, useMemo } from 'react';
import styles from './Navbar.module.scss';
import classNames from 'classnames';
@@ -11,12 +11,6 @@ import { usePathname, useRouter } from 'next/navigation';
import useToggle from '@/app/_hooks/useToggle';
import Confirm from '@/app/_components/_modules/_modal/Confirm';
-type ClickedList = 'presentationList' | 'report';
-
-const isClickedList = (name: string): name is ClickedList => {
- return name === 'presentationList' || name === 'report';
-};
-
const NavMenu = () => {
const pathName = usePathname();
const pageName = useMemo(() => pathName.split('/')[1], [pathName]);
@@ -65,10 +59,12 @@ const NavMenu = () => {
}
if (name === 'home') {
+ router.refresh();
router.push('/home');
return;
}
if (name === 'feedback') {
+ router.refresh();
router.push('/feedback/list');
return;
}
@@ -77,18 +73,18 @@ const NavMenu = () => {
return (
<>