This repository has been archived by the owner on Dec 18, 2024. It is now read-only.
-
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.
feat(rapid-handout): barebones solution
- Loading branch information
1 parent
50da90b
commit 3d53a7e
Showing
5 changed files
with
231 additions
and
0 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,35 @@ | ||
import { Button, Card, Container, Typography } from "@mui/material"; | ||
import { Box } from "@mui/system"; | ||
import { Metadata } from "next"; | ||
|
||
import DynamicLink from "@/components/DynamicLink"; | ||
import RapidHandout from "@/components/RapidHandout"; | ||
import BL_CONFIG from "@/utils/bl-config"; | ||
|
||
export const metadata: Metadata = { | ||
title: "Hurtigutdeling", | ||
description: "Adminverktøy for å raskt dele ut bøker.", | ||
}; | ||
|
||
export default function HandoutPage() { | ||
return ( | ||
<Card sx={{ paddingBottom: 4 }}> | ||
<Container component="main" maxWidth="xs"> | ||
<Box | ||
sx={{ | ||
marginTop: 2, | ||
display: "flex", | ||
flexDirection: "column", | ||
alignItems: "center", | ||
}} | ||
> | ||
<Typography variant="h1">Hurtigutdeling</Typography> | ||
<DynamicLink href={BL_CONFIG.blAdmin.basePath}> | ||
<Button sx={{ mt: 2 }}>tilbake til bl-admin</Button> | ||
</DynamicLink> | ||
<RapidHandout /> | ||
</Box> | ||
</Container> | ||
</Card> | ||
); | ||
} |
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,37 @@ | ||
"use client"; | ||
import { UserDetail } from "@boklisten/bl-model"; | ||
import { Alert, Button } from "@mui/material"; | ||
import { useState } from "react"; | ||
|
||
import { isLoggedIn } from "@/api/auth"; | ||
import DynamicLink from "@/components/DynamicLink"; | ||
import RapidHandoutDetails from "@/components/RapidHandoutDetails"; | ||
import UserDetailSearchField from "@/components/search/UserDetailSearchField"; | ||
import useIsHydrated from "@/utils/useIsHydrated"; | ||
|
||
export default function RapidHandout() { | ||
const hydrated = useIsHydrated(); | ||
const [customer, setCustomer] = useState<UserDetail | null>(null); | ||
|
||
return hydrated && isLoggedIn() ? ( | ||
<> | ||
<UserDetailSearchField | ||
onSelectedResult={(userDetail) => { | ||
setCustomer(userDetail); | ||
}} | ||
/> | ||
{customer && <RapidHandoutDetails customer={customer} />} | ||
</> | ||
) : ( | ||
<> | ||
<Alert sx={{ mt: 2 }} severity="info"> | ||
Du må logge inn som administrator for å bruke denne siden. | ||
</Alert> | ||
<DynamicLink href={"/auth/login?redirect=admin/hurtigutdeling"}> | ||
<Button variant={"contained"} sx={{ mt: 2 }}> | ||
Logg inn | ||
</Button> | ||
</DynamicLink> | ||
</> | ||
); | ||
} |
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,53 @@ | ||
import { Order, UserDetail } from "@boklisten/bl-model"; | ||
import { Alert, Typography } from "@mui/material"; | ||
import useSWR from "swr"; | ||
|
||
import BlFetcher from "@/api/blFetcher"; | ||
import { ItemStatus } from "@/components/matches/matches-helper"; | ||
import MatchItemTable from "@/components/matches/MatchItemTable"; | ||
import BL_CONFIG from "@/utils/bl-config"; | ||
|
||
function mapOrdersToItemStatuses(orders: Order[]): ItemStatus[] { | ||
return orders | ||
.filter((order) => order.byCustomer && !order.handoutByDelivery) | ||
.flatMap((order) => order.orderItems) | ||
.filter( | ||
(orderItem) => | ||
!orderItem.movedToOrder && | ||
!orderItem.handout && | ||
(orderItem.type === "rent" || | ||
orderItem.type === "buy" || | ||
orderItem.type === "partly-payment"), | ||
) | ||
.map((oi) => ({ | ||
id: oi.item, | ||
title: oi.title, | ||
fulfilled: false, | ||
})); | ||
} | ||
|
||
export default function RapidHandoutDetails({ | ||
customer, | ||
}: { | ||
customer: UserDetail; | ||
}) { | ||
const { data: orders } = useSWR( | ||
`${BL_CONFIG.collection.order}?placed=true&customer=${customer.id}`, | ||
BlFetcher.get<Order[]>, | ||
{ refreshInterval: 5000 }, | ||
); | ||
const itemStatuses = mapOrdersToItemStatuses(orders ?? []); | ||
|
||
return itemStatuses.length === 0 ? ( | ||
<Alert severity={"info"} sx={{ mt: 2 }}> | ||
Denne kunden har for øyeblikket ingen bestilte bøker | ||
</Alert> | ||
) : ( | ||
<> | ||
<Typography variant={"h2"} textAlign={"center"} mt={6}> | ||
Plukkliste | ||
</Typography> | ||
<MatchItemTable itemStatuses={itemStatuses} isSender={true} /> | ||
</> | ||
); | ||
} |
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,76 @@ | ||
import { UserDetail } from "@boklisten/bl-model"; | ||
import { Autocomplete, Typography } from "@mui/material"; | ||
import TextField from "@mui/material/TextField"; | ||
import { Box } from "@mui/system"; | ||
import { useState } from "react"; | ||
|
||
import BlFetcher from "@/api/blFetcher"; | ||
import UserDetailSearchResult from "@/components/search/UserDetailSearchResult"; | ||
import BL_CONFIG from "@/utils/bl-config"; | ||
|
||
export default function UserDetailSearchField({ | ||
onSelectedResult, | ||
}: { | ||
onSelectedResult: (userDetail: UserDetail | null) => void; | ||
}) { | ||
const [searchValue, setSearchValue] = useState<UserDetail | null>(null); | ||
const [searchResults, setSearchResults] = useState<UserDetail[]>([]); | ||
return ( | ||
<Box sx={{ width: "100%" }}> | ||
<Typography sx={{ mt: 2, mb: 1, textAlign: "center" }}> | ||
Søk etter en kunde for å se plukkliste | ||
</Typography> | ||
<Autocomplete | ||
autoComplete | ||
value={searchValue} | ||
isOptionEqualToValue={(a, b) => a.id === b.id} | ||
filterSelectedOptions | ||
getOptionLabel={(option) => option.name ?? option.email} | ||
getOptionKey={(option) => option.id} | ||
filterOptions={(x) => x} | ||
noOptionsText={null} | ||
onInputChange={async (event, newInputValue) => { | ||
if (event === null) return; | ||
if (newInputValue.length < 3) { | ||
onSelectedResult(null); | ||
setSearchValue(null); | ||
setSearchResults([]); | ||
return; | ||
} | ||
try { | ||
const result = await BlFetcher.get<UserDetail[]>( | ||
`${BL_CONFIG.collection.userDetail}?s=${newInputValue}`, | ||
); | ||
setSearchResults(result); | ||
} catch { | ||
setSearchResults([]); | ||
} | ||
}} | ||
options={searchResults} | ||
renderOption={({ key }, userDetail) => ( | ||
<UserDetailSearchResult | ||
key={key} | ||
userDetail={userDetail} | ||
onClick={() => { | ||
setSearchValue(userDetail); | ||
setSearchResults([userDetail]); | ||
onSelectedResult(userDetail); | ||
}} | ||
/> | ||
)} | ||
renderInput={(params) => ( | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-expect-error Using example from https://mui.com/material-ui/react-autocomplete/#system-FreeSolo.tsx | ||
<TextField | ||
{...params} | ||
label="Søk etter kunde" | ||
InputProps={{ | ||
...params.InputProps, | ||
type: "search", | ||
}} | ||
/> | ||
)} | ||
/> | ||
</Box> | ||
); | ||
} |
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 { UserDetail } from "@boklisten/bl-model"; | ||
import { Email, Person, Phone } from "@mui/icons-material"; | ||
import { ListItemButton, Stack, Typography } from "@mui/material"; | ||
|
||
export default function UserDetailSearchResult({ | ||
userDetail, | ||
onClick, | ||
}: { | ||
userDetail: UserDetail; | ||
onClick: () => void; | ||
}) { | ||
return ( | ||
<ListItemButton onClick={onClick}> | ||
<Stack gap={0.5}> | ||
<Stack gap={0.5} direction={"row"} alignItems={"center"}> | ||
<Person /> | ||
<Typography>{userDetail.name}</Typography> | ||
</Stack> | ||
<Stack gap={0.5} direction={"row"} alignItems={"center"}> | ||
<Email /> | ||
<Typography>{userDetail.email}</Typography> | ||
</Stack> | ||
<Stack gap={0.5} direction={"row"} alignItems={"center"}> | ||
<Phone /> | ||
<Typography>{userDetail.phone}</Typography> | ||
</Stack> | ||
</Stack> | ||
</ListItemButton> | ||
); | ||
} |