Created
February 6, 2023 04:32
-
-
Save AlexandroMtzG/cd15eecf5081f3d4ff38b70342710605 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Route View (Client component): Table with rows and quick row overview | |
// Date: 2023-02-04 | |
// Version: SaasRock v0.8.2 | |
import { useLoaderData, useActionData, useSearchParams, Link, useNavigate } from "@remix-run/react"; | |
import { useState, useEffect } from "react"; | |
import { useTranslation } from "react-i18next"; | |
import ButtonPrimary from "~/components/ui/buttons/ButtonPrimary"; | |
import ExternalLinkEmptyIcon from "~/components/ui/icons/ExternalLinkEmptyIcon"; | |
import IndexPageLayout from "~/components/ui/layouts/IndexPageLayout"; | |
import SlideOverWideEmpty from "~/components/ui/slideOvers/SlideOverWideEmpty"; | |
import DocumentForm from "../../components/DocumentForm"; | |
import { DocumentDto } from "../../dtos/DocumentDto"; | |
import { DocumentRoutesIndexApi } from "../api/DocumentRoutes.Index.Api"; | |
import AccountDocuments from "~/modules/documents/components/AccountDocuments"; | |
import { useAppData } from "~/utils/data/useAppData"; | |
import InputSearch from "~/components/ui/input/InputSearch"; | |
import InputSelect from "~/components/ui/input/InputSelect"; | |
import { DocumentTypeDto } from "~/modules/codeGeneratorTests/document-types/dtos/DocumentTypeDto"; | |
import DocumentTypeHelper from "~/modules/documents/helpers/DocumentTypeHelper"; | |
export default function DocumentRoutesIndexView() { | |
const { t } = useTranslation(); | |
const appData = useAppData(); | |
const data = useLoaderData<DocumentRoutesIndexApi.LoaderData>(); | |
const actionData = useActionData<{ error?: string; success?: string }>(); | |
const [searchParams, setSearchParams] = useSearchParams(); | |
const navigate = useNavigate(); | |
const [searchInput, setSearchInput] = useState<string>(""); | |
const [overviewItem, setOverviewItem] = useState<DocumentDto>(); | |
useEffect(() => { | |
setOverviewItem(data.overviewItem ?? undefined); | |
}, [data.overviewItem]); | |
function filteredTypes() { | |
return appData.documentTypes.filter( | |
(t) => t.name.toLowerCase().includes(searchInput.toLowerCase()) || t.description.toLowerCase().includes(searchInput.toLowerCase()) | |
); | |
} | |
function onClick(type: DocumentTypeDto, year: number, period: number) { | |
const existingDocument = data.items.find((d) => d.typeId === type.row.id && d.year === year && d.period === period); | |
if (existingDocument) { | |
searchParams.set("overview", existingDocument.row.id); | |
setSearchParams(searchParams); | |
} else { | |
navigate(`new?typeId=${type.row.id}&year=${year}&period=${period}`); | |
} | |
} | |
function getYear() { | |
if (searchParams.get("year")) { | |
const year = Number(searchParams.get("year")?.toString()); | |
const possibleYears = DocumentTypeHelper.getPossibleYears(); | |
if (possibleYears.find((f) => f.value === year)) { | |
return year; | |
} | |
} | |
return new Date().getFullYear(); | |
} | |
return ( | |
<IndexPageLayout | |
title={t("Documents")} | |
buttons={ | |
<> | |
<ButtonPrimary to="new">{t("shared.new")}</ButtonPrimary> | |
</> | |
} | |
> | |
<div className="flex space-x-2"> | |
<div className="w-full"> | |
<InputSearch value={searchInput} setValue={setSearchInput} /> | |
</div> | |
<div className="w-32"> | |
<InputSelect | |
value={getYear()} | |
options={DocumentTypeHelper.getPossibleYears()} | |
setValue={(e) => { | |
if (Number(e) === new Date().getFullYear()) { | |
searchParams.delete("year"); | |
} else { | |
searchParams.set("year", Number(e).toString()); | |
} | |
setSearchParams(searchParams); | |
}} | |
/> | |
</div> | |
</div> | |
<AccountDocuments year={getYear()} types={filteredTypes()} documents={data.items} onClick={onClick} /> | |
<SlideOverWideEmpty | |
withTitle={false} | |
withClose={false} | |
title={t("Document")} | |
open={!!searchParams.get("overview")?.toString()} | |
onClose={() => { | |
searchParams.delete("overview"); | |
setSearchParams(searchParams); | |
setTimeout(() => { | |
setOverviewItem(undefined); | |
}, 100); | |
}} | |
className="sm:max-w-md" | |
buttons={ | |
<> | |
<Link | |
to={overviewItem?.row.id ?? ""} | |
className="rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2" | |
> | |
<span className="sr-only">Close panel</span> | |
<ExternalLinkEmptyIcon className="h-6 w-6" aria-hidden="true" /> | |
</Link> | |
</> | |
} | |
> | |
{!overviewItem ? <div>{t("shared.loading")}...</div> : <DocumentForm item={overviewItem} actionData={actionData} />} | |
</SlideOverWideEmpty> | |
</IndexPageLayout> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment