Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Problem description #43

Merged
merged 7 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use client';

import { Box, Button, Flex, HStack, VStack } from '@chakra-ui/react';
import { Box, Button, Flex, HStack, VStack, useDisclosure } from '@chakra-ui/react';
import { useRef } from 'react';

import { CustomModal } from '../../../../../../components/molecules/CustomModal';
import { SyntaxHighlighter } from '../../../../../../components/organisms/SyntaxHighlighter';
import type { TurtleGraphicsHandle } from '../../../../../../components/organisms/TurtleGraphics';
import { TurtleGraphics } from '../../../../../../components/organisms/TurtleGraphics';
Expand All @@ -12,20 +13,22 @@ import { solveProblem } from '../../../../../lib/solveProblem';
import { Variables } from './Variables';

interface CheckpointProblemProps {
beforeCheckPointLine: number;
checkPointLines: number[];
currentCheckPointLine: number;
explanation?: Record<'title' | 'body', string>;
problemProgram: string;
selectedLanguageId: string;
checkPointLines: number[];
setStep: (step: ProblemType) => void;
beforeCheckPointLine: number;
setBeforeCheckPointLine: (line: number) => void;
currentCheckPointLine: number;
setCurrentCheckPointLine: (line: number) => void;
setStep: (step: ProblemType) => void;
}

export const CheckpointProblem: React.FC<CheckpointProblemProps> = ({
beforeCheckPointLine,
checkPointLines,
currentCheckPointLine,
explanation,
problemProgram,
selectedLanguageId,
setBeforeCheckPointLine,
Expand All @@ -34,6 +37,7 @@ export const CheckpointProblem: React.FC<CheckpointProblemProps> = ({
}) => {
const turtleGraphicsRef = useRef<TurtleGraphicsHandle>(null);

const { isOpen, onClose, onOpen } = useDisclosure();
const beforeCheckpointResult = solveProblem(problemProgram).histories?.at(beforeCheckPointLine);

const handleClickResetButton = (): void => {
Expand Down Expand Up @@ -90,7 +94,14 @@ export const CheckpointProblem: React.FC<CheckpointProblemProps> = ({
</Box>
</VStack>
<VStack align="end" minW="50%" overflow="hidden">
<Button colorScheme="gray">解説</Button>
{explanation && (
<>
<Button colorScheme="gray" onClick={onOpen}>
解説
</Button>
<CustomModal body={explanation.body} isOpen={isOpen} title={explanation.title} onClose={onClose} />
</>
)}
<Box h="640px" w="100%">
<SyntaxHighlighter
beforeCheckPointLine={beforeCheckPointLine}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
'use client';

import { Box, Button, Flex, HStack, VStack } from '@chakra-ui/react';
import { Box, Button, Flex, HStack, VStack, useDisclosure } from '@chakra-ui/react';
import { useRef } from 'react';

import { CustomModal } from '../../../../../../components/molecules/CustomModal';
import { SyntaxHighlighter } from '../../../../../../components/organisms/SyntaxHighlighter';
import type { TurtleGraphicsHandle } from '../../../../../../components/organisms/TurtleGraphics';
import { TurtleGraphics } from '../../../../../../components/organisms/TurtleGraphics';
import type { ProblemType } from '../../../../../../types';

interface ExecutionResultProblemProps {
explanation?: Record<'title' | 'body', string>;
handleComplete: () => void;
problemProgram: string;
selectedLanguageId: string;
setStep: (step: ProblemType) => void;
handleComplete: () => void;
}

export const ExecutionResultProblem: React.FC<ExecutionResultProblemProps> = ({
explanation,
handleComplete,
problemProgram,
selectedLanguageId,
setStep,
}) => {
const turtleGraphicsRef = useRef<TurtleGraphicsHandle>(null);
const { isOpen, onClose, onOpen } = useDisclosure();

const handleClickResetButton = (): void => {
turtleGraphicsRef.current?.init();
Expand Down Expand Up @@ -49,7 +53,14 @@ export const ExecutionResultProblem: React.FC<ExecutionResultProblemProps> = ({
</Box>
</VStack>
<VStack align="end" minW="50%" overflow="hidden">
<Button colorScheme="gray">解説</Button>
{explanation && (
<>
<Button colorScheme="gray" onClick={onOpen}>
解説
</Button>
<CustomModal body={explanation.body} isOpen={isOpen} title={explanation.title} onClose={onClose} />
</>
)}
{/* 画面に収まる高さに設定 */}
<Box h="calc(100vh - 370px)" w="100%">
<SyntaxHighlighter code={problemProgram} programmingLanguageId={selectedLanguageId} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use client';

import { Box, Button, Flex, HStack, VStack } from '@chakra-ui/react';
import { Box, Button, Flex, HStack, VStack, useDisclosure } from '@chakra-ui/react';
import { useRef } from 'react';

import { CustomModal } from '../../../../../../components/molecules/CustomModal';
import { SyntaxHighlighter } from '../../../../../../components/organisms/SyntaxHighlighter';
import type { TurtleGraphicsHandle } from '../../../../../../components/organisms/TurtleGraphics';
import { TurtleGraphics } from '../../../../../../components/organisms/TurtleGraphics';
Expand All @@ -13,23 +14,26 @@ import { Variables } from './Variables';
interface StepProblemProps {
beforeCheckPointLine: number;
currentCheckPointLine: number;
explanation?: Record<'title' | 'body', string>;
handleComplete: () => void;
problemProgram: string;
selectedLanguageId: string;
setBeforeCheckPointLine: (line: number) => void;
setCurrentCheckPointLine: (line: number) => void;
handleComplete: () => void;
}

export const StepProblem: React.FC<StepProblemProps> = ({
beforeCheckPointLine,
currentCheckPointLine,
explanation,
handleComplete,
problemProgram,
selectedLanguageId,
setBeforeCheckPointLine,
setCurrentCheckPointLine,
}) => {
const turtleGraphicsRef = useRef<TurtleGraphicsHandle>(null);
const { isOpen, onClose, onOpen } = useDisclosure();

const beforeCheckpointResult = solveProblem(problemProgram).histories?.at(beforeCheckPointLine);

Expand Down Expand Up @@ -83,7 +87,14 @@ export const StepProblem: React.FC<StepProblemProps> = ({
</Box>
</VStack>
<VStack align="end" minW="50%" overflow="hidden">
<Button colorScheme="gray">解説</Button>
{explanation && (
<>
<Button colorScheme="gray" onClick={onOpen}>
解説
</Button>
<CustomModal body={explanation.body} isOpen={isOpen} title={explanation.title} onClose={onClose} />
</>
)}
<Box h="640px" w="100%">
<SyntaxHighlighter
beforeCheckPointLine={beforeCheckPointLine}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { NextPage } from 'next';
import { useEffect, useState } from 'react';
import { useSessionContext } from 'supertokens-auth-react/recipe/session';

import { generateProgram, programIdToName } from '../../../../../../problems/problemData';
import { generateProgram, getExplanation, programIdToName } from '../../../../../../problems/problemData';
import type { ProblemType } from '../../../../../../types';
import { getLanguageIdFromSessionStorage } from '../../../../../lib/SessionStorage';
import { createUserSolvedProblem } from '../../../../../lib/actions';
Expand Down Expand Up @@ -42,11 +42,14 @@ const ProblemPage: NextPage<{ params: { courseId: string; programId: string } }>
}
};

const explanation = getExplanation(programId, selectedLanguageId);

const ProblemComponent: React.FC = () => {
switch (step) {
case 'normal': {
return (
<ExecutionResultProblem
explanation={explanation}
handleComplete={handleSolveProblem}
problemProgram={problemProgram}
selectedLanguageId={selectedLanguageId}
Expand All @@ -60,6 +63,7 @@ const ProblemPage: NextPage<{ params: { courseId: string; programId: string } }>
beforeCheckPointLine={beforeCheckPointLine}
checkPointLines={checkPointLines}
currentCheckPointLine={currentCheckPointLine}
explanation={explanation}
problemProgram={problemProgram}
selectedLanguageId={selectedLanguageId}
setBeforeCheckPointLine={setBeforeCheckPointLine}
Expand All @@ -73,6 +77,7 @@ const ProblemPage: NextPage<{ params: { courseId: string; programId: string } }>
<StepProblem
beforeCheckPointLine={beforeCheckPointLine}
currentCheckPointLine={currentCheckPointLine}
explanation={explanation}
handleComplete={handleSolveProblem}
problemProgram={problemProgram}
selectedLanguageId={selectedLanguageId}
Expand Down
37 changes: 37 additions & 0 deletions src/components/molecules/CustomModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
Button,
ModalBody,
Modal,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
} from '@chakra-ui/react';

interface CustomModalProps {
title: string;
body: string;
isOpen: boolean;
onClose: () => void;
}

export const CustomModal: React.FC<CustomModalProps> = ({ body, isOpen, onClose, title }) => {
return (
<>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>{title}</ModalHeader>
<ModalCloseButton />
<ModalBody>{body}</ModalBody>
<ModalFooter>
<Button colorScheme="blue" onClick={onClose}>
閉じる
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
};
41 changes: 30 additions & 11 deletions src/problems/problemData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ turtle.moveForward();` || programIdToLanguageIdToProgram[programId][languageId]
);
}

export function getExplanation(programId: ProgramId, languageId: LanguageId): string {
return programIdToLanguageIdToExplanation[programId][languageId];
export function getExplanation(programId: ProgramId, languageId: LanguageId): Record<'title' | 'body', string> {
return programIdToLanguageIdToExplanation[programId]?.[languageId];
}

export const programIdToLanguageIdToProgram: Record<ProgramId, Record<LanguageId, string>> = {
Expand Down Expand Up @@ -92,21 +92,40 @@ public class Curve {
},
};

export const programIdToLanguageIdToExplanation: Record<ProgramId, Record<LanguageId, string>> = {
export const programIdToLanguageIdToExplanation: Record<
ProgramId,
Record<LanguageId, Record<'title' | 'body', string>>
> = {
straight: {
js: `
JavaScript向けの解説。JavaScript向けの解説。
js: {
title: 'JavaScript向けstraightの解説のタイトル',
body: `
JavaScript向けstraightの解説
解説文がここに入ります。
`.trim(),
java: `
Java向けの解説。Java向けの解説。
},
java: {
title: 'Java向けstraightの解説のタイトル',
body: `
Java向けstraightの解説
解説文がここに入ります。
`.trim(),
},
},
curve: {
js: `
JavaScript向けの解説。JavaScript向けの解説。
js: {
title: 'JavaScript向けcurveの解説のタイトル',
body: `
JavaScript向けcurveの解説
解説文がここに入ります。
`.trim(),
java: `
Java向けの解説。Java向けの解説。
},
java: {
title: 'Java向けcurveの解説のタイトル',
body: `
Java向けcurveの解説
解説文がここに入ります。
`.trim(),
},
},
};