Skip to content

Commit

Permalink
feat: download option
Browse files Browse the repository at this point in the history
  • Loading branch information
codaisa committed Jul 27, 2023
1 parent 43df384 commit cd9507f
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 77 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@superset-ui/embedded-sdk": "^0.1.0-alpha.9",
"@types/styled-system": "^5.1.16",
"axios": "^1.3.4",
"date-fns": "^2.30.0",
"framer-motion": "^10.2.3",
"i18next": "^22.4.11",
"react": "^18.2.0",
Expand All @@ -28,7 +29,8 @@
"react-paginate": "^8.2.0",
"react-router-dom": "6.4.3",
"react-toastify": "^9.1.1",
"styled-system": "^5.1.5"
"styled-system": "^5.1.5",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@babel/core": "^7.21.0",
Expand Down
13 changes: 13 additions & 0 deletions src/common/date/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { format, isValid } from "date-fns";
import { ptBR } from "date-fns/locale";

const formatDate = (date: Date | undefined, customFormat?: string) => {
if (date && isValid(date)) {
return format(date, customFormat || "dd MMM yyyy", {
locale: ptBR,
});
}
return "";
};

export default formatDate;
11 changes: 11 additions & 0 deletions src/common/download/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as XLSX from "xlsx";
import formatDate from "../date";

const handleDownloadJSON = (data: any, name: string) => {
let wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(data), "Relatório");

XLSX.writeFile(wb, `${name} - ${formatDate(new Date(), "dd-MM-yyyy")}.xlsx`);
};

export default handleDownloadJSON;
38 changes: 28 additions & 10 deletions src/components/HeaderPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import React from "react";
import { Button, HStack, Text, VStack } from "@chakra-ui/react";
import Icon from "../Base/Icon";
import { useTranslation } from "react-i18next";

type Props = {
title: string;
subtitle: string;
newButtonValue?: string | null;
onClickNew?: () => void;
onClickDownload?: () => void;
};

const HeaderPage: React.FC<Props> = ({
title,
subtitle,
newButtonValue,
onClickNew,
onClickDownload,
}) => {
const { t } = useTranslation();

return (
<HStack flex={1}>
<VStack flex={1} alignItems="start" mt="60px" mb="24px">
Expand All @@ -37,16 +42,29 @@ const HeaderPage: React.FC<Props> = ({
{title}
</Text>
</VStack>
{newButtonValue && onClickNew && (
<Button
variant="solid"
colorScheme="blue"
onClick={onClickNew}
gap="8px"
>
<Icon name="plus" color="#fff" size={24} /> {newButtonValue}
</Button>
)}
<HStack>
{onClickDownload && (
<Button
variant="solid"
colorScheme="blue"
onClick={onClickDownload}
gap="8px"
>
{t("general.download-data")}
</Button>
)}

{newButtonValue && onClickNew && (
<Button
variant="solid"
colorScheme="blue"
onClick={onClickNew}
gap="8px"
>
<Icon name="plus" color="#fff" size={24} /> {newButtonValue}
</Button>
)}
</HStack>
</HStack>
);
};
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/langs/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const enTranslation = {
view: "View",
delete: "Delete",
},
general: {
"download-data": "Download data",
},
};

export default enTranslation;
14 changes: 11 additions & 3 deletions src/pages/Coaches/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import {
Box,
Button,
Center,
Flex,
Heading,
Modal,
ModalBody,
ModalCloseButton,
Expand All @@ -20,6 +18,7 @@ import CoachForm from "./CoachForm";
import CoachList from "./CoachList";
import HeaderPage from "@/components/HeaderPage";
import { useTranslation } from "react-i18next";
import handleDownloadJSON from "@/common/download";

const CoachesPage: React.FC = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -73,7 +72,16 @@ const CoachesPage: React.FC = () => {

return (
<Box p={4} minH="100vh" flex={1}>
<HeaderPage subtitle={t("Navbar.data")} title={t("Navbar.coaches")} />
<HeaderPage
subtitle={t("Navbar.data")}
title={t("Navbar.coaches")}
onClickDownload={() =>
handleDownloadJSON(
coaches,
t("Navbar.coaches").toLowerCase().replaceAll(" ", "-")
)
}
/>
<CoachForm
onClose={closeForm}
onSubmit={saveCoach}
Expand Down
7 changes: 7 additions & 0 deletions src/pages/Competencies/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import CompetenceForm from "./CompetenceForm";
import CompetenceList from "./CompetenceList";
import HeaderPage from "@/components/HeaderPage";
import { useTranslation } from "react-i18next";
import handleDownloadJSON from "@/common/download";

const CompetenciesPage: React.FC = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -59,6 +60,12 @@ const CompetenciesPage: React.FC = () => {
title={t("Navbar.teaching-practices")}
newButtonValue={t("competence.new-competence")}
onClickNew={() => setNewCompetence(true)}
onClickDownload={() =>
handleDownloadJSON(
competencies,
t("Navbar.teaching-practices").toLowerCase().replaceAll(" ", "-")
)
}
/>

<CompetenceForm
Expand Down
10 changes: 7 additions & 3 deletions src/pages/Schools/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@ import {
Box,
Button,
Center,
Flex,
Heading,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
} from "@chakra-ui/react";
import { useEffect, useState } from "react";
import SchoolList from "./SchoolList";
import HeaderPage from "@/components/HeaderPage";
import { useTranslation } from "react-i18next";
import SchoolForm from "./SchoolForm";
import handleDownloadJSON from "@/common/download";

const SchoolsPage: React.FC = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -80,6 +78,12 @@ const SchoolsPage: React.FC = () => {
title={t("Navbar.schools")}
newButtonValue={t("school.new-school")}
onClickNew={() => setNewSchool(true)}
onClickDownload={() =>
handleDownloadJSON(
schools,
t("Navbar.schools").toLowerCase().replaceAll(" ", "-")
)
}
/>
<SchoolForm
onClose={closeForm}
Expand Down
10 changes: 7 additions & 3 deletions src/pages/Sessions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@ import {
Box,
Button,
Center,
Flex,
Heading,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
} from "@chakra-ui/react";
import { useEffect, useState } from "react";
import SessionForm from "./SessionForm";
import SessionList from "./SessionList";
import HeaderPage from "@/components/HeaderPage";
import { useTranslation } from "react-i18next";
import handleDownloadJSON from "@/common/download";

const SessionsPage: React.FC = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -78,6 +76,12 @@ const SessionsPage: React.FC = () => {
<HeaderPage
subtitle={t("Navbar.questionnaire")}
title={t("Navbar.coaching-sessions")}
onClickDownload={() =>
handleDownloadJSON(
sessions,
t("Navbar.sessions").toLowerCase().replaceAll(" ", "-")
)
}
/>

<SessionForm
Expand Down
69 changes: 13 additions & 56 deletions src/pages/Sync/index.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,17 @@
import Loader from "@/components/Base/Loader";
import SyncService from "@/services/sync";
import { ISync } from "@/types";
import {
Box,
Button,
Center,
Flex,
Heading,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Text,
} from "@chakra-ui/react";
import { Box, Center } from "@chakra-ui/react";
import { useEffect, useState } from "react";
import SyncList from "./SyncList";
import { useTranslation } from "react-i18next";
import HeaderPage from "@/components/HeaderPage";
import handleDownloadJSON from "@/common/download";

const SyncsPage: React.FC = () => {
const { t } = useTranslation();
const [newSync, setNewSync] = useState(false);
const [syncs, setSyncs] = useState<ISync[]>([]);
const [isLoadingList, setIsLoadingList] = useState(true);
const [isLoadingForm, setIsLoadingForm] = useState(false);
const [isLoadingDelete, setIsLoadingDelete] = useState(false);
const [syncToEdit, setSyncToEdit] = useState<ISync>();
const [syncToDelete, setSyncToDelete] = useState<ISync>();

useEffect(() => {
loadSyncs();
Expand All @@ -42,49 +24,24 @@ const SyncsPage: React.FC = () => {
setIsLoadingList(false);
};

const closeForm = () => {
setNewSync(false);
setSyncToEdit(undefined);
};

const saveSync = async (sync: Partial<ISync>) => {
setIsLoadingForm(true);
if (syncToEdit) {
await SyncService.updateSync({ ...syncToEdit, ...sync });
} else {
await SyncService.saveSync(sync);
}
setIsLoadingForm(false);
loadSyncs();
closeForm();
};

const deleteSync = async () => {
setIsLoadingDelete(true);
if (syncToDelete) await SyncService.DeleteSync(syncToDelete?.id);
setIsLoadingDelete(false);
onCloseDeleteModal();
loadSyncs();
};

const onCloseDeleteModal = () => {
setSyncToDelete(undefined);
};

return (
<Box p={4} minH="100vh" flex={1}>
{" "}
<HeaderPage title={t("Navbar.syncs")} subtitle={t("Navbar.data")} />
<HeaderPage
title={t("Navbar.syncs")}
subtitle={t("Navbar.data")}
onClickDownload={() =>
handleDownloadJSON(
syncs,
t("Navbar.syncs").toLowerCase().replaceAll(" ", "-")
)
}
/>
{isLoadingList ? (
<Center minW={"350px"} h={"200px"}>
<Loader />
</Center>
) : (
<SyncList
syncs={syncs}
handleEdit={setSyncToEdit}
handleDelete={setSyncToDelete}
/>
<SyncList syncs={syncs} handleEdit={() => {}} handleDelete={() => {}} />
)}
</Box>
);
Expand Down
12 changes: 11 additions & 1 deletion src/pages/Teacher/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import TeacherForm from "./TeacherForm";
import TeacherList from "./TeacherList";
import HeaderPage from "@/components/HeaderPage";
import { useTranslation } from "react-i18next";
import handleDownloadJSON from "@/common/download";

const TeachersPage: React.FC = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -74,7 +75,16 @@ const TeachersPage: React.FC = () => {

return (
<Box p={4} minH="100vh" flex={1}>
<HeaderPage title={t("Navbar.teachers")} subtitle={t("Navbar.data")} />
<HeaderPage
title={t("Navbar.teachers")}
subtitle={t("Navbar.data")}
onClickDownload={() =>
handleDownloadJSON(
teachers,
t("Navbar.teachers").toLowerCase().replaceAll(" ", "-")
)
}
/>
<TeacherForm
onClose={closeForm}
onSubmit={saveTeacher}
Expand Down
Loading

0 comments on commit cd9507f

Please sign in to comment.