Skip to content

Commit

Permalink
Merge pull request #3 from woodnext/quiz_filter
Browse files Browse the repository at this point in the history
Quiz filter
  • Loading branch information
woodnx authored Jun 26, 2023
2 parents c2952e0 + f29f815 commit bc802db
Show file tree
Hide file tree
Showing 19 changed files with 357 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ dist-ssr
*.sln
*.sw?

firebase.config.ts
src/plugins/firebase.config.ts
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Notifications } from "@mantine/notifications"
import { BrowserRouter as Router } from "react-router-dom"
import DetermineLayout from './determineLayout.tsx'
import Layout from './layouts'

export default function App() {
return (
<>
<Notifications position="top-right" />
<Router>
<DetermineLayout />
<Layout />
</Router>
</>
)
Expand Down
34 changes: 15 additions & 19 deletions src/axios.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import _axios from "axios"
// import useUserStore from "./store/user"
import { getAuth, getIdToken, onAuthStateChanged } from "firebase/auth"
import { Auth, User, getAuth, getIdToken, onAuthStateChanged } from "firebase/auth"

// const auth = getAuth()
// let idToken = ''
// onAuthStateChanged(auth, async (user) => {
// if (!user) return;

// idToken = await getIdToken(user, true)
// })

// const idToken = use
// const idToken = useUserStore.getState().idToken
const checkFirebaseAuth = (auth: Auth) => {
return new Promise<User | null>((resolve) => {
onAuthStateChanged(auth, (user) => {
// user オブジェクトを resolve
resolve(user);
});
});
}

const axios = _axios.create({
baseURL: 'http://localhost:9000/v2',
Expand All @@ -23,18 +21,16 @@ const axios = _axios.create({
responseType: 'json',
})

axios.interceptors.request.use((request) => {
axios.interceptors.request.use(async (request) => {
//リクエスト前に毎回idTokenを取得する
const auth = getAuth()
onAuthStateChanged(auth, async (user) => {
if (!user) return;

const idToken = await getIdToken(user, true)
const user = await checkFirebaseAuth(auth)

if (!idToken) return;
if (!user) return request;

request.headers.Authorization = idToken
})
const idToken = await getIdToken(user, true)
request.headers.Authorization = idToken

return request
},(error) => {
// リクエスト エラーの処理
Expand Down
43 changes: 43 additions & 0 deletions src/components/FilteringLevel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import useSWR from "swr";
import { fetcher } from "../fetchers";
import { Checkbox, DefaultProps, Group } from "@mantine/core";

interface FilteringLevelProps extends DefaultProps {
value: string[] | undefined,
onChange: React.Dispatch<React.SetStateAction<string[]>>,
}

export interface Level{
id: number,
name: string,
color: string,
}

export default function FilteringLevel({
value,
onChange,
...others
}: FilteringLevelProps) {
const { data: levels } = useSWR<Level[]>('/levels', fetcher)

return (
<Checkbox.Group
value={value}
onChange={onChange}
defaultValue={[]}
label="Select Workbook's Level"
{...others}
>
<Group>
{levels?.map(level =>
<Checkbox
value={level.id.toString()}
label={level.name}
color={level.color}
key={level.id}
/>
)}
</Group>
</Checkbox.Group>
)
}
51 changes: 51 additions & 0 deletions src/components/FilteringWord.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { DefaultProps, Group, Radio, TextInput } from "@mantine/core"
import { formInputProps } from "../hooks"

export type optionProps = {
value: string,
onChange: (value: string) => void
}

interface FilteringWordProps extends DefaultProps {
wordInputProps: formInputProps,
wordSearchOption: optionProps,
}

export default function FilteringWord({
wordInputProps,
wordSearchOption,
className,
...others
}: FilteringWordProps) {
return (
<>
<TextInput
className={className}
label="Word Search"
{...wordInputProps}
{...others}
/>
<Radio.Group
mt="sm"
label="Search Option"
{...wordSearchOption}
>
<Group>
<Radio
value="1"
label="問題文と解答の両方"
/>
<Radio
value="2"
label="問題文のみ"
/>
<Radio
value="3"
label="解答のみ"
/>
</Group>

</Radio.Group>
</>
)
}
57 changes: 57 additions & 0 deletions src/components/FilteringWorkbook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { forwardRef } from "react";
import useSWR from "swr";
import { fetcher } from "../fetchers";
import { Badge, DefaultProps, Group, MultiSelect } from "@mantine/core";

interface WorkbookProps extends React.ComponentPropsWithoutRef<'div'> {
id: string,
label: string,
color: string,
}

export interface Workbook {
id: number,
label: string,
color: string,
}

interface FilteringWorkbookProps extends DefaultProps {
value: string[] | undefined,
onChange: React.Dispatch<React.SetStateAction<string[]>>
}

export default function FilteringWorkbook({
value,
onChange,
...others
}: FilteringWorkbookProps ) {
const { data: workbooks } = useSWR<Workbook[]>('/workbooks/color', fetcher)

const data = workbooks ? workbooks.map(({id, label, ...others}) => ({...others, value: String(id), key: id, label})) : []

const Item = forwardRef<HTMLDivElement, WorkbookProps>(
({ id, label, color, ...others}: WorkbookProps, ref) => (
<div ref={ref} {...others}>
<Group noWrap>
<Badge
size="lg"
radius="sm"
color={color}
>{label}</Badge>
</Group>
</div>
))

return (
<MultiSelect
label="Select Workbooks"
searchable
data={data}
itemComponent={Item}
filter={(value, selected, item) => !selected && (item.label?.includes(value) || false)}
value={value}
onChange={onChange}
{...others}
/>
)
}
31 changes: 21 additions & 10 deletions src/components/QuizCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { Badge, Card, DefaultProps, Flex, Group, MantineNumberSize, Selectors, Text, } from "@mantine/core";
import QuizMylistButton from "./QuizMylistButton";
import QuizFavoriteButton from "./QuizFavoriteButton";
import useStyles, { QuizCardStylesParams } from "./QuizCard.styles";
import useStyles, { QuizCardStylesParams } from "./styles/QuizCard.styles";

export interface Quiz {
id: number,
question: string,
answer: string,
workbook: string,
level: string,
date: string,
}

// このtypeは,useStyleに定義されたすべてのselectorsを含む結合が存在する.
// ここではroot | title | descriptionである.
Expand All @@ -10,8 +19,7 @@ type QuizCardStylesNames = Selectors<typeof useStyles>
interface QuizCardProps extends DefaultProps<QuizCardStylesNames, QuizCardStylesParams> {
margin?: MantineNumberSize,
index: number,
question: string,
answer: string,
quiz: Quiz,
}

export default function QuizCard({
Expand All @@ -20,10 +28,8 @@ export default function QuizCard({
unstyled,
className,
margin,
index = 1,
question = "",
answer="",

index,
quiz,
}: QuizCardProps) {
const { classes, cx } = useStyles(
{ margin },
Expand All @@ -36,16 +42,21 @@ export default function QuizCard({
<Text>No.{index}</Text>
<QuizFavoriteButton/>
</Group>
<Text className={classes.text}>{question}</Text>
<Text className={classes.text}>{quiz.question}</Text>
<Text align="right" className={classes.text}>
{answer}
{quiz.answer}
</Text>
<Flex
justify="space-between"
align="center"
>
<QuizMylistButton/>
<Badge>abc2014</Badge>
<Badge
color={quiz.level}
radius="sm"
>
{quiz.workbook}({quiz.date.slice(0, 4)})
</Badge>
</Flex>
</Card>
)
Expand Down
16 changes: 4 additions & 12 deletions src/components/QuizCardList.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import QuizCard from "./QuizCard"
import { useEffect } from "react"
import useQuizzesStore from "../store/quiz"
import { Center, Loader } from "@mantine/core"
// import { useFetch } from "../hooks"

export default function QuizCardList() {
const quizzes = useQuizzesStore(state => state.quizzes)
const getQuizzes = useQuizzesStore(state => state.getQuiz)

useEffect(() => {
getQuizzes()
}, [])

if (!quizzes) {
return (
Expand All @@ -22,12 +15,11 @@ export default function QuizCardList() {

return (
<>
{quizzes?.map(({question, answer}, idx) => (
{quizzes?.map((quiz, idx) => (
<QuizCard
key={idx}
index={idx+1}
question={question}
answer={answer}
key={quiz.id}
index={idx + 1}
quiz={quiz}
styles={(theme) => ({
root: {
marginBottom: theme.spacing.xs
Expand Down
Loading

0 comments on commit bc802db

Please sign in to comment.