Skip to content

Commit

Permalink
Merge pull request #23 from SocialGouv/feat/user-discounts
Browse files Browse the repository at this point in the history
feat: user discounts
  • Loading branch information
HoreKk authored Feb 5, 2024
2 parents 1517ead + 5f81d34 commit 5828780
Show file tree
Hide file tree
Showing 31 changed files with 3,481 additions and 424 deletions.
22 changes: 13 additions & 9 deletions webapp/src/components/BottomNavigation.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Flex, Icon, Text } from "@chakra-ui/react";
import { Flex, Icon, SimpleGrid, Text } from "@chakra-ui/react";
import { WalletIcon } from "./icons/wallet";
import { HomeIcon } from "./icons/home";
import { AccountIcon } from "./icons/account";
import { usePathname } from "next/navigation";
import { useRouter } from "next/router";
import { FiLayers } from "react-icons/fi";

const BottomNavigation = () => {
const router = useRouter();
Expand All @@ -18,7 +19,12 @@ const BottomNavigation = () => {
{
label: "Mes réductions",
icon: WalletIcon,
href: "/dashboard/offers",
href: "/dashboard/wallet",
},
{
label: "Explorer",
icon: FiLayers,
href: "/dashboard/categories",
},
{
label: "Profil",
Expand All @@ -28,16 +34,16 @@ const BottomNavigation = () => {
];

return (
<Flex
<SimpleGrid
columns={4}
borderTopRadius={24}
bgColor="white"
position="fixed"
bottom={0}
left={0}
right={0}
justifyContent="space-between"
py={5}
px={14}
px={6}
>
{navigationItems.map(({ href, label, icon }) => (
<Flex
Expand All @@ -46,9 +52,7 @@ const BottomNavigation = () => {
alignItems="center"
gap={1}
cursor="pointer"
onClick={() => {
router.push(href);
}}
onClick={() => router.push(href)}
>
<Icon
as={icon}
Expand All @@ -66,7 +70,7 @@ const BottomNavigation = () => {
</Text>
</Flex>
))}
</Flex>
</SimpleGrid>
);
};

Expand Down
115 changes: 35 additions & 80 deletions webapp/src/components/InstallationBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import React, { useEffect, useState } from "react";
import { Box, Button, Flex, Icon, Text, useToast } from "@chakra-ui/react";
import { useAuth } from "~/providers/Auth";
import { BeforeInstallPromptEvent, useAuth } from "~/providers/Auth";
import { useLocalStorage } from "usehooks-ts";
import { CloseIcon } from "@chakra-ui/icons";
import { FiX } from "react-icons/fi";

interface BeforeInstallPromptEvent extends Event {
readonly platforms: Array<string>;
readonly userChoice: Promise<{
outcome: "accepted" | "dismissed";
platform: string;
}>;
prompt(): Promise<void>;
}
const InstallationBanner: React.FC = () => {
// overlay show state
const toast = useToast();
Expand All @@ -21,20 +14,7 @@ const InstallationBanner: React.FC = () => {
"accepted" | "dismissed" | null
>("cje-pwa-user-outcome", null);

const [showing, setShowing] = useState(false);

const [deferredEvent, setDeferredEvent] =
useState<BeforeInstallPromptEvent | null>(null);

const handleBeforeInstallPrompt = (event: Event) => {
// Prevent the default behavior to keep the event available for later use
event.preventDefault();

// Save the event for later use
setDeferredEvent(event as BeforeInstallPromptEvent);

setShowing(true);
};
const { showing, deferredEvent, setShowing, setDeferredEvent } = useAuth();

async function handleInstallClick() {
if (deferredEvent) {
Expand All @@ -54,25 +34,6 @@ const InstallationBanner: React.FC = () => {
setShowing(false);
}

useEffect(() => {
if (
typeof window !== "undefined" &&
"serviceWorker" in navigator &&
(window as any)?.workbox !== undefined
) {
// const wb = (window as any)?.workbox;
// add event listeners to handle PWA lifecycle events
window.addEventListener("beforeinstallprompt", handleBeforeInstallPrompt);
}

return () => {
window.removeEventListener(
"beforeinstallprompt",
handleBeforeInstallPrompt
);
};
}, [user]);

if (
overlayShowing ||
!showing ||
Expand All @@ -82,49 +43,43 @@ const InstallationBanner: React.FC = () => {
return null;

return (
<Box
position="absolute"
bottom={24}
left={6}
right={6}
bg="white"
zIndex={49}
<Flex
flexDir="column"
mb={4}
p={4}
borderRadius={8}
bgColor="primary.500"
gap={4}
borderRadius="xl"
bgColor="cje-gray.500"
>
<Flex
alignItems="center"
justifyContent="space-between"
position="relative"
>
<Flex flexDir="column" gap={1} w="70%">
<Text fontSize="md" fontWeight="bold" color="white">
Installer l'application
</Text>
<Text fontSize="xs" color="white" noOfLines={2}>
Pour une meilleure expérience, installez l'app sur votre téléphone.
</Text>
</Flex>
<Button
size="md"
variant="ghost"
color="white"
onClick={handleInstallClick}
>
Installer
</Button>
<CloseIcon
position="absolute"
h={3}
w={3}
right={-1}
top={-1}
color="white"
<Flex alignItems="flex-start">
<Text fontSize="xl" fontWeight="bold" w="85%">
Ajouter l’application sur votre téléphone
</Text>
<Icon
as={FiX}
ml="auto"
h={7}
w={7}
onClick={() => setUserOutcome("dismissed")}
/>
</Flex>
</Box>
<Text fontWeight="medium">
Créer un raccourci sur votre téléphone pour pouvoir accéder à toutes vos
promotions simplement et rapidement.
</Text>
<Button
size="lg"
mt={3}
py={3}
fontSize="md"
fontWeight="medium"
color="black"
colorScheme="whiteBtn"
onClick={handleInstallClick}
>
Ajouter l’application sur l’accueil
</Button>
</Flex>
);
};

Expand Down
73 changes: 73 additions & 0 deletions webapp/src/components/cards/OfferCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Flex, Text } from "@chakra-ui/react";
import Image from "next/image";
import Link from "next/link";
import { OfferIncluded } from "~/server/api/routers/offer";
import { dottedPattern } from "~/utils/chakra-theme";
import { OfferKindBadge } from "../OfferKindBadge";

type OfferCardProps = {
offer: OfferIncluded;
displayExpiryDate?: boolean;
};

const OfferCard = ({ offer, displayExpiryDate = false }: OfferCardProps) => {
return (
<Link
href={`/dashboard/offer/${
offer.kind === "code" ? "online" : "in-store"
}/${offer.id}`}
>
<Flex flexDir="column">
<Flex
bgColor={offer.partner.color}
py={5}
borderTopRadius={12}
position="relative"
justifyContent="center"
alignItems="center"
sx={{ ...dottedPattern("#ffffff") }}
>
<Flex alignItems="center" borderRadius="full" p={1} bgColor="white">
<Image
src={offer.partner.icon.url ?? ""}
alt={offer.partner.icon.alt ?? ""}
width={32}
height={32}
/>
</Flex>
</Flex>
<Flex
flexDir="column"
p={3}
bgColor="white"
borderBottomRadius={8}
gap={2}
boxShadow="md"
>
<Text fontSize="sm" fontWeight="medium">
{offer.partner.name}
</Text>
<Text fontWeight="bold" fontSize="sm" noOfLines={2} h="42px">
{offer.title}
</Text>
<OfferKindBadge kind={offer.kind} variant="light" />
{displayExpiryDate && (
<Flex
alignSelf="start"
borderRadius="2xl"
bgColor="bgWhite"
py={2}
px={3}
>
<Text fontSize="xs" fontWeight="medium">
Expire le : {new Date(offer.validityTo).toLocaleDateString()}
</Text>
</Flex>
)}
</Flex>
</Flex>
</Link>
);
};

export default OfferCard;
4 changes: 2 additions & 2 deletions webapp/src/components/icons/online.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export const OnlineIcon = (props: IconProps) => {
<Icon width="16px" height="16px" viewBox="0 0 16 16">
<path
d="M4.60869 12.9565L2 2L12.9565 4.60869L9.82607 6.69567L14 10.8695L10.8695 14L6.69567 9.82607L4.60869 12.9565Z"
fill={props.color === "black" ? "white" : "black"}
stroke={props.color === "black" ? "black" : "white"}
fill="transparent"
stroke={String(props.color)}
strokeOpacity="0.95"
strokeWidth="1.5"
strokeLinecap="round"
Expand Down
35 changes: 6 additions & 29 deletions webapp/src/components/wrappers/CategoriesWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,21 @@
import { ArrowBackIcon } from '@chakra-ui/icons';
import { Button, Flex, Heading, SimpleGrid } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { ReactNode } from 'react';
import { ArrowBackIcon } from "@chakra-ui/icons";
import { Button, Flex, Heading, SimpleGrid } from "@chakra-ui/react";
import { useRouter } from "next/router";
import { ReactNode } from "react";

type CategoriesWrapperProps = {
children: ReactNode;
isLoading?: boolean;
};

const CategoriesWrapper = ({ children, isLoading }: CategoriesWrapperProps) => {
const router = useRouter();

return (
<Flex flexDir="column" pt={12} px={8} h="full">
<Flex alignItems="center" gap={4}>
<Button
colorScheme="whiteBtn"
size="md"
iconSpacing={0}
px={0}
onClick={() => router.back()}
rightIcon={<ArrowBackIcon w={6} h={6} color="black" />}
/>
<Heading as="h3" fontSize="2xl">
Les catégories
</Heading>
</Flex>
<Flex flexDir="column" pt={12} pb={24} px={8}>
<SimpleGrid
columns={isLoading ? 1 : 2}
spacing={4}
spacing={5}
alignItems="center"
h="full"
mt={8}
pb={12}
overflowY="auto"
sx={{
'::-webkit-scrollbar': {
display: 'none'
}
}}
>
{children}
</SimpleGrid>
Expand Down
26 changes: 7 additions & 19 deletions webapp/src/components/wrappers/CategoryWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ChevronLeftIcon } from '@chakra-ui/icons';
import { Box, Button, Flex, Heading } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { ReactNode } from 'react';
import { CategoryIncluded } from '~/server/api/routers/category';
import Image from 'next/image';
import { ChevronLeftIcon } from "@chakra-ui/icons";
import { Box, Button, Flex, Heading } from "@chakra-ui/react";
import { useRouter } from "next/router";
import { ReactNode } from "react";
import { CategoryIncluded } from "~/server/api/routers/category";
import Image from "next/image";

type CategoryWrapperProps = {
children: ReactNode;
Expand Down Expand Up @@ -43,19 +43,7 @@ const CategoryWrapper = ({ children, category }: CategoryWrapperProps) => {
</Heading>
</Flex>
</Box>
<Flex
flexDir="column"
gap={6}
mt={8}
h="full"
overflowY="auto"
pb={12}
sx={{
'::-webkit-scrollbar': {
display: 'none'
}
}}
>
<Flex flexDir="column" gap={6} mt={8} h="full" pb={12}>
{children}
</Flex>
</Flex>
Expand Down
Loading

0 comments on commit 5828780

Please sign in to comment.