Skip to content

Commit f136341

Browse files
committed
Add restaurant card and toggle
1 parent 783309e commit f136341

7 files changed

+198
-22
lines changed

src/App.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import AppLayout from '@app/layouts/AppLayout.tsx';
33
import { ThemeProvider } from '@mui/material/styles';
44
import { CssBaseline } from '@mui/material';
55
import { customTheme } from '@app/theme.ts';
6-
import MealOptions from '@app/pages/MealOptions.tsx';
6+
import RestaurantsOptions from '@app/pages/RestaurantsOptions.tsx';
77

88
function App() {
99

1010
return (
1111
<ThemeProvider theme={customTheme}>
1212
<CssBaseline />
1313
<AppLayout>
14-
<MealOptions />
14+
<RestaurantsOptions />
1515
</AppLayout>
1616
</ThemeProvider>
1717
)

src/components/UI/RestaurantButton.tsx

-5
This file was deleted.

src/components/UI/RestaurantCard.tsx

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { Button, Card, CardActions, CardContent, CardMedia, Typography } from '@mui/material';
2+
import ToggleSwitch from '@app/components/UI/ToggleSwitch.tsx';
3+
4+
5+
interface Props {
6+
id: number
7+
name: string
8+
description: string
9+
website: string
10+
image: string
11+
pickedRestaurantIds: number[]
12+
setPickedRestaurantIds: (id: number[]) => void
13+
}
14+
15+
export function RestaurantCard({
16+
id,
17+
name,
18+
description,
19+
website,
20+
image,
21+
pickedRestaurantIds,
22+
setPickedRestaurantIds,
23+
}: Props) {
24+
25+
function addRestaurantToPool (id: number) {
26+
setPickedRestaurantIds([...pickedRestaurantIds, id]);
27+
}
28+
29+
function removeRestaurantFromPool (id: number) {
30+
setPickedRestaurantIds(pickedRestaurantIds.filter(restaurantId => id !== restaurantId));
31+
}
32+
33+
const selected = pickedRestaurantIds.includes(id);
34+
35+
function toggleRestaurant (value: boolean) {
36+
if (value) {
37+
addRestaurantToPool(id);
38+
} else {
39+
removeRestaurantFromPool(id);
40+
}
41+
}
42+
43+
return <>
44+
<Card sx={{ maxWidth: 345 }}>
45+
<CardMedia
46+
sx={{ height: 140 }}
47+
component="img"
48+
image={image}
49+
alt={name}
50+
/>
51+
<CardContent>
52+
<Typography gutterBottom variant="h5" component="div">
53+
{name}
54+
</Typography>
55+
<Typography variant="body2" color="text.secondary">
56+
{description}
57+
</Typography>
58+
</CardContent>
59+
<CardActions>
60+
<ToggleSwitch label="Ajouter au pool de selection" checked={selected} setChecked={toggleRestaurant}></ToggleSwitch>
61+
<Button size="small" href={website} target='_blank'>Website</Button>
62+
</CardActions>
63+
</Card>
64+
</>
65+
}

src/components/UI/ToggleSwitch.tsx

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React from 'react'
2+
import { FormGroup, FormControlLabel, Switch, styled } from '@mui/material'
3+
4+
interface Props {
5+
label: string
6+
checked: boolean
7+
setChecked: (value: boolean) => void
8+
}
9+
10+
export default function ToggleSwitch({
11+
label,
12+
checked,
13+
setChecked,
14+
}: Props) {
15+
16+
const handleSwitch = (event: React.ChangeEvent<HTMLInputElement>) => {
17+
setChecked(event.target.checked);
18+
}
19+
20+
return (
21+
<FormGroup>
22+
<LabelStyled
23+
control={
24+
<Switch className={checked ? 'on' : 'off'} checked={checked} onChange={handleSwitch} />
25+
}
26+
label={label}
27+
/>
28+
</FormGroup>
29+
);
30+
}
31+
32+
33+
const LabelStyled = styled(FormControlLabel)(({ theme }) => ({
34+
'.MuiSwitch-root': {
35+
height: '55px',
36+
borderWidth: '2px',
37+
borderColor: theme.palette.mode === 'dark' ? '#fff' : theme.palette.primary.main,
38+
opacity: '1',
39+
'&:before, &:after': {
40+
content: '""',
41+
color: theme.palette.mode === 'dark' ? '#fff' : theme.palette.primary.main,
42+
textTransform: 'uppercase',
43+
fontSize: '.9rem',
44+
fontWeight: '600',
45+
position: 'absolute',
46+
top: 18,
47+
},
48+
},
49+
'&:has(.on) .MuiSwitch-track:before': {
50+
content: '"Off"',
51+
left: 20,
52+
},
53+
'&:has(.off) .MuiSwitch-track:after': {
54+
content: '"On"',
55+
right: 20,
56+
},
57+
'.MuiButtonBase-root.MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': {
58+
opacity: '1',
59+
height: '19px',
60+
width: '19px',
61+
},
62+
}));

src/data/restaurants.ts

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const data = {
2+
"restaurants": [
3+
{
4+
"id": 1,
5+
"name": "Restaurant 1",
6+
"description": "Restaurant 1 description",
7+
"website": "https://mui.com/material-ui/react-card/",
8+
"image": "https://mui.com/static/images/cards/contemplative-reptile.jpg"
9+
},
10+
{
11+
"id": 2,
12+
"name": "Restaurant 2",
13+
"description": "Restaurant 2 description",
14+
"website": "https://mui.com/material-ui/react-card/",
15+
"image": "https://mui.com/static/images/cards/contemplative-reptile.jpg"
16+
},
17+
{
18+
"id": 3,
19+
"name": "Restaurant 3",
20+
"description": "Restaurant 3 description",
21+
"website": "https://mui.com/material-ui/react-card/",
22+
"image": "https://mui.com/static/images/cards/contemplative-reptile.jpg"
23+
}
24+
]
25+
};
26+
27+
export default data;

src/pages/MealOptions.tsx

-15
This file was deleted.

src/pages/RestaurantsOptions.tsx

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Box, styled } from '@mui/material';
2+
import { RestaurantCard } from '@app/components/UI/RestaurantCard.tsx';
3+
import { useState } from 'react';
4+
import data from '@app/data/restaurants.ts';
5+
6+
export interface Restaurant {
7+
id: number
8+
name: string
9+
description: string
10+
website: string
11+
image: string
12+
}
13+
14+
export default function RestaurantsOptions() {
15+
const [pickedRestaurantIds, setPickedRestaurantIds] = useState<number[]>([]);
16+
17+
const dataRestaurants = data.restaurants;
18+
19+
console.log(pickedRestaurantIds);
20+
21+
return <StyledContainer>
22+
{dataRestaurants && dataRestaurants.map((restaurant: Restaurant) => {
23+
return <RestaurantCard
24+
key={restaurant.id}
25+
id={restaurant.id}
26+
name={restaurant.name}
27+
description={restaurant.description}
28+
website={restaurant.website}
29+
image={restaurant.image}
30+
pickedRestaurantIds={pickedRestaurantIds}
31+
setPickedRestaurantIds={setPickedRestaurantIds}
32+
/>
33+
})}
34+
35+
</StyledContainer>
36+
}
37+
38+
const StyledContainer = styled(Box)(({ theme }) => theme.unstable_sx({
39+
40+
41+
}));
42+

0 commit comments

Comments
 (0)