-
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.
- Loading branch information
Showing
11 changed files
with
441 additions
and
3 deletions.
There are no files selected for viewing
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,29 @@ | ||
import { Card } from '@mantine/core'; | ||
import { CartProps } from '~/stores/cartAtom'; | ||
import BookCardThumbnail from '../books/BookCardThumbnail'; | ||
import CartCardHeader from './CartCardHeader'; | ||
|
||
interface CartCardProps { | ||
book: CartProps; | ||
} | ||
|
||
const CartCard = ({ book }: CartCardProps) => { | ||
return ( | ||
<Card shadow="sm" radius="md" pb="xs" withBorder> | ||
<Card.Section withBorder inheritPadding> | ||
<CartCardHeader | ||
id={book.id} | ||
stock={book.stock} | ||
title={book.title} | ||
volume={book.volume} | ||
thumbnail={book.thumbnail} | ||
/> | ||
</Card.Section> | ||
<Card.Section withBorder inheritPadding py="xs"> | ||
<BookCardThumbnail id={book.id} thumbnail={book.thumbnail} /> | ||
</Card.Section> | ||
</Card> | ||
); | ||
}; | ||
|
||
export default CartCard; |
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,81 @@ | ||
import { Checkbox, Group } from '@mantine/core'; | ||
import { useAtom } from 'jotai'; | ||
import type { SelectedBookProps } from '~/stores/bookAtom'; | ||
import { cartAtom, selectedCartBooksAtom } from '~/stores/cartAtom'; | ||
import CartCardNumberInput from './CartCardNumberInput'; | ||
|
||
interface CartCardHeaderProps { | ||
id: number; | ||
stock: number; | ||
title: string; | ||
volume: number; | ||
thumbnail?: string; | ||
} | ||
|
||
const CartCardHeader = ({ | ||
id, | ||
stock, | ||
title, | ||
volume, | ||
thumbnail, | ||
}: CartCardHeaderProps) => { | ||
const [cart, setCart] = useAtom(cartAtom); | ||
const [selectedCartBook, setSelectedCartBook] = useAtom( | ||
selectedCartBooksAtom, | ||
); | ||
|
||
// 該当する本のvolumeを変更する | ||
const handleChangeVolume = (id: number, value: number) => { | ||
setCart( | ||
cart.map((element) => { | ||
if (element.id === id) { | ||
return { | ||
id: element.id, | ||
stock: element.stock, | ||
title: element.title, | ||
thumbnail: element.thumbnail, | ||
volume: value, | ||
}; | ||
} | ||
return element; | ||
}), | ||
); | ||
}; | ||
|
||
// 選択されている本のIDと表示する本のIDを比較する関数 | ||
const selectedCheck = (element: SelectedBookProps) => element.id === id; | ||
|
||
const selectedBookAdd = () => { | ||
// チェックボックスの状態が変化した時に | ||
if (selectedCartBook.some(selectedCheck)) { | ||
// すでに選択されていた場合は選択を外す | ||
setSelectedCartBook( | ||
selectedCartBook.filter((element) => element.id !== id), | ||
); | ||
} else { | ||
// 選択されていなかった場合は選択する | ||
setSelectedCartBook([ | ||
...selectedCartBook, | ||
{ id, stock, title, thumbnail, volume: 1 }, | ||
]); | ||
} | ||
}; | ||
|
||
return ( | ||
<Group justify="space-between" py={10}> | ||
<Checkbox | ||
value={id} | ||
checked={selectedCartBook.some(selectedCheck)} | ||
onChange={selectedBookAdd} | ||
/> | ||
<CartCardNumberInput | ||
id={id} | ||
stock={stock} | ||
volume={volume} | ||
handleChangeVolume={handleChangeVolume} | ||
/> | ||
</Group> | ||
); | ||
}; | ||
|
||
export default CartCardHeader; |
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,40 @@ | ||
import { Group, Select, Text } from '@mantine/core'; | ||
import { range } from '@mantine/hooks'; | ||
|
||
interface CartCardHeaderBadgeProps { | ||
id: number; | ||
stock: number; | ||
volume: number; | ||
handleChangeVolume: (id: number, value: number) => void; | ||
} | ||
|
||
const CartCardNumberInput = ({ | ||
id, | ||
stock, | ||
volume, | ||
handleChangeVolume, | ||
}: CartCardHeaderBadgeProps) => { | ||
const stockList = range(0, stock); | ||
const dataList = stock >= volume ? stockList : [...stockList, volume]; | ||
const strList = dataList.map((data) => data.toString()); | ||
|
||
const handleOnChange = (volume: string | null) => { | ||
if (!volume) return; | ||
const numVolume = Number(volume); | ||
handleChangeVolume(id, numVolume); | ||
}; | ||
return ( | ||
<Group justify="flex-end" w="70%"> | ||
<Text>冊数</Text> | ||
<Select | ||
w="50%" | ||
data={strList} | ||
value={String(volume)} | ||
error={volume > stock} | ||
onChange={(value) => handleOnChange(value)} | ||
/> | ||
</Group> | ||
); | ||
}; | ||
|
||
export default CartCardNumberInput; |
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,31 @@ | ||
import { ScrollArea, SimpleGrid } from '@mantine/core'; | ||
import { useAtom } from 'jotai'; | ||
import { cartAtom } from '~/stores/cartAtom'; | ||
import CartCard from './CartCard'; | ||
|
||
const CartCards = () => { | ||
const [cart] = useAtom(cartAtom); | ||
|
||
return ( | ||
<ScrollArea h="70dh"> | ||
<SimpleGrid | ||
type="container" | ||
cols={{ | ||
base: 2, | ||
'500px': 3, | ||
'800px': 4, | ||
'1100px': 5, | ||
'1400px': 6, | ||
'1700px': 7, | ||
}} | ||
spacing={{ base: 10, '300px': 'xl' }} | ||
> | ||
{cart.map((book, index) => ( | ||
<CartCard key={index} book={book} /> | ||
))} | ||
</SimpleGrid> | ||
</ScrollArea> | ||
); | ||
}; | ||
|
||
export default CartCards; |
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,30 @@ | ||
import { Stack } from '@mantine/core'; | ||
import CartTitle from './CartTitle'; | ||
import CartCards from './CartCards'; | ||
import CartSelectedDialog from './CartSelectedDialog'; | ||
import { useAtom } from 'jotai'; | ||
import { cartAtom } from '~/stores/cartAtom'; | ||
import NoCartComponent from './NoCartComponent'; | ||
|
||
interface CartListComponentProps { | ||
handleLoanPatch: () => void; | ||
} | ||
|
||
const CartListComponent = ({ handleLoanPatch }: CartListComponentProps) => { | ||
const [cart] = useAtom(cartAtom); | ||
return ( | ||
<Stack bg="var(--mantine-color-body)" align="stretch" justify="flex-start"> | ||
<CartTitle /> | ||
{cart.length == 0 ? ( | ||
<NoCartComponent /> | ||
) : ( | ||
<> | ||
<CartCards /> | ||
<CartSelectedDialog handleLoanPatch={handleLoanPatch} /> | ||
</> | ||
)} | ||
</Stack> | ||
); | ||
}; | ||
|
||
export default CartListComponent; |
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,54 @@ | ||
import { Button, Dialog, Stack } from '@mantine/core'; | ||
import { useAtom } from 'jotai'; | ||
import { cartAtom, selectedCartBooksAtom } from '~/stores/cartAtom'; | ||
import { removeBooksFromCart } from '~/utils/cart'; | ||
|
||
interface CartSelectedDialogProps { | ||
handleLoanPatch: () => void; | ||
} | ||
|
||
const CartSelectedDialog = ({ handleLoanPatch }: CartSelectedDialogProps) => { | ||
const [selectedCartBook, setSelectedCartBook] = useAtom( | ||
selectedCartBooksAtom, | ||
); | ||
const [cart, setCart] = useAtom(cartAtom); | ||
|
||
return ( | ||
<Dialog | ||
opened={selectedCartBook.length > 0} | ||
onClose={() => setSelectedCartBook([])} | ||
> | ||
<Stack | ||
bg="var(--mantine-color-body)" | ||
align="stretch" | ||
justify="center" | ||
gap="md" | ||
> | ||
<Button fz="xs" color="blue" onClick={handleLoanPatch}> | ||
借りる | ||
</Button> | ||
<Button | ||
fz="xs" | ||
color="red" | ||
onClick={() => { | ||
setCart(removeBooksFromCart(cart, selectedCartBook)); | ||
setSelectedCartBook([]); | ||
}} | ||
> | ||
カートから削除する | ||
</Button> | ||
<Button | ||
fz="xs" | ||
variant="light" | ||
bd="solid 2px" | ||
onClick={() => setSelectedCartBook([])} | ||
> | ||
選択を解除する | ||
</Button> | ||
</Stack> | ||
</Dialog> | ||
); | ||
return <div>CartSelectedDialog</div>; | ||
}; | ||
|
||
export default CartSelectedDialog; |
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,15 @@ | ||
import { Center, Group, Title } from '@mantine/core'; | ||
import { FaShoppingCart } from 'react-icons/fa'; | ||
|
||
const CartTitle = () => { | ||
return ( | ||
<Center> | ||
<Group justify="center" align="center"> | ||
<FaShoppingCart size="3.5ch" /> | ||
<Title order={1}>貸出カート</Title> | ||
</Group> | ||
</Center> | ||
); | ||
}; | ||
|
||
export default CartTitle; |
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,19 @@ | ||
import { Anchor, Blockquote, Center } from '@mantine/core'; | ||
import { FaInfoCircle } from 'react-icons/fa'; | ||
|
||
interface NoCartComponentProps { | ||
color?: string; | ||
} | ||
|
||
const NoCartComponent = ({ color }: NoCartComponentProps) => { | ||
return ( | ||
<Center h="70dh" w="100%"> | ||
<Blockquote color={color ?? 'blue'} icon={<FaInfoCircle />} mt="xl"> | ||
カートに本が入っていません。蔵書一覧は | ||
<Anchor href="/home">こちら</Anchor>から。 | ||
</Blockquote> | ||
</Center> | ||
); | ||
}; | ||
|
||
export default NoCartComponent; |
Oops, something went wrong.