From 8543b60328f08b479557e53277f4b2ff096b6b71 Mon Sep 17 00:00:00 2001 From: Lea Renaux Date: Fri, 26 Apr 2024 11:15:55 +0200 Subject: [PATCH] add follow single page header --- src/i18n-en.js | 10 +++- src/i18n-fr.js | 10 +++- src/pages/FollowCampaignPage.tsx | 58 ++++++++++++++++++- src/pages/FollowPage.tsx | 6 +- src/theme.tsx | 38 ++++++++++++ src/ui/Breadcrumbs.tsx | 53 +++++++++++++++++ src/ui/PageTab.tsx | 21 +++++++ src/ui/follow/FollowCampaignProgress.tsx | 46 +++++++++++++++ src/ui/{ => follow}/FollowCardHeader.tsx | 2 +- src/ui/{ => follow}/FollowInterviewerCard.tsx | 6 +- .../FollowOrganizationUnitCard.tsx | 4 +- src/ui/follow/FollowSinglePageHeader.tsx | 39 +++++++++++++ src/ui/{ => follow}/FollowSurveyCard.tsx | 2 +- src/ui/follow/SurveyGlobalFollow.tsx | 11 ++++ 14 files changed, 292 insertions(+), 14 deletions(-) create mode 100644 src/ui/Breadcrumbs.tsx create mode 100644 src/ui/PageTab.tsx create mode 100644 src/ui/follow/FollowCampaignProgress.tsx rename src/ui/{ => follow}/FollowCardHeader.tsx (94%) rename src/ui/{ => follow}/FollowInterviewerCard.tsx (96%) rename src/ui/{ => follow}/FollowOrganizationUnitCard.tsx (96%) create mode 100644 src/ui/follow/FollowSinglePageHeader.tsx rename src/ui/{ => follow}/FollowSurveyCard.tsx (97%) create mode 100644 src/ui/follow/SurveyGlobalFollow.tsx diff --git a/src/i18n-en.js b/src/i18n-en.js index ce5754e..e77fd1d 100644 --- a/src/i18n-en.js +++ b/src/i18n-en.js @@ -29,5 +29,13 @@ export const messagesEn = { followInterviewer: "Follow an interviewer", followSurvey: 'Follow a survey', allSurveys: 'All surveys', - followOrganizationUnit: "Follow an organization unit" + followOrganizationUnit: "Follow an organization unit", + followCampaignBreacrumb: "Follow survey", + survey: "Survey", + progress: "Progress", + collect: "Collect", + reminders: "Reminders", + provisionalStatus: "Provisional status", + closedSU: "Closed SU", + terminatedSU: "Terminated SU" } \ No newline at end of file diff --git a/src/i18n-fr.js b/src/i18n-fr.js index c7b40e7..cb3192a 100644 --- a/src/i18n-fr.js +++ b/src/i18n-fr.js @@ -29,5 +29,13 @@ export const messagesFr = { followInterviewer: "Suivre un enquêteur", followSurvey: "Suivre une enquête", allSurveys: "Ensemble des enquêtes", - followOrganizationUnit: "Suivre un site" + followOrganizationUnit: "Suivre un site", + followCampaignBreacrumb: "Suivre enquête", + survey: "Enquête", + progress: "Avancement", + collect: "Collecte", + reminders: "Relances", + provisionalStatus: "Statut provisoire", + closedSU: "UE cloturées", + terminatedSU: "UE terminées" } \ No newline at end of file diff --git a/src/pages/FollowCampaignPage.tsx b/src/pages/FollowCampaignPage.tsx index e527f4f..980de1a 100644 --- a/src/pages/FollowCampaignPage.tsx +++ b/src/pages/FollowCampaignPage.tsx @@ -1,5 +1,59 @@ -import { Typography } from "@mui/material"; +import { useIntl } from "react-intl"; +import { FollowSinglePageHeader } from "../ui/follow/FollowSinglePageHeader"; +import { SyntheticEvent, useState } from "react"; +import Tabs from "@mui/material/Tabs"; +import Stack from "@mui/material/Stack"; +import { PageTab } from "../ui/PageTab"; +import { FollowCampaignProgress } from "../ui/follow/FollowCampaignProgress"; + +// TODO remove +const labelMock = "Logement"; + +enum Tab { + progress = "progress", + collect = "collect", + reminders = "reminders", + provisionalStatus = "provisionalStatus", + closedSU = "closedSU", + terminatedSU = "terminatedSU", +} export const FollowCampaignPage = () => { - return page suivre enquête; + const intl = useIntl(); + const [currentTab, setCurrentTab] = useState(Tab.progress); + const handleChange = (_: SyntheticEvent, newValue: Tab) => { + setCurrentTab(newValue); + }; + + const breadcrumbs = [ + { href: "/follow", title: "goToFollowPage" }, + intl.formatMessage({ id: "followCampaignBreacrumb" }), + labelMock, + ]; + + return ( + <> + + + {Object.keys(Tab).map(k => ( + + ))} + + + {currentTab === Tab.progress && } + {currentTab === Tab.collect && <>tab collecte} + {currentTab === Tab.reminders && <>tab relances} + {currentTab === Tab.provisionalStatus && <>tab statut provisoire} + {currentTab === Tab.closedSU && <>tab UE cloturées} + {currentTab === Tab.terminatedSU && <>tab UE terminées} + + + ); }; diff --git a/src/pages/FollowPage.tsx b/src/pages/FollowPage.tsx index 6fb688c..1ef718d 100644 --- a/src/pages/FollowPage.tsx +++ b/src/pages/FollowPage.tsx @@ -1,7 +1,7 @@ import { Row } from "../ui/Row"; -import { FollowInterviewerCard } from "../ui/FollowInterviewerCard"; -import { FollowSurveyCard } from "../ui/FollowSurveyCard"; -import { FollowOrganizationUnitCard } from "../ui/FollowOrganizationUnitCard"; +import { FollowInterviewerCard } from "../ui/follow/FollowInterviewerCard"; +import { FollowSurveyCard } from "../ui/follow/FollowSurveyCard"; +import { FollowOrganizationUnitCard } from "../ui/follow/FollowOrganizationUnitCard"; export const FollowPage = () => { // TODO use real condition diff --git a/src/theme.tsx b/src/theme.tsx index 6826824..b6a7f3d 100644 --- a/src/theme.tsx +++ b/src/theme.tsx @@ -119,6 +119,7 @@ declare module "@mui/material/Paper" { declare module "@mui/material/Tab" { interface TabPropsClassesOverrides { search: true; + cardTab: true; } } @@ -148,6 +149,7 @@ const typography = { headlineLarge: { fontSize: 32, lineHeight: "40px", + fontWeight: 400, }, headlineMedium: { fontSize: 28, @@ -323,6 +325,42 @@ export const theme = createTheme({ }, }, }, + { + props: { classes: "cardTab" }, + style: { + borderTopLeftRadius: "16px !important", + borderTopRightRadius: "16px !important", + paddingLeft: 40, + paddingRight: 40, + backgroundColor: "#EFEFEF", + border: "none", + ...typography.titleSmall, + textTransform: "none", + "&:hover": { + backgroundColor: "#EFEFEF", + }, + ":nth-of-type(2)": { + left: -20, + }, + ":nth-of-type(3)": { + left: -40, + }, + ":nth-of-type(4)": { + left: -60, + }, + ":nth-of-type(5)": { + left: -80, + }, + "&.Mui-selected": { + position: "relative", + zIndex: 2, + background: "white", + "&:hover": { + background: "white", + }, + }, + }, + }, ], }, MuiPaper: { diff --git a/src/ui/Breadcrumbs.tsx b/src/ui/Breadcrumbs.tsx new file mode 100644 index 0000000..c3a653d --- /dev/null +++ b/src/ui/Breadcrumbs.tsx @@ -0,0 +1,53 @@ +import MuiBreadcrumbs from "@mui/material/Breadcrumbs"; +import Box from "@mui/material/Box"; +import Link from "@mui/material/Link"; +import { NavLink } from "react-router-dom"; +import { useIntl } from "react-intl"; + +export type BreadcrumbsItem = { href: string; title: string } | string; + +type Props = { + items: BreadcrumbsItem[]; +}; + +export function Breadcrumbs({ items }: Readonly) { + return ( + + {items.map(item => ( + + ))} + + ); +} + +function getKey(item: BreadcrumbsItem) { + if (typeof item === "string") { + return item; + } + return item.href; +} + +function BreadcrumbsItem({ item }: Readonly<{ item: BreadcrumbsItem }>) { + const intl = useIntl(); + if (typeof item === "string") { + return ( + + {item} + + ); + } + + return ( + + {intl.formatMessage({ id: item.title })} + + ); +} diff --git a/src/ui/PageTab.tsx b/src/ui/PageTab.tsx new file mode 100644 index 0000000..e9f24e3 --- /dev/null +++ b/src/ui/PageTab.tsx @@ -0,0 +1,21 @@ +import Tab, { TabProps } from "@mui/material/Tab"; + +type Props = { + label: string; +} & TabProps; + +export const PageTab = ({ label, ...props }: Props) => { + return ( + + ); +}; diff --git a/src/ui/follow/FollowCampaignProgress.tsx b/src/ui/follow/FollowCampaignProgress.tsx new file mode 100644 index 0000000..fd0806a --- /dev/null +++ b/src/ui/follow/FollowCampaignProgress.tsx @@ -0,0 +1,46 @@ +import { useIntl } from "react-intl"; +import { SyntheticEvent, useState } from "react"; +import Tabs from "@mui/material/Tabs"; +import Stack from "@mui/material/Stack"; +import { SurveyGlobalFollow } from "./SurveyGlobalFollow"; +import { Tab as MuiTab } from "@mui/material"; + +// TODO change tabs +enum Tab { + progress = "progress", + collect = "collect", + reminders = "reminders", + provisionalStatus = "provisionalStatus", + closedSU = "closedSU", +} + +export const FollowCampaignProgress = () => { + const intl = useIntl(); + const [currentTab, setCurrentTab] = useState(Tab.progress); + const handleChange = (_: SyntheticEvent, newValue: Tab) => { + setCurrentTab(newValue); + }; + + return ( + <> + + {Object.keys(Tab).map(k => ( + + ))} + + + + {/* todo changes components and tabs */} + {currentTab === Tab.progress && } + {currentTab === Tab.collect && } + {currentTab === Tab.reminders && } + {currentTab === Tab.provisionalStatus && } + {currentTab === Tab.closedSU && } + + + ); +}; diff --git a/src/ui/FollowCardHeader.tsx b/src/ui/follow/FollowCardHeader.tsx similarity index 94% rename from src/ui/FollowCardHeader.tsx rename to src/ui/follow/FollowCardHeader.tsx index 48af30b..4424608 100644 --- a/src/ui/FollowCardHeader.tsx +++ b/src/ui/follow/FollowCardHeader.tsx @@ -1,7 +1,7 @@ import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; import { useIntl } from "react-intl"; -import { SearchField } from "./SearchField"; +import { SearchField } from "../SearchField"; import { ChangeEvent } from "react"; type Props = { diff --git a/src/ui/FollowInterviewerCard.tsx b/src/ui/follow/FollowInterviewerCard.tsx similarity index 96% rename from src/ui/FollowInterviewerCard.tsx rename to src/ui/follow/FollowInterviewerCard.tsx index 2e76d06..a0e42f7 100644 --- a/src/ui/FollowInterviewerCard.tsx +++ b/src/ui/follow/FollowInterviewerCard.tsx @@ -1,5 +1,5 @@ import { useIntl } from "react-intl"; -import { useDebouncedState } from "../hooks/useDebouncedState"; +import { useDebouncedState } from "../../hooks/useDebouncedState"; import Card from "@mui/material/Card"; import Stack from "@mui/material/Stack"; import TableContainer from "@mui/material/TableContainer"; @@ -7,9 +7,9 @@ import Table from "@mui/material/Table"; import TableHead from "@mui/material/TableHead"; import { TableBody, TableCell, TableRow } from "@mui/material"; import { useState } from "react"; -import { APISchemas } from "../types/api"; +import { APISchemas } from "../../types/api"; import { Link as RouterLink } from "react-router-dom"; -import { Link } from "./Link"; +import { Link } from "../Link"; import { FollowCardHeader } from "./FollowCardHeader"; const interviewersMock = [ diff --git a/src/ui/FollowOrganizationUnitCard.tsx b/src/ui/follow/FollowOrganizationUnitCard.tsx similarity index 96% rename from src/ui/FollowOrganizationUnitCard.tsx rename to src/ui/follow/FollowOrganizationUnitCard.tsx index 322f990..cb86c72 100644 --- a/src/ui/FollowOrganizationUnitCard.tsx +++ b/src/ui/follow/FollowOrganizationUnitCard.tsx @@ -1,5 +1,5 @@ import { useIntl } from "react-intl"; -import { useDebouncedState } from "../hooks/useDebouncedState"; +import { useDebouncedState } from "../../hooks/useDebouncedState"; import Card from "@mui/material/Card"; import Stack from "@mui/material/Stack"; import TableContainer from "@mui/material/TableContainer"; @@ -8,7 +8,7 @@ import TableHead from "@mui/material/TableHead"; import { TableBody, TableCell, TableRow } from "@mui/material"; import { useState } from "react"; import { Link as RouterLink } from "react-router-dom"; -import { Link } from "./Link"; +import { Link } from "../Link"; import { FollowCardHeader } from "./FollowCardHeader"; const OUMock = [ diff --git a/src/ui/follow/FollowSinglePageHeader.tsx b/src/ui/follow/FollowSinglePageHeader.tsx new file mode 100644 index 0000000..b10c9ad --- /dev/null +++ b/src/ui/follow/FollowSinglePageHeader.tsx @@ -0,0 +1,39 @@ +import { useNavigate } from "react-router-dom"; +import { Row } from "../Row"; +import Stack from "@mui/material/Stack"; +import { Box, Divider, IconButton, Typography } from "@mui/material"; +import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew"; +import { Breadcrumbs, BreadcrumbsItem } from "../Breadcrumbs"; +import { useIntl } from "react-intl"; + +type Props = { + category: string; + label: string; + breadcrumbs: BreadcrumbsItem[]; +}; + +export const FollowSinglePageHeader = ({ category, label, breadcrumbs }: Props) => { + const navigate = useNavigate(); + const intl = useIntl(); + + return ( + + + + + navigate(-1)}> + + + + {intl.formatMessage({ id: category })} - + + {label} + + + + + + + + ); +}; diff --git a/src/ui/FollowSurveyCard.tsx b/src/ui/follow/FollowSurveyCard.tsx similarity index 97% rename from src/ui/FollowSurveyCard.tsx rename to src/ui/follow/FollowSurveyCard.tsx index 4b821c6..d1d1504 100644 --- a/src/ui/FollowSurveyCard.tsx +++ b/src/ui/follow/FollowSurveyCard.tsx @@ -3,7 +3,7 @@ import Card from "@mui/material/Card"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; import Box from "@mui/material/Box"; -import { Link } from "./Link"; +import { Link } from "../Link"; import { Link as RouterLink } from "react-router-dom"; const surveysMock = [ diff --git a/src/ui/follow/SurveyGlobalFollow.tsx b/src/ui/follow/SurveyGlobalFollow.tsx new file mode 100644 index 0000000..a34ceab --- /dev/null +++ b/src/ui/follow/SurveyGlobalFollow.tsx @@ -0,0 +1,11 @@ +import { Card, Typography } from "@mui/material"; +import { useIntl } from "react-intl"; + +export const SurveyGlobalFollow = () => { + const intl = useIntl(); + return ( + + {intl.formatMessage({ id: "followSurvey" })} + + ); +};