-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* style: run prisma format * feat: Add UserSolvedProblem table and relation to User model * fix: Programming language name (#31) * feat: Add checkpoint problem (#30) * feat: add create userSolvedProblem action * refactor: fix Addressability directory * feat: handle complete problem * style: display progress * feat: display progress and complete status * style: fix import and tidy up * refactor: renaming function * refactor: use server component and Improved performance --------- Co-authored-by: tatehito <[email protected]>
- Loading branch information
Showing
10 changed files
with
262 additions
and
98 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
prisma/migrations/20240209123948_create_user_solved_problem_table/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
-- CreateTable | ||
CREATE TABLE "UserSolvedProblem" ( | ||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, | ||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
"updatedAt" DATETIME NOT NULL, | ||
"userId" TEXT NOT NULL, | ||
"courseId" TEXT NOT NULL, | ||
"programId" TEXT NOT NULL, | ||
"languageId" TEXT NOT NULL, | ||
CONSTRAINT "UserSolvedProblem_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
'use client'; | ||
|
||
import { | ||
Box, | ||
Heading, | ||
VStack, | ||
Accordion, | ||
AccordionItem, | ||
AccordionButton, | ||
AccordionIcon, | ||
AccordionPanel, | ||
Select, | ||
Table, | ||
TableContainer, | ||
Thead, | ||
Tbody, | ||
Tr, | ||
Td, | ||
Th, | ||
Flex, | ||
} from '@chakra-ui/react'; | ||
import Image from 'next/image'; | ||
import NextLink from 'next/link'; | ||
import React, { useEffect, useState } from 'react'; | ||
|
||
import { | ||
courseIdToProgramIdLists, | ||
languageIdToName, | ||
languageIds, | ||
programIdToName, | ||
} from '../../../../problems/problemData'; | ||
import { getLanguageIdFromSessionStorage, setLanguageIdToSessionStorage } from '../../../lib/SessionStorage'; | ||
|
||
export const Course: React.FC<{ | ||
courseId: string; | ||
userSolvedProblems: { programId: string; languageId: string }[]; | ||
}> = ({ courseId, userSolvedProblems }) => { | ||
const [selectedLanguageId, setSelectedLanguageId] = useState(''); | ||
|
||
const SPECIFIED_COMPLETION_COUNT = 2; | ||
|
||
useEffect(() => { | ||
setSelectedLanguageId(getLanguageIdFromSessionStorage()); | ||
}, []); | ||
|
||
const handleSelectLanguage = (event: React.ChangeEvent<HTMLSelectElement>): void => { | ||
const inputValue = event.target.value; | ||
setLanguageIdToSessionStorage(inputValue); | ||
setSelectedLanguageId(inputValue); | ||
}; | ||
|
||
const countUserSolvedProblems = (programId: string, languageId: string): number => { | ||
return userSolvedProblems.filter( | ||
(userSolvedProblem) => userSolvedProblem.programId === programId && userSolvedProblem.languageId === languageId | ||
).length; | ||
}; | ||
|
||
return ( | ||
<main> | ||
<Heading as="h1" marginBottom="4"> | ||
Lessons | ||
</Heading> | ||
<Select | ||
marginBottom="4" | ||
maxW="300" | ||
placeholder="Select language" | ||
value={selectedLanguageId} | ||
onChange={(e) => handleSelectLanguage(e)} | ||
> | ||
{languageIds.map((languageId) => ( | ||
<option key={languageId} value={languageId}> | ||
{languageIdToName[languageId]} | ||
</option> | ||
))} | ||
</Select> | ||
<VStack align="stretch"> | ||
{courseIdToProgramIdLists[courseId].map((programIds, iLesson) => ( | ||
<Box key={iLesson}> | ||
<Accordion allowToggle> | ||
<AccordionItem> | ||
<AccordionButton> | ||
<Box flex="1" textAlign="left"> | ||
第{iLesson + 1}回 | ||
</Box> | ||
<AccordionIcon /> | ||
</AccordionButton> | ||
<AccordionPanel pb={4}> | ||
<TableContainer> | ||
<Table> | ||
<Thead> | ||
<Tr> | ||
<Th textAlign="left" width="50%"> | ||
プログラム | ||
</Th> | ||
<Th align="left" width="50%"> | ||
進捗 | ||
</Th> | ||
</Tr> | ||
</Thead> | ||
<Tbody> | ||
{programIds.map((programId) => ( | ||
<Tr key={programId}> | ||
<Td> | ||
<NextLink passHref href={`${courseId}/programs/${programId}`}> | ||
{programIdToName[programId]} | ||
</NextLink> | ||
</Td> | ||
<Td> | ||
<Flex> | ||
<p> | ||
{countUserSolvedProblems(programId, selectedLanguageId)} /{' '} | ||
{SPECIFIED_COMPLETION_COUNT} | ||
</p> | ||
{countUserSolvedProblems(programId, selectedLanguageId) >= | ||
SPECIFIED_COMPLETION_COUNT && ( | ||
<Box h={4} ml={2} position={'relative'} w={4}> | ||
<Image fill alt="完了の王冠" src="/crown.png" /> | ||
</Box> | ||
)} | ||
</Flex> | ||
</Td> | ||
</Tr> | ||
))} | ||
</Tbody> | ||
</Table> | ||
</TableContainer> | ||
</AccordionPanel> | ||
</AccordionItem> | ||
</Accordion> | ||
</Box> | ||
))} | ||
</VStack> | ||
</main> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,30 @@ | ||
'use client'; | ||
|
||
import { | ||
Box, | ||
Heading, | ||
OrderedList, | ||
ListItem, | ||
VStack, | ||
Accordion, | ||
AccordionItem, | ||
AccordionButton, | ||
AccordionIcon, | ||
AccordionPanel, | ||
Select, | ||
} from '@chakra-ui/react'; | ||
import type { NextPage } from 'next'; | ||
import NextLink from 'next/link'; | ||
import React, { useEffect, useState } from 'react'; | ||
import { redirect } from 'next/navigation'; | ||
|
||
import { prisma } from '../../../../infrastructures/prisma'; | ||
import { getNullableSessionOnServer } from '../../../../utils/session'; | ||
import { fetchUserSolvedProblems } from '../../../lib/actions'; | ||
|
||
import { | ||
courseIdToProgramIdLists, | ||
languageIdToName, | ||
languageIds, | ||
programIdToName, | ||
} from '../../../../problems/problemData'; | ||
import { getLanguageIdFromSessionStorage, setLanguageIdToSessionStorage } from '../../../lib/SessionStorage'; | ||
import { Course } from './Course'; | ||
|
||
const CoursePage: NextPage<{ params: { courseId: string } }> = ({ params }) => { | ||
const [selectedLanguageId, setSelectedLanguageId] = useState(''); | ||
const CoursePage: NextPage<{ params: { courseId: string } }> = async ({ params }) => { | ||
const { session } = await getNullableSessionOnServer(); | ||
const user = | ||
session && | ||
(await prisma.user.findUnique({ | ||
where: { | ||
id: session.getUserId(), | ||
}, | ||
})); | ||
|
||
useEffect(() => { | ||
setSelectedLanguageId(getLanguageIdFromSessionStorage()); | ||
}, []); | ||
if (!user) { | ||
return redirect('/auth'); | ||
} | ||
|
||
const handleSelectLanguage = (event: React.ChangeEvent<HTMLSelectElement>): void => { | ||
const inputValue = event.target.value; | ||
setLanguageIdToSessionStorage(inputValue); | ||
setSelectedLanguageId(inputValue); | ||
}; | ||
const courseId = params.courseId; | ||
const userSolvedProblems = await fetchUserSolvedProblems(user.id, courseId); | ||
|
||
return ( | ||
<main> | ||
<Heading as="h1" marginBottom="4"> | ||
Lessons | ||
</Heading> | ||
<Select | ||
marginBottom="4" | ||
maxW="300" | ||
placeholder="Select language" | ||
value={selectedLanguageId} | ||
onChange={(e) => handleSelectLanguage(e)} | ||
> | ||
{languageIds.map((languageId) => ( | ||
<option key={languageId} value={languageId}> | ||
{languageIdToName[languageId]} | ||
</option> | ||
))} | ||
</Select> | ||
<VStack align="stretch"> | ||
{courseIdToProgramIdLists[params.courseId].map((programIds, iLesson) => ( | ||
<Box key={iLesson}> | ||
<Accordion allowToggle> | ||
<AccordionItem> | ||
<AccordionButton> | ||
<Box flex="1" textAlign="left"> | ||
第{iLesson + 1}回 | ||
</Box> | ||
<AccordionIcon /> | ||
</AccordionButton> | ||
<AccordionPanel pb={4}> | ||
<OrderedList> | ||
{programIds.map((programId) => ( | ||
<ListItem key={programId}> | ||
<NextLink passHref href={`/programs/${programId}`}> | ||
{programIdToName[programId]} | ||
</NextLink> | ||
</ListItem> | ||
))} | ||
</OrderedList> | ||
</AccordionPanel> | ||
</AccordionItem> | ||
</Accordion> | ||
</Box> | ||
))} | ||
</VStack> | ||
</main> | ||
); | ||
return <Course courseId={params.courseId} userSolvedProblems={userSolvedProblems} />; | ||
}; | ||
|
||
export default CoursePage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.