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

Features/show travels user #25

Merged
merged 19 commits into from
Mar 30, 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
48 changes: 48 additions & 0 deletions src/components/cardCustom/TravelCard/TravelCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Button, Card, Group, Image, Text } from '@mantine/core';
import {
IconHourglassEmpty,
IconHourglassOff,
IconPlayerPlay,
} from '@tabler/icons-react';

export type TravelCardProps = {
img: string;
title: string;
description: string | null | undefined;
id: string;
startDate: string;
};

export const TravelCard = (props: TravelCardProps) => {
const isInProgress = (startDate: string) => {
const currentDate = new Date();
const tripStartDate = new Date(startDate);

switch (true) {
case currentDate.toDateString() === tripStartDate.toDateString():
return <IconPlayerPlay size={24} strokeWidth={2} color="teal" />;
case currentDate > tripStartDate:
return <IconHourglassOff size={24} strokeWidth={2} color="teal" />;
default:
return <IconHourglassEmpty size={24} strokeWidth={2} color="teal" />;
}
};

return (
<Card shadow="sm" padding="lg" radius="md" withBorder>
<Card.Section>
<Image src={props.img} height={160} alt="Norway" />
</Card.Section>
<Group justify="space-between" mt="md" mb="xs">
<Text fw={500}>{props.title}</Text>
{isInProgress(props.startDate)}
</Group>
<Text size="sm" c="dimmed">
{props.description}
</Text>
<Button color="blue" fullWidth mt="md" radius="md">
Voir Plus
</Button>
</Card>
);
};
31 changes: 31 additions & 0 deletions src/components/cardCustom/noFoundTravels/NoFoundTravels.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Image, Button, Container, Flex, Title } from '@mantine/core';
import { IconSquareRoundedPlusFilled } from '@tabler/icons-react';

const NoFoundTravels = () => {
return (
<Container size="xl" pt="xl">
<Flex
gap="md"
justify="flex-start"
align="center"
direction="column"
wrap="wrap">
<Title mt="sm" size="sm" c="teal">
Vous avez actuellement aucun voyage prévue, en cours ou terminé
</Title>
<Image
h={500}
w={600}
src="https://img.lemde.fr/2020/08/06/0/153/2480/1653/1440/960/60/0/8214e3b_835252256-dossier_univ_shanghai_2020_bonhomme_05-copie.jpg"
/>
<Button
variant="light"
rightSection={<IconSquareRoundedPlusFilled size={14} />}>
Créer un nouveau voyage
</Button>
</Flex>
</Container>
);
};

export default NoFoundTravels;
3 changes: 1 addition & 2 deletions src/components/header/DefaultHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ const DefaultHeader = (props: DefaultHeaderProps) => {

const handleTrips = () => {
handleCloseNavbar();
//TODO: Redirect to Trips list page
throw new Error('handleTrips Not implemented');
navigate('/trips');
};

const handleLogout = () => {
Expand Down
8 changes: 6 additions & 2 deletions src/components/profileMenu/ProfileMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ const ProfileMenu = () => {
await logOut();
}, []);

const handleTripsHistory = () => {
navigate('/trips/history');
};

const handleTrips = () => {
throw new Error('handleTrips Not implemented');
navigate('/trips');
};

const handleLogout = () => {
Expand Down Expand Up @@ -65,7 +69,7 @@ const ProfileMenu = () => {
leftSection={
<IconHistory style={{ width: rem(14), height: rem(14) }} />
}
onClick={handleTrips}>
onClick={handleTripsHistory}>
Historique
</Menu.Item>
<Menu.Divider />
Expand Down
31 changes: 31 additions & 0 deletions src/components/tabTravels/TabTravels.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Container, Tabs, Title } from '@mantine/core';
import { useLocation, useNavigate } from 'react-router-dom';

const TabTravels = () => {
const navigate = useNavigate();

const location = useLocation();
const currentPath = location.pathname;

const getPageName = (path: string) => {
const editPath = path.replace('/trips', '');
if (editPath === '') return 'home';
return editPath;
};

return (
<Container size="xl" mt="xl">
<Tabs value={getPageName(currentPath)}>
<Tabs.List grow justify="center">
<Tabs.Tab value="home" onClick={() => navigate('')}>
<Title order={4}>Voyages</Title>
</Tabs.Tab>
<Tabs.Tab value="/history" onClick={() => navigate('history')}>
<Title order={4}>Historique</Title>
</Tabs.Tab>
</Tabs.List>
</Tabs>
</Container>
);
};
export default TabTravels;
4 changes: 3 additions & 1 deletion src/layout/halfMap/HalfMapLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import DefaultFooter from '../../components/footer/DefaultFooter';
import DefaultHeader from '../../components/header/DefaultHeader';
import './HalfMapLayout.scss';

export const HalfMapLayout = () => {
const HalfMapLayout = () => {
const [opened, { toggle }] = useDisclosure();

return (
Expand Down Expand Up @@ -36,3 +36,5 @@ export const HalfMapLayout = () => {
</AppShell>
);
};

export default HalfMapLayout;
34 changes: 34 additions & 0 deletions src/layout/showTravels/ShowTravelsLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { AppShell } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { Outlet } from 'react-router-dom';
import DefaultFooter from '../../components/footer/DefaultFooter';
import DefaultHeader from '../../components/header/DefaultHeader';
import TabTravels from '../../components/tabTravels/TabTravels.tsx';

const ShowTravelsLayout = () => {
const [opened, { toggle }] = useDisclosure();

return (
<AppShell
header={{ height: 60 }}
navbar={{
width: 300,
breakpoint: 'sm',
collapsed: { desktop: true, mobile: !opened },
}}>
<AppShell.Header>
<DefaultHeader burgerOpened={opened} toggleBurgerState={toggle} />
</AppShell.Header>

<AppShell.Main>
<TabTravels />
<Outlet />
</AppShell.Main>
<AppShell.Footer>
<DefaultFooter />
</AppShell.Footer>
</AppShell>
);
};

export default ShowTravelsLayout;
4 changes: 3 additions & 1 deletion src/pages/landing/LandingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import HeroImageBackground from './HeroHeader';
import Content from '../../components/landing/Content';

export const LandingPage = () => {
const LandingPage = () => {
return (
<>
<HeroImageBackground />
<Content />
</>
);
};

export default LandingPage;
6 changes: 4 additions & 2 deletions src/pages/login/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { RequestResetPasswordModal } from '../../components/passwordReset/Reques
import useNotify, { NotifyDto } from '../../hooks/useNotify';
import { AuthStore, useAuthStore } from '../../store/useAuthStore';

export function LoginPage() {
const LoginPage = () => {
const login = useAuthStore((s: AuthStore) => s.login);
const navigate = useNavigate();

Expand Down Expand Up @@ -135,4 +135,6 @@ export function LoginPage() {
/>
</>
);
}
};

export default LoginPage;
2 changes: 2 additions & 0 deletions src/pages/register/RegisterPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,5 @@ export const RegisterPage = () => {
</form>
);
};

export default RegisterPage;
72 changes: 72 additions & 0 deletions src/pages/showTravels/history/HistoryPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Container, Grid, Loader, Center } from '@mantine/core';
import { TripController } from '../../../services/BaseApi';
import { TravelCard } from '../../../components/cardCustom/TravelCard/TravelCard';
import { AuthStore, useAuthStore } from '../../../store/useAuthStore';
import { useQuery } from '@tanstack/react-query';
import NoFoundTravels from '../../../components/cardCustom/noFoundTravels/NoFoundTravels';
import useNotify, { NotifyDto } from '../../../hooks/useNotify';

const HistoryPage = () => {
const userId: string | undefined = useAuthStore((s: AuthStore) => s.user?.Id);
const { ErrorNotify } = useNotify();

const { isPending, data: query } = useQuery({
queryKey: ['trips', userId],
queryFn: async () => {
if (!userId) {
return Promise.resolve([]);
}
return TripController.getAllTripByUserIdAsyncGET(userId as string)
.then((res) => res.data)
.catch(() => {
ErrorNotify({
title: "Une erreur s'est produite",
message: "Vos anciens voyages n'ont pas pu être chargés",
} as NotifyDto);
});
},
});

if (isPending) {
return (
<>
<Center mt="xl">
<Loader size="xl" />
</Center>
</>
);
}

if (!query || query.length === 0) {
return <NoFoundTravels />;
}

const currentDate = new Date();

const historyTrips = query.filter((trip) => {
if (!trip.startDate) return false;
const tripStartDate = new Date(trip.startDate);
return tripStartDate < currentDate;
});

return (
<Container size="xl" pt="xl">
<Grid gutter="lg" align="center" mb="xl">
{historyTrips.map((trip, index) => (
<Grid.Col key={index} span={{ base: 12, md: 6, lg: 3 }}>
<TravelCard
key={trip.tripId}
id={trip.tripId as string}
title={trip.name as string}
description={trip.description}
startDate={trip.startDate as string}
img={trip.backgroundPicturePath as string}
/>
</Grid.Col>
))}
</Grid>
</Container>
);
};

export default HistoryPage;
73 changes: 73 additions & 0 deletions src/pages/showTravels/myTrips/MyTrips.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { useQuery } from '@tanstack/react-query';
import { TripController } from '../../../services/BaseApi';
import { AuthStore, useAuthStore } from '../../../store/useAuthStore';

import NoFoundTravels from '../../../components/cardCustom/noFoundTravels/NoFoundTravels.tsx';
import { TravelCard } from '../../../components/cardCustom/TravelCard/TravelCard.tsx';

import { Center, Container, Grid, Loader } from '@mantine/core';
import useNotify, { NotifyDto } from '../../../hooks/useNotify.tsx';

const MyTrips = () => {
const userId: string | undefined = useAuthStore((s: AuthStore) => s.user?.Id);
const { ErrorNotify } = useNotify();

const { isPending, data: query } = useQuery({
queryKey: ['trips', userId],
queryFn: async () => {
if (!userId) {
return Promise.resolve([]);
}
return TripController.getAllTripByUserIdAsyncGET(userId as string)
.then((res) => res.data)
.catch(() => {
ErrorNotify({
title: "Une erreur s'est produite",
message: "Vos voyages n'ont pas pu être chargés",
} as NotifyDto);
});
},
});

if (isPending) {
return (
<>
<Center mt="xl">
<Loader size="xl" />
</Center>
</>
);
}

if (!query || query.length === 0) {
return <NoFoundTravels />;
}
const currentDate = new Date();

const trips = query.filter((trip) => {
if (!trip.startDate) return false;
const tripStartDate = new Date(trip.startDate);
return tripStartDate >= currentDate;
});

return (
<Container size="xl" pt="xl">
<Grid gutter="lg" align="center" mb="xl">
{trips.map((trip, index) => (
<Grid.Col key={index} span={{ base: 12, md: 6, lg: 3 }}>
<TravelCard
key={trip.tripId}
id={trip.tripId as string}
title={trip.name as string}
description={trip.description}
startDate={trip.startDate as string}
img={trip.backgroundPicturePath as string}
/>
</Grid.Col>
))}
</Grid>
</Container>
);
};

export default MyTrips;
Loading
Loading