From e1188f7e1cab292dedb76c24d15ede5a90d1295d Mon Sep 17 00:00:00 2001 From: jspark2000 Date: Thu, 14 Mar 2024 11:47:38 +0000 Subject: [PATCH] feat: implements survey-unsubmit-list page --- backend/prisma/seed.ts | 45 ++++++++++++++++--- .../_components/SurveyGroupCardSection.tsx | 28 +++++++----- .../account/_component/UserListTable.tsx | 6 +-- .../AthleteAttendanceListTable.tsx | 30 ++++++++++--- .../src/app/console/schedule/[id]/page.tsx | 2 - .../_components/SurveyUnsubmitListTable.tsx | 22 +++++++++ .../app/console/survey/[id]/unsubmit/page.tsx | 28 ++++++++++++ .../_components/SurveyGroupListTable.tsx | 11 ++++- frontend/src/lib/actions.ts | 9 +++- frontend/src/lib/types/roster.ts | 6 +++ frontend/src/lib/types/survey.ts | 5 +++ 11 files changed, 160 insertions(+), 32 deletions(-) create mode 100644 frontend/src/app/console/survey/[id]/unsubmit/_components/SurveyUnsubmitListTable.tsx create mode 100644 frontend/src/app/console/survey/[id]/unsubmit/page.tsx diff --git a/backend/prisma/seed.ts b/backend/prisma/seed.ts index 28eafc5..606a8a2 100644 --- a/backend/prisma/seed.ts +++ b/backend/prisma/seed.ts @@ -5,7 +5,8 @@ import { AccountStatus, RosterStatus, RosterType, - ScheduleType + ScheduleType, + AttendanceLocation } from '@prisma/client' import { hash } from 'argon2' @@ -268,29 +269,34 @@ const seedingDatabase = async () => { { scheduleId: 1, rosterId: 1, - response: 'Present' + response: 'Present', + location: AttendanceLocation.Seoul }, { scheduleId: 1, rosterId: 2, - response: 'Present' + response: 'Present', + location: AttendanceLocation.Seoul }, { scheduleId: 1, rosterId: 3, - response: 'Present' + response: 'Present', + location: AttendanceLocation.Seoul }, { scheduleId: 1, rosterId: 5, response: 'Tardy', - reason: '수업' + reason: '수업', + location: AttendanceLocation.Suwon }, { scheduleId: 1, rosterId: 6, response: 'Tardy', - reason: '수업' + reason: '수업', + location: AttendanceLocation.Suwon }, { scheduleId: 1, @@ -314,6 +320,33 @@ const seedingDatabase = async () => { await prisma.attendance.createMany({ data: attendances }) + + const surveyTargets: Prisma.SurveyTargetCreateManyInput[] = [ + { + surveyGroupId: 2, + rosterId: 1 + }, + { + surveyGroupId: 2, + rosterId: 2 + }, + { + surveyGroupId: 2, + rosterId: 3 + }, + { + surveyGroupId: 2, + rosterId: 4 + }, + { + surveyGroupId: 2, + rosterId: 5 + } + ] + + await prisma.surveyTarget.createMany({ + data: surveyTargets + }) } const main = async () => { diff --git a/frontend/src/app/(public)/survey/_components/SurveyGroupCardSection.tsx b/frontend/src/app/(public)/survey/_components/SurveyGroupCardSection.tsx index a3c8386..d647217 100644 --- a/frontend/src/app/(public)/survey/_components/SurveyGroupCardSection.tsx +++ b/frontend/src/app/(public)/survey/_components/SurveyGroupCardSection.tsx @@ -25,6 +25,14 @@ export default async function SurveyGroupCardSection() { return } + const isClosedSurvey = (surveyGroup: SurveyGroupListItem) => { + const now = new Date() + return ( + now <= new Date(surveyGroup.startedAt) || + now >= new Date(surveyGroup.endedAt) + ) + } + return ( <>

출석조사 목록

@@ -48,27 +56,27 @@ export default async function SurveyGroupCardSection() { 시작:{' '}

마감:{' '}

- - diff --git a/frontend/src/app/console/account/_component/UserListTable.tsx b/frontend/src/app/console/account/_component/UserListTable.tsx index 6c6e0ac..4b039be 100644 --- a/frontend/src/app/console/account/_component/UserListTable.tsx +++ b/frontend/src/app/console/account/_component/UserListTable.tsx @@ -7,10 +7,6 @@ import type { ColumnDef } from '@tanstack/react-table' export default function UserListTable({ users }: { users: UserListItem[] }) { const columns: ColumnDef[] = [ - { - accessorKey: 'id', - header: 'ID' - }, { accessorKey: 'username', header: '아이디' @@ -38,7 +34,7 @@ export default function UserListTable({ users }: { users: UserListItem[] }) { return ( ) } diff --git a/frontend/src/app/console/schedule/[id]/_components/AthleteAttendanceListTable.tsx b/frontend/src/app/console/schedule/[id]/_components/AthleteAttendanceListTable.tsx index cdaea06..6698205 100644 --- a/frontend/src/app/console/schedule/[id]/_components/AthleteAttendanceListTable.tsx +++ b/frontend/src/app/console/schedule/[id]/_components/AthleteAttendanceListTable.tsx @@ -2,7 +2,7 @@ import Badge, { BadgeColor } from '@/components/Badge' import { DataTable } from '@/components/DataTable' -import { AttendanceStatus, RosterType } from '@/lib/enums' +import { AttendanceLocation, AttendanceStatus, RosterType } from '@/lib/enums' import type { AttendanceListItem } from '@/lib/types/attendance' import type { RosterListItem } from '@/lib/types/roster' import type { ColumnDef } from '@tanstack/react-table' @@ -39,6 +39,19 @@ export default function AthleteAttendanceListTable({ } } + const renderAttendanceLocation = (attendance: AttendanceListItem) => { + if (attendance.response === AttendanceStatus.Absence) return + + switch (attendance.location) { + case AttendanceLocation.Seoul: + return + case AttendanceLocation.Suwon: + return + default: + return + } + } + const renderAthleteType = (roster: RosterListItem) => { if (roster.registerYear === new Date().getFullYear()) { return @@ -47,10 +60,6 @@ export default function AthleteAttendanceListTable({ } const columns: ColumnDef[] = [ - { - accessorKey: 'id', - header: 'ID' - }, { id: 'rosterProfile', header: '이름', @@ -92,6 +101,15 @@ export default function AthleteAttendanceListTable({ return renderAthletePosition(attendance.Roster) } }, + { + accessorKey: 'location', + header: '위치', + cell: ({ row }) => { + const attendance = row.original + + return renderAttendanceLocation(attendance) + } + }, { id: 'type', header: '구분', @@ -112,7 +130,7 @@ export default function AthleteAttendanceListTable({ }, { accessorKey: 'reason', - header: '불참사유' + header: '사유' } ] diff --git a/frontend/src/app/console/schedule/[id]/page.tsx b/frontend/src/app/console/schedule/[id]/page.tsx index 0a0c5fd..8805d08 100644 --- a/frontend/src/app/console/schedule/[id]/page.tsx +++ b/frontend/src/app/console/schedule/[id]/page.tsx @@ -31,8 +31,6 @@ export default async function AttendanceStatisticPage({ searchTerm ) - console.log(attendanceList) - return (
diff --git a/frontend/src/app/console/survey/[id]/unsubmit/_components/SurveyUnsubmitListTable.tsx b/frontend/src/app/console/survey/[id]/unsubmit/_components/SurveyUnsubmitListTable.tsx new file mode 100644 index 0000000..b4544b6 --- /dev/null +++ b/frontend/src/app/console/survey/[id]/unsubmit/_components/SurveyUnsubmitListTable.tsx @@ -0,0 +1,22 @@ +import { DataTable } from '@/components/DataTable' +import type { UnsubmitRosterListItem } from '@/lib/types/roster' +import type { ColumnDef } from '@tanstack/react-table' + +export default function SurveyUnsubmitListTable({ + rosters +}: { + rosters: UnsubmitRosterListItem[] +}) { + const columns: ColumnDef[] = [ + { + accessorKey: 'name', + header: '이름' + }, + { + accessorKey: 'admissionYear', + header: '학번' + } + ] + + return +} diff --git a/frontend/src/app/console/survey/[id]/unsubmit/page.tsx b/frontend/src/app/console/survey/[id]/unsubmit/page.tsx new file mode 100644 index 0000000..639947b --- /dev/null +++ b/frontend/src/app/console/survey/[id]/unsubmit/page.tsx @@ -0,0 +1,28 @@ +import { Button } from '@/components/ui/button' +import { getSurveyUnsubmits } from '@/lib/actions' +import Link from 'next/link' +import SurveyUnsubmitListTable from './_components/SurveyUnsubmitListTable' + +export default async function SurveyUnsubmitPage({ + params +}: { + params: { + id: number + } +}) { + const surveyUnsubmitList = await getSurveyUnsubmits(params.id) + + return ( +
+
+

미응답자 명단

+ + + +
+
+ +
+
+ ) +} diff --git a/frontend/src/app/console/survey/_components/SurveyGroupListTable.tsx b/frontend/src/app/console/survey/_components/SurveyGroupListTable.tsx index c683d37..5b549e7 100644 --- a/frontend/src/app/console/survey/_components/SurveyGroupListTable.tsx +++ b/frontend/src/app/console/survey/_components/SurveyGroupListTable.tsx @@ -15,6 +15,7 @@ import { import type { SurveyGroupListItem } from '@/lib/types/survey' import type { ColumnDef } from '@tanstack/react-table' import { MoreHorizontal } from 'lucide-react' +import Link from 'next/link' import { useState } from 'react' import DeleteSurveyGroupForm from './DeleteSurveyGroupForm' import UpdateSurveyGroupForm from './UpdateSurveyGroupForm' @@ -85,7 +86,7 @@ export default function SurveyGroupListTable({ cell: ({ row }) => { return ( ) @@ -97,7 +98,7 @@ export default function SurveyGroupListTable({ cell: ({ row }) => { return ( ) @@ -127,6 +128,12 @@ export default function SurveyGroupListTable({ 메뉴 + + + 미응답자 확인 + + + handleUpdateClick(surveyGroup)}> 수정 diff --git a/frontend/src/lib/actions.ts b/frontend/src/lib/actions.ts index b7f0a55..10387e0 100644 --- a/frontend/src/lib/actions.ts +++ b/frontend/src/lib/actions.ts @@ -8,7 +8,8 @@ import type { ScheduleList, ScheduleListItem } from './types/schedule' import type { SurveyGroupList, SurveyGroupListItem, - SurveyGroupWithSchedules + SurveyGroupWithSchedules, + SurveyUnsubmitList } from './types/survey' import type { UserList, UserProfile } from './types/user' import { PAGINATION_LIMIT_DEFAULT } from './vars' @@ -73,3 +74,9 @@ export const getAttendances = async ( `/attendances?scheduleId=${scheduleId}&page=${page}&rosterType=${rosterType}&searchTerm=${searchTerm}&limit=${PAGINATION_LIMIT_DEFAULT}` ) } + +export const getSurveyUnsubmits = async (surveyGroupId: number) => { + return await fetcher.get( + `/surveys/groups/${surveyGroupId}/unsubmits` + ) +} diff --git a/frontend/src/lib/types/roster.ts b/frontend/src/lib/types/roster.ts index 1bfb2e6..4b72402 100644 --- a/frontend/src/lib/types/roster.ts +++ b/frontend/src/lib/types/roster.ts @@ -37,3 +37,9 @@ export interface RosterList { total: number rosters: RosterListItem[] } + +export interface UnsubmitRosterListItem { + name: string + admissionYear: number + profileImageUrl?: string +} diff --git a/frontend/src/lib/types/survey.ts b/frontend/src/lib/types/survey.ts index 3fde9de..63315cd 100644 --- a/frontend/src/lib/types/survey.ts +++ b/frontend/src/lib/types/survey.ts @@ -1,3 +1,4 @@ +import type { UnsubmitRosterListItem } from './roster' import type { Schedule } from './schedule' type SurveyGroupBasic = { @@ -19,3 +20,7 @@ export interface SurveyGroupWithSchedules { surveyGroup: SurveyGroupBasic schedules: Schedule[] } + +export interface SurveyUnsubmitList { + rosters: UnsubmitRosterListItem[] +}