diff --git a/.env.example b/.env.example index 908b053..4693d11 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,6 @@ # Replace USER, PASSWORD, PORT, DATABASE with your respective database user/password/port/name # Prisma database url -PRISMA_DB_URL="postgresql://postgres:postgres@localhost:11111/postgres" \ No newline at end of file +PRISMA_DB_URL="postgresql://USER:PASSWORD@localhost:PORT/DATABASE" + +NEXT_PUBLIC_API_URL="http://localhost:3000/api/" \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index 9f035c6..dbea486 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,9 +1,7 @@ { "semi": true, - "singleQuote": false, - - "printWidth": 80, - + "printWidth": 120, + "tabWidth": 2, "trailingComma": "es5" } diff --git a/app/(pages)/Donations/Add/page.tsx b/app/(pages)/Donations/Add/page.tsx new file mode 100644 index 0000000..1ec27f4 --- /dev/null +++ b/app/(pages)/Donations/Add/page.tsx @@ -0,0 +1,448 @@ +"use client"; +import * as React from "react"; +import { + AddDonationDonorFormProps, + addressTypes, + donationSources, + donationTypes, + donorCommPreferences, + donorModes, + donorStatuses, + donorTypes, + paymentMethods, + recurringFrequencies, + statesChoices, +} from "@/app/components/formComponents/FormInputProps"; +import { Box, TextField, MenuItem, Typography } from "@mui/material"; +import { useState, useEffect } from "react"; +import { Controller, useForm } from "react-hook-form"; +import { FormInputDropdown } from "@/app/components/formComponents/FormInputDropdown"; +import { FormInputTextfield } from "@/app/components/formComponents/FormInputTextfield"; +import { FormInputDate } from "@/app/components/formComponents/FormInputDate"; +import { AddFooter } from "@/app/components/donations/add/AddFooter"; +import { FormInputCheckbox } from "@/app/components/formComponents/FormInputCheckbox"; + +export default function AddDonation() { + const { + handleSubmit, + control, + reset, + setValue, + formState: { isDirty, isValid, errors }, + } = useForm({ + mode: "onChange", + defaultValues: { + donation: { + type: "", + amount: 0, + item: "", + paymentMethod: "", + campaign: "", + fundDesignation: "", + date: new Date(), + recurringFrequency: "", + source: "", + isMatching: false, + taxDeductibleAmount: 0, + receiptSent: false, + receiptNumber: "", + isAnonymous: false, + acknowledgementSent: false, + }, + donor: { + type: "Individual", + communicationPreference: "", + status: "", + notes: "", + isRetained: false, + }, + person: { firstName: "", lastName: "", emailAddress: "", phoneNumber: "" }, + organization: { name: "", emailAddress: "" }, + address: { addressLine1: "", addressLine2: "", city: "", state: "", zipCode: "", type: "" }, + }, + }); + + const [donorMode, setDonorMode] = useState("Anonymous"); + const [donorEmail, setDonorEmail] = useState(""); + + // Switch modes will reset fields to regular + useEffect(() => { + reset({ + donation: { + type: "", + amount: 0, + item: "", + paymentMethod: "", + campaign: "", + fundDesignation: "", + date: new Date(), + recurringFrequency: "", + source: "", + isMatching: false, + taxDeductibleAmount: 0, + receiptSent: false, + receiptNumber: "", + isAnonymous: false, + acknowledgementSent: false, + }, + donor: { + type: "Individual", + communicationPreference: "", + status: "", + notes: "", + isRetained: false, + }, + person: { firstName: "", lastName: "", emailAddress: "", phoneNumber: "" }, + organization: { name: "", emailAddress: "" }, + address: { addressLine1: "", addressLine2: "", city: "", state: "", zipCode: "", type: "" }, + }); + }, [donorMode]); + + return ( + + + + Add Donation + + + + + setDonorMode(event.target.value)} + > + {donorModes.map((type, index) => ( + + {type.label} + + ))} + + + + {donorMode === "Existing" && ( + + + + Donor Info + + + setDonorEmail(event.target.value)} + > + + )} + + {donorMode === "New" && ( + + + + Donor Info + + + + + + + + + + + + ( + + + + {value !== "Individual" ? "Organization" : "Individual"} Details + + + + {value !== "Individual" ? ( + <> + + + + + ) : ( + <> + + + + + + + + )} + + + + + + + + )} + /> + + )} + + + + + Donation Info + + + + { + const label = value !== "In-Kind" ? "Donation Amount" : "Item(s) Value"; + return ( + + ); + }} + /> + + value !== "In-Kind" ? ( + + ) : ( + + ) + } + /> + + + + + + + + + + + + ); +} +const styles = { + container: { + p: 4, + display: "grid", + gridTemplateColumns: "repeat(3, 1fr)", + gap: 2, + width: "100%", + }, + innerContainer: { + gridColumn: "span 3", + gridTemplateColumns: "repeat(3, 1fr)", + display: "grid", + gap: 2, + }, + title: { + gridColumn: "span 3", + mb: 1, + }, + titleText: { + fontWeight: "bold", + }, + textField: { + flex: 1, + }, +}; diff --git a/app/(pages)/Donations/Detail/[id]/page.tsx b/app/(pages)/Donations/Detail/[id]/page.tsx new file mode 100644 index 0000000..46fe46c --- /dev/null +++ b/app/(pages)/Donations/Detail/[id]/page.tsx @@ -0,0 +1,290 @@ +"use client"; +import { useParams } from "next/navigation"; +import { Box, Typography } from "@mui/material"; +import { useEffect, useRef, useState } from "react"; +import { DonationResponse } from "@/app/types/states"; +import Loading from "@/app/loading"; +import { useRouter } from "next/navigation"; +import { DetailFooter } from "@/app/components/donations/DetailFooter"; +import { + DonationFormProps, + donationSources, + donationTypes, + paymentMethods, + recurringFrequencies, +} from "@/app/components/formComponents/FormInputProps"; +import { Controller, useForm } from "react-hook-form"; +import { FormInputDropdown } from "@/app/components/formComponents/FormInputDropdown"; +import { FormInputTextfield } from "@/app/components/formComponents/FormInputTextfield"; +import { FormInputDate } from "@/app/components/formComponents/FormInputDate"; +import { grey } from "@mui/material/colors"; +import { FormInputCheckbox } from "@/app/components/formComponents/FormInputCheckbox"; + +export default function DonationDetail() { + const { id }: { id: string } = useParams(); + const router = useRouter(); + + const [isLoading, setIsLoading] = useState(true); + const donorNameRef = useRef(""); + const isAnonymousRef = useRef(false); + + const { + handleSubmit, + control, + reset, + setValue, + formState: { isDirty, isValid, errors }, + } = useForm({ + mode: "onChange", + defaultValues: { + donation: { + type: "", + amount: 0, + item: "", + paymentMethod: "", + campaign: "", + fundDesignation: "", + date: new Date(), + recurringFrequency: "None", + source: "", + isMatching: false, + taxDeductibleAmount: 0, + receiptSent: false, + receiptNumber: "", + isAnonymous: false, + acknowledgementSent: false, + }, + }, + }); + + useEffect(() => { + fetchDonation(); + }, []); + + const fetchDonation = async () => { + try { + const result = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/donations/${id}`, { + method: "GET", + }); + + const { data } = (await result.json()) as DonationResponse; + + if (!result.ok) { + const errorData = await result.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + + if (data.donor && !data.isAnonymous) { + donorNameRef.current = `${data.donor.person.firstName} ${data.donor.person.lastName}`; + } + isAnonymousRef.current = data.isAnonymous; + + reset({ + donation: { + type: data.type || "One-Time", + amount: data.amount || 0, + item: data?.item || "", + paymentMethod: data.paymentMethod || "Credit Card", + campaign: data.campaign || "", + fundDesignation: data.fundDesignation || "", + date: data.date || new Date(), + recurringFrequency: data.recurringFrequency || "None", + source: data.source || "Website", + isMatching: data.isMatching || false, + taxDeductibleAmount: data?.taxDeductibleAmount || 0, + receiptSent: data.receiptSent || false, + receiptNumber: data.receiptNumber || "", + isAnonymous: data.isAnonymous || false, + acknowledgementSent: data.acknowledgementSent || false, + }, + }); + + setIsLoading(false); + } catch (error) { + console.error(error); + router.push("/not-found"); + } + }; + + return ( + + {isLoading ? ( + + ) : ( + + + + Donation Details + + + {isAnonymousRef.current ? "Anonymous Donor" : donorNameRef.current} + + + + { + const label = value !== "In-Kind" ? "Donation Amount" : "Item(s) Value"; + return ( + + ); + }} + /> + + value !== "In-Kind" ? ( + + ) : ( + + ) + } + /> + + + + + + + + + + + Tax Information + + + + + + + + + + )} + + ); +} + +const styles = { + container: { + p: 4, + display: "grid", + gridTemplateColumns: "repeat(3, 1fr)", + gap: 2, + width: "100%", + }, + title: { + gridColumn: "span 3", + fontWeight: "bold", + mb: 1, + }, + textField: { + flex: 1, + }, +}; diff --git a/app/(pages)/Donations/layout.tsx b/app/(pages)/Donations/layout.tsx new file mode 100644 index 0000000..ebc565a --- /dev/null +++ b/app/(pages)/Donations/layout.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import { SecondarySideBar } from "../../components/SecondarySideBar"; + +export default function DonationsLayout({ children }: { children: React.ReactNode }) { + return ( +
+ +
{children}
+
+ ); +} diff --git a/app/(pages)/Donations/page.tsx b/app/(pages)/Donations/page.tsx new file mode 100644 index 0000000..ff1f3e6 --- /dev/null +++ b/app/(pages)/Donations/page.tsx @@ -0,0 +1,109 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import type { Donation } from "@/prisma"; +import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material"; +import Link from "next/link"; + +/* +place holder list +*/ + +const headCells = [ + { + id: "type", + numeric: false, + label: "Donation Type", + }, + { + id: "amount", + numeric: true, + label: "Donation Amount / Item(s) Value", + }, + { + id: "item", + numeric: false, + label: "Item", + }, + { + id: "paymentMethod", + numeric: false, + label: "Method", + }, + { + id: "date", + numeric: false, + label: "Date", + }, +]; +export const TableHeader = () => { + return ( + + + {headCells.map((headCell: any) => ( + + {headCell.label} + + ))} + + + ); +}; + +export default function DonationsList() { + const [data, setData] = useState([]); + + const fetchDonationsData = async () => { + try { + const response = await fetch("/api/donations", { + method: "GET", + }); + const result = await response.json(); + + setData(result.data); + } catch (error) { + console.error("Error fetching:", error); + } + }; + useEffect(() => { + fetchDonationsData(); + }, []); + + return ( + + + + + {data.map((donation) => { + return ( + + + + {donation.type} + + + + ${donation.amount} + + {donation.type !== "In-Kind" ? "" : donation.item} + {donation.type !== "In-Kind" ? donation.paymentMethod : ""} + {new Date(donation.date).toLocaleDateString()} + + ); + })} + +
+
+ ); +} + +const styles = { + table: { + minWidth: 750, + }, + tableCellHeader: { + fontWeight: "bold", + }, + tableCell: { + borderTop: "1px solid #ccc", + }, +}; diff --git a/app/(pages)/Donors/Add/page.tsx b/app/(pages)/Donors/Add/page.tsx new file mode 100644 index 0000000..821bc6d --- /dev/null +++ b/app/(pages)/Donors/Add/page.tsx @@ -0,0 +1,238 @@ +"use client"; +import { Box, TextField, Typography } from "@mui/material"; +import * as React from "react"; +import { FormInputTextfield } from "@/app/components/formComponents/FormInputTextfield"; +import { FormInputDropdown } from "@/app/components/formComponents/FormInputDropdown"; +import { Controller, useForm } from "react-hook-form"; +import { + addressTypes, + donorCommPreferences, + DonorFormProps, + donorStatuses, + donorTypes, + statesChoices, +} from "@/app/components/formComponents/FormInputProps"; +import { AddDonorFooter } from "@/app/components/donations/add/AddDonorFooter"; +import { FormInputCheckbox } from "@/app/components/formComponents/FormInputCheckbox"; + +export default function AddDonor() { + const { + handleSubmit, + control, + setValue, + formState: { isDirty, isValid, errors }, + } = useForm({ + mode: "onChange", + defaultValues: { + donor: { + type: "Individual", + communicationPreference: "", + status: "", + notes: "", + isRetained: false, + }, + person: { firstName: "", lastName: "", emailAddress: "", phoneNumber: "" }, + organization: { name: "", emailAddress: "" }, + address: { addressLine1: "", addressLine2: "", city: "", state: "", zipCode: "", type: "" }, + }, + }); + + return ( + + + + Add Donor + + + + + + Donor Info + + + + + + + + + + + + + ( + + + + {value !== "Individual" ? "Organization" : "Individual"} Details + + + + {value !== "Individual" ? ( + <> + + + + + ) : ( + <> + + + + + + + + )} + + + + + + + + )} + /> + + + + ); +} + +const styles = { + container: { + p: 4, + display: "grid", + gridTemplateColumns: "repeat(3, 1fr)", + gap: 2, + width: "100%", + }, + innerContainer: { + gridColumn: "span 3", + gridTemplateColumns: "repeat(3, 1fr)", + display: "grid", + gap: 2, + }, + title: { + gridColumn: "span 3", + mb: 1, + }, + titleText: { + fontWeight: "bold", + }, + textField: { + flex: 1, + }, +}; diff --git a/app/(pages)/Donors/Detail/[id]/page.tsx b/app/(pages)/Donors/Detail/[id]/page.tsx new file mode 100644 index 0000000..88d9943 --- /dev/null +++ b/app/(pages)/Donors/Detail/[id]/page.tsx @@ -0,0 +1,358 @@ +"use client"; +import { useParams, useRouter } from "next/navigation"; +import { Box, TextField, Typography } from "@mui/material"; +import { useEffect, useRef, useState } from "react"; +import { Controller, useForm } from "react-hook-form"; +import { FormInputTextfield } from "../../../../components/formComponents/FormInputTextfield"; +import Loading from "@/app/loading"; +import { addressTypes, DonorFormProps, statesChoices } from "@/app/components/formComponents/FormInputProps"; +import { DonationTableState, DonorResponse } from "@/app/types/states"; +import { FormInputDropdown } from "@/app/components/formComponents/FormInputDropdown"; +import { donorCommPreferences, donorStatuses, donorTypes } from "@/app/components/formComponents/FormInputProps"; +import { DetailFooter } from "@/app/components/donations/DetailFooter"; +import { MiniDonationsTable } from "@/app/components/donations/MiniDonationTable"; +import { grey } from "@mui/material/colors"; +import { FormInputCheckbox } from "@/app/components/formComponents/FormInputCheckbox"; + +export default function DonorDetail() { + const { id }: { id: string } = useParams(); + const router = useRouter(); + + const [isLoading, setIsLoading] = useState(true); + const personNameRef = useRef(""); + const isOrgRef = useRef(false); + + const [donationInfo, setDonationInfo] = useState([ + { + id: "", + type: "", + amount: 0, + item: "", + paymentMethod: "", + date: new Date(), + }, + ]); + + const { + handleSubmit, + control, + reset, + setValue, + formState: { isDirty, isValid, errors }, + } = useForm({ + mode: "onChange", + defaultValues: { + donor: undefined, + person: undefined, + organization: undefined, + address: undefined, + }, + }); + + useEffect(() => { + fetchDonor(); + }, []); + + const fetchDonor = async () => { + try { + const result = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/donors/${id}`, { + method: "GET", + }); + + const { data } = (await result.json()) as DonorResponse; + + if (!result.ok) { + const errorData = await result.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + + if (data.person) { + personNameRef.current = `${data.person.firstName} ${data.person.lastName}`; + } + isOrgRef.current = data.organization !== null || data.type === "Corporate" || data.type === "Foundation"; + + setDonationInfo( + data.donation.map((donation) => ({ + id: donation.id, + type: donation.type || "One-Time", + amount: donation.amount || 0, + item: donation.item || "placeholder", + paymentMethod: donation.paymentMethod || "placeholder", + date: new Date(donation.date) || new Date(), + })) + ); + + reset({ + donor: { + type: data.type || "Individual", + communicationPreference: data.communicationPreference || "Email", + status: data.status || "Active", + notes: data.notes || "", + isRetained: data.isRetained || false, + }, + organization: isOrgRef.current + ? { + name: data.organization.name || "", + emailAddress: data.organization.emailAddress || "", + } + : {}, + person: isOrgRef.current + ? {} + : { + firstName: data.person.firstName || "", + lastName: data.person.lastName || "", + emailAddress: data.person.emailAddress || "", + phoneNumber: data.person?.phoneNumber || "", + }, + address: isOrgRef.current + ? { + addressLine1: data.organization.address?.addressLine1 || "", + addressLine2: data.organization.address?.addressLine2 || "", + city: data.organization.address?.city || "", + state: data.organization.address?.state || "", + zipCode: data.organization.address?.zipCode || "", + type: data.organization.address?.type || "", + } + : { + addressLine1: data.person.address?.addressLine1 || "", + addressLine2: data.person.address?.addressLine2 || "", + city: data.person.address?.city || "", + state: data.person.address?.state, + zipCode: data.person.address?.zipCode || "", + type: data.person.address?.type || "Residential", + }, + }); + + setIsLoading(false); + } catch (error) { + console.error(error); + router.push("/not-found"); + } + }; + + return ( + + {isLoading ? ( + + ) : ( + + + + Donor Details + + + {personNameRef.current} + + + + + + + + + + + + + + ( + + + + {isOrgRef.current ? "Organization" : "Individual"} Details + + + + {isOrgRef.current ? ( + <> + + + + ) : ( + <> + + + + + + + + + )} + + + + + + + + + )} + /> + + + + Donor Lifetime Value (placeholder) + + + + + Donation History + + + + + + + )} + + ); +} + +const styles = { + container: { + p: 4, + display: "grid", + gridTemplateColumns: "repeat(3, 1fr)", + gap: 2, + width: "100%", + }, + innerContainer: { + gridColumn: "span 3", + gridTemplateColumns: "repeat(3, 1fr)", + display: "grid", + gap: 2, + }, + title: { + gridColumn: "span 3", + mb: 1, + }, + titleText: { + fontWeight: "bold", + }, + textField: { + flex: 1, + }, +}; diff --git a/app/(pages)/Donors/layout.tsx b/app/(pages)/Donors/layout.tsx new file mode 100644 index 0000000..5b5cb43 --- /dev/null +++ b/app/(pages)/Donors/layout.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import { SecondarySideBar } from "../../components/SecondarySideBar"; + +export default function DonorsLayout({ children }: { children: React.ReactNode }) { + return ( +
+ +
{children}
+
+ ); +} diff --git a/app/(pages)/Donors/page.tsx b/app/(pages)/Donors/page.tsx new file mode 100644 index 0000000..d4ebe95 --- /dev/null +++ b/app/(pages)/Donors/page.tsx @@ -0,0 +1,96 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import type { Donation } from "@/prisma"; +import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from "@mui/material"; +import Link from "next/link"; +import { Donor } from "@prisma/client"; + +/* +place holder list +*/ + +const headCells = [ + { + id: "type", + numeric: false, + label: "Donor Type", + }, + { + id: "commPref", + numeric: false, + label: "Communication Preference", + }, + { + id: "status", + numeric: false, + label: "Status", + }, +]; +export const TableHeader = () => { + return ( + + + {headCells.map((headCell: any) => ( + + {headCell.label} + + ))} + + + ); +}; + +export default function DonorsList() { + const [data, setData] = useState([]); + + const fetchDonorData = async () => { + try { + const response = await fetch("/api/donors", { + method: "GET", + }); + const result = await response.json(); + console.log(result.data); + setData(result.data); + } catch (error) { + console.error("Error fetching:", error); + } + }; + useEffect(() => { + fetchDonorData(); + }, []); + + return ( + + + + + {data.map((donor) => { + return ( + + + + {donor.type} + + + {donor.communicationPreference} + {donor.status} + + ); + })} + +
+
+ ); +} + +const styles = { + table: { + minWidth: 750, + }, + tableCellHeader: { + fontWeight: "bold", + }, + tableCell: { + borderTop: "1px solid #ccc", + }, +}; diff --git a/app/(pages)/Grants/Add/page.tsx b/app/(pages)/Grants/Add/page.tsx new file mode 100644 index 0000000..41f13a2 --- /dev/null +++ b/app/(pages)/Grants/Add/page.tsx @@ -0,0 +1,391 @@ +"use client"; + +import { + Box, + InputLabel, + MenuItem, + Select, + Typography, + Checkbox, + FormControlLabel, + TextField, + Button, + Modal, + InputAdornment, +} from "@mui/material"; +import React, { useState } from "react"; + +const GrantAddPage = () => { + const [grantor, setGrantor] = useState(""); + const [grantName, setGrantName] = useState(""); + const [amountRequested, setAmountRequested] = useState(""); + const [grantStatus, setGrantStatus] = useState(""); + const [grantPurpose, setGrantPurpose] = useState(""); + const [startDate, setStartDate] = useState(""); + const [endDate, setEndDate] = useState(""); + const [multiYear, setMultiYear] = useState(false); + const [quarter, setQuarter] = useState(""); + const [proposalDate, setProposalDate] = useState(""); + const [notificationDate, setNotificationDate] = useState(""); + + // Modal states + const [openGrantorModal, setOpenGrantorModal] = useState(false); + const [openPurposeModal, setOpenPurposeModal] = useState(false); + const [newGrantorName, setNewGrantorName] = useState(""); + const [newGrantorTitle, setNewGrantorTitle] = useState(""); + const [newGrantorAddress, setNewGrantorAddress] = useState(""); + const [newGrantorEmail, setNewGrantorEmail] = useState(""); + const [newGrantorPhone, setNewGrantorPhone] = useState(""); + const [newGrantorLink, setNewGrantorLink] = useState(""); + const [newGrantPurpose, setNewGrantPurpose] = useState(""); + + const handleSubmit = () => { + console.log({ + grantor, + grantName, + amountRequested, + grantStatus, + grantPurpose, + startDate, + endDate, + multiYear, + quarter, + proposalDate, + notificationDate, + }); + }; + + const handleOpenGrantorModal = () => { + setOpenGrantorModal(true); + }; + + const handleCloseGrantorModal = () => { + setOpenGrantorModal(false); + }; + + const handleAddGrantor = () => { + console.log("New Grantor:", newGrantorName); + setGrantor(newGrantorName); + setNewGrantorName(""); + setNewGrantorTitle(""); + setNewGrantorEmail(""); + setNewGrantorPhone(""); + setNewGrantorAddress(""); + setNewGrantorLink(""); + handleCloseGrantorModal(); + }; + + const handleOpenPurposeModal = () => { + setOpenPurposeModal(true); + }; + + const handleClosePurposeModal = () => { + setOpenPurposeModal(false); + }; + + const handleAddGrantPurpose = () => { + console.log("New Grant Purpose:", newGrantPurpose); + setGrantPurpose(newGrantPurpose); + setNewGrantPurpose(""); + handleClosePurposeModal(); + }; + + return ( + + + Add a New Grant + + + + Select Grantor + + + + setGrantName(e.target.value)} + fullWidth + sx={{ mb: 2 }} + /> + + setAmountRequested(e.target.value)} + fullWidth + InputProps={{ + startAdornment: $, // Add dollar sign + }} + sx={{ mb: 2 }} + /> + + Grant Status + + + Grant Purpose + + + + setStartDate(e.target.value)} + InputLabelProps={{ shrink: true }} + sx={{ width: "48%" }} + /> + setEndDate(e.target.value)} + InputLabelProps={{ shrink: true }} + sx={{ width: "48%" }} + /> + + + setMultiYear(e.target.checked)} + /> + } + label="Multi-Year" + /> + + Quarter + + + setProposalDate(e.target.value)} + InputLabelProps={{ shrink: true }} + fullWidth + sx={{ mb: 2 }} + /> + + setNotificationDate(e.target.value)} + InputLabelProps={{ shrink: true }} + fullWidth + sx={{ mb: 2 }} + /> + + + + {/* Modal for adding new grantor */} + + + + Add New Grantor + + setNewGrantorName(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="text" + /> + setNewGrantorTitle(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="text" + /> + setNewGrantorEmail(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="email" + /> + setNewGrantorPhone(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="tel" + /> + setNewGrantorAddress(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="text" + /> + setNewGrantorLink(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="url" + /> + + + + + {/* Modal for adding new grant purpose */} + + + + Add New Grant Purpose + + setNewGrantPurpose(e.target.value)} + fullWidth + sx={{ mb: 2 }} + /> + + + + + ); +}; + +export default GrantAddPage; diff --git a/app/(pages)/Grants/Detail/[id]/page.tsx b/app/(pages)/Grants/Detail/[id]/page.tsx new file mode 100644 index 0000000..cdfa759 --- /dev/null +++ b/app/(pages)/Grants/Detail/[id]/page.tsx @@ -0,0 +1,798 @@ +"use client"; +import React from "react"; +import { useEffect, useState } from "react"; +import type { Grant } from "@/prisma"; +import { useParams } from "next/navigation"; +import { + Box, + TextField, + Button, + Typography, + Breadcrumbs, + CircularProgress, + MenuItem, + InputAdornment, +} from "@mui/material" +import Grid from '@mui/material/Grid2'; +import Link from "next/link" + + +const GrantDetailPage = () => { + const { id } = useParams(); + const [grantDetails, setGrantDetails] = useState([]); + const [isEditing, setIsEditing] = useState(false); + const [loading, setLoading] = useState(true); + const [showSave, setShowSave] = useState(false); + const [showEdit, setShowEdit] = useState(true); + const [showCancelEdit, setShowCancelEdit] = useState(false); + + useEffect(() => { + const fetchGrantDetails = async () => { + try { + const response = await fetch(`/api/grants/${id}/get`); + const result = await response.json(); + setGrantDetails(result.data); + setLoading(false); + } catch (error) { + console.error("Error fetching grant details:", error); + setLoading(false); + } + }; + + if (id) { + fetchGrantDetails(); + } + }, [id]); + + const handleEditClick = () => { + setIsEditing((prevState) => !prevState); + setShowEdit(false); + setShowSave(true); + setShowCancelEdit(true); + }; + + const handleSaveClick = async () => { + setShowEdit(true); + setShowSave(false); + setShowCancelEdit(false); + try { + //const response = await axios.put(`/api/grant/updateGrant?id=${id}`, { + // updatedData: grantDetails, + //}); + //console.log("Updated grant details:", response.data); + const response = await fetch(`/api/grants/${id}/patch`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(grantDetails) }); + const result = await response.json(); + setGrantDetails(result.data); + console.log(result.data) + setIsEditing(false); + } catch (error) { + console.error("Error updating grant details:", error); + // Handle error + } + }; + + const handleCancelEditClick = () => { + setShowEdit(true); + setShowSave(false); + setShowCancelEdit(false); + setIsEditing(false); + } + + //Old handleInputChange, not really sure how this works + + /*const handleInputChange = (e: any) => { + const { name, value } = e.target; + setGrantDetails((prevGrantDetails: any) => { + if (Array.isArray(prevGrantDetails[name])) { + // If the field is an array, split the value by comma + const values = value.split(","); + // Check if each item can be parsed as a Date object + const updatedValues = values.map((item: any) => { + const date = new Date(item.trim()); + return isNaN(date.getTime()) ? item.trim() : date.toISOString(); // If it's not a valid date, keep it as string + }); + return { + ...prevGrantDetails, + [name]: updatedValues, + }; + } else if (value instanceof Date) { + // If the value is a Date object, convert it to an ISO 8601 string + return { + ...prevGrantDetails, + [name]: value.toISOString(), + }; + } else { + // For other cases, directly update the value + return { + ...prevGrantDetails, + [name]: value, + }; + } + }); + };*/ + + //Only works for status at the moment, was supposed to be dynamic and work for all textfields + const handleInputChange = (event: React.ChangeEvent) => { + const { value } = event.target; + + setGrantDetails((prevState) => ({ + ...prevState, + status: value, + })); + }; + + if (loading) { + return + } + + if (!grantDetails) { + return
Grant not found
; + } + + return ( + + + + Dashboard + Grants + Grant List + Grant Details + + + + + {showSave && + } + {showEdit && + } + {showCancelEdit && + } + + + + + + + ); +}; + +const DetailsTable = ({ grantDetails, isEditing, handleInputChange }: any) => { + + const status = [ + { + value: 'LOI Submitted', + label: 'LOI Submitted', + }, + { + value: 'Proposal Submitted', + label: 'Proposal Submitted', + }, + { + value: 'Awarded', + label: 'Awarded', + }, + { + value: 'Declined', + label: 'Declined', + }, + { + value: 'Pending', + label: 'Pending', + } + ]; + + const renewalStatus = [ + { + value: 'Submitted', + label: 'Submitted', + }, + { + value: 'Awarded', + label: 'Awarded', + }, + { + value: 'Declined', + label: 'Declined', + }, + { + value: 'Pending', + label: 'Pending', + } + ]; + + const quarter = [ + { + value: '1', + label: '1', + }, + { + value: '2', + label: '2', + }, + { + value: '3', + label: '3', + }, + { + value: '4', + label: '4', + }, + ]; + + const trueFalse = [ + { + value: 'true', + label: 'true', + }, + { + value: 'false', + label: 'false', + }, + ]; + + //Need to make the next few dynamic so kids-u can add more purposes, useArea, fundingArea + const purpose = [ + { + value: 'After-School Tutoring Program', + label: 'After-School Tutoring Program', + }, + { + value: 'Summer Program', + label: 'Summer Program', + }, + { + value: 'Family & Community Engagement', + label: 'Family & Community Engagement', + }, + { + value: 'Nutrition and Meal Programs', + label: 'Nutrition and Meal Programs', + }, + { + value: 'Community Safety Initiatives', + label: 'Community Safety Initiatives', + }, + { + value: 'General', + label: 'General', + }, + ] + + const fundingArea = [ + { + value: 'After-school Tutoring', + label: 'After-School Tutoring', + }, + { + value: 'Summer Programs', + label: 'Summer Programs', + }, + { + value: 'Family & Community Engagement', + label: 'Family & Community Engagement', + }, + { + value: 'General', + label: 'General', + }, + ] + + const useArea = [ + { + value: 'Educational Programming', + label: 'Educational Programming', + }, + { + value: 'Social-Emotional Learning', + label: 'Social-Emotional Learning', + }, + { + value: 'Community Safety', + label: 'Community Safety', + }, + { + value: 'Nutrition Programs', + label: 'Nutrition Programs', + }, + { + value: 'General', + label: 'General', + }, + ] + + + return ( + + + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + {status.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + $, + }, + }} + /> + + + {/*----------------------------------------------------------------*/} + + + $, + }, + }} + /> + + + {/*----------------------------------------------------------------*/} + + + + + {purpose.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + {fundingArea.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + {useArea.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + {quarter.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + {trueFalse.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + {trueFalse.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + + {/*----------------------------------------------------------------*/} + + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + {trueFalse.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + {renewalStatus.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + ); +}; + +const styles = { + center: { + display: "flex", + justifyContent: "center", + alignItems: "center", + height: "100vh", + marginLeft: "auto", + marginRight: "auto", + }, + breadcrumb: { + marginLeft: "5px", + marginTop: "8px" + } +}; + +export default GrantDetailPage; \ No newline at end of file diff --git a/app/(pages)/Grants/Grantor/Add/page.tsx b/app/(pages)/Grants/Grantor/Add/page.tsx new file mode 100644 index 0000000..e506cad --- /dev/null +++ b/app/(pages)/Grants/Grantor/Add/page.tsx @@ -0,0 +1,391 @@ +"use client"; + +import { + Box, + InputLabel, + MenuItem, + Select, + Typography, + Checkbox, + FormControlLabel, + TextField, + Button, + Modal, + InputAdornment, +} from "@mui/material"; +import React, { useState } from "react"; + +const GrantAddPage = () => { + const [grantor, setGrantor] = useState(""); + const [grantName, setGrantName] = useState(""); + const [amountRequested, setAmountRequested] = useState(""); + const [grantStatus, setGrantStatus] = useState(""); + const [grantPurpose, setGrantPurpose] = useState(""); + const [startDate, setStartDate] = useState(""); + const [endDate, setEndDate] = useState(""); + const [multiYear, setMultiYear] = useState(false); + const [quarter, setQuarter] = useState(""); + const [proposalDate, setProposalDate] = useState(""); + const [notificationDate, setNotificationDate] = useState(""); + + // Modal states + const [openGrantorModal, setOpenGrantorModal] = useState(false); + const [openPurposeModal, setOpenPurposeModal] = useState(false); + const [newGrantorName, setNewGrantorName] = useState(""); + const [newGrantorTitle, setNewGrantorTitle] = useState(""); + const [newGrantorAddress, setNewGrantorAddress] = useState(""); + const [newGrantorEmail, setNewGrantorEmail] = useState(""); + const [newGrantorPhone, setNewGrantorPhone] = useState(""); + const [newGrantorLink, setNewGrantorLink] = useState(""); + const [newGrantPurpose, setNewGrantPurpose] = useState(""); + + const handleSubmit = () => { + console.log({ + grantor, + grantName, + amountRequested, + grantStatus, + grantPurpose, + startDate, + endDate, + multiYear, + quarter, + proposalDate, + notificationDate, + }); + }; + + const handleOpenGrantorModal = () => { + setOpenGrantorModal(true); + }; + + const handleCloseGrantorModal = () => { + setOpenGrantorModal(false); + }; + + const handleAddGrantor = () => { + console.log("New Grantor:", newGrantorName); + setGrantor(newGrantorName); + setNewGrantorName(""); + setNewGrantorTitle(""); + setNewGrantorEmail(""); + setNewGrantorPhone(""); + setNewGrantorAddress(""); + setNewGrantorLink(""); + handleCloseGrantorModal(); + }; + + const handleOpenPurposeModal = () => { + setOpenPurposeModal(true); + }; + + const handleClosePurposeModal = () => { + setOpenPurposeModal(false); + }; + + const handleAddGrantPurpose = () => { + console.log("New Grant Purpose:", newGrantPurpose); + setGrantPurpose(newGrantPurpose); + setNewGrantPurpose(""); + handleClosePurposeModal(); + }; + + return ( + + + Add a New Grant + + + + Select Grantor + + + + setGrantName(e.target.value)} + fullWidth + sx={{ mb: 2 }} + /> + + setAmountRequested(e.target.value)} + fullWidth + InputProps={{ + startAdornment: $, // Add dollar sign + }} + sx={{ mb: 2 }} + /> + + Grant Status + + + Grant Purpose + + + + setStartDate(e.target.value)} + InputLabelProps={{ shrink: true }} + sx={{ width: "48%" }} + /> + setEndDate(e.target.value)} + InputLabelProps={{ shrink: true }} + sx={{ width: "48%" }} + /> + + + setMultiYear(e.target.checked)} + /> + } + label="Multi-Year" + /> + + Quarter + + + setProposalDate(e.target.value)} + InputLabelProps={{ shrink: true }} + fullWidth + sx={{ mb: 2 }} + /> + + setNotificationDate(e.target.value)} + InputLabelProps={{ shrink: true }} + fullWidth + sx={{ mb: 2 }} + /> + + + + {/* Modal for adding new grantor */} + + + + Add New Grantor + + setNewGrantorName(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="text" + /> + setNewGrantorTitle(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="text" + /> + setNewGrantorEmail(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="email" + /> + setNewGrantorPhone(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="tel" + /> + setNewGrantorAddress(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="text" + /> + setNewGrantorLink(e.target.value)} + fullWidth + sx={{ mb: 2 }} + type="url" + /> + + + + + {/* Modal for adding new grant purpose */} + + + + Add New Grant Purpose + + setNewGrantPurpose(e.target.value)} + fullWidth + sx={{ mb: 2 }} + /> + + + + + ); +}; + +export default GrantAddPage; diff --git a/app/(pages)/Grants/Grantor/Detail/[id]/page.tsx b/app/(pages)/Grants/Grantor/Detail/[id]/page.tsx new file mode 100644 index 0000000..5765c10 --- /dev/null +++ b/app/(pages)/Grants/Grantor/Detail/[id]/page.tsx @@ -0,0 +1,444 @@ +"use client"; +import React from "react"; +import { useEffect, useState } from "react"; +import type { Grantor } from "@/prisma"; +import { useParams } from "next/navigation"; +import { + Box, + TextField, + Button, + Typography, + Breadcrumbs, + CircularProgress, + MenuItem, + InputAdornment, +} from "@mui/material" +import Grid from '@mui/material/Grid2'; +import Link from "next/link" + +const GrantorDetailPage = () => { + const { id } = useParams(); + const [grantorDetails, setGrantorDetails] = useState([]); + const [isEditing, setIsEditing] = useState(false); + const [loading, setLoading] = useState(true); + const [showSave, setShowSave] = useState(false); + const [showEdit, setShowEdit] = useState(true); + const [showCancelEdit, setShowCancelEdit] = useState(false); + + useEffect(() => { + const fetchGrantorDetails = async () => { + try { + const response = await fetch(`/api/grantors/${id}/get`); + const result = await response.json(); + setGrantorDetails(result.data); + console.log(result.data); + setLoading(false); + } catch (error) { + console.error("Error fetching grant details:", error); + setLoading(false); + } + }; + + if (id) { + fetchGrantorDetails(); + } + }, [id]); + + const handleEditClick = () => { + setIsEditing((prevState) => !prevState); + setShowEdit(false); + setShowSave(true); + setShowCancelEdit(true); + }; + + const handleSaveClick = async () => { + setShowEdit(true); + setShowSave(false); + setShowCancelEdit(false); + try { + //const response = await fetch(`/api/grantors/${id}/patch`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(grantDetails) }); + // const result = await response.json(); + //setGrantDetails(result.data); + //console.log(result.data) + setIsEditing(false); + } catch (error) { + console.error("Error updating grant details:", error); + // Handle error + } + }; + + const handleCancelEditClick = () => { + setShowEdit(true); + setShowSave(false); + setShowCancelEdit(false); + setIsEditing(false); + } + + //Old handleInputChange, not really sure how this works + + /*const handleInputChange = (e: any) => { + const { name, value } = e.target; + setGrantDetails((prevGrantDetails: any) => { + if (Array.isArray(prevGrantDetails[name])) { + // If the field is an array, split the value by comma + const values = value.split(","); + // Check if each item can be parsed as a Date object + const updatedValues = values.map((item: any) => { + const date = new Date(item.trim()); + return isNaN(date.getTime()) ? item.trim() : date.toISOString(); // If it's not a valid date, keep it as string + }); + return { + ...prevGrantDetails, + [name]: updatedValues, + }; + } else if (value instanceof Date) { + // If the value is a Date object, convert it to an ISO 8601 string + return { + ...prevGrantDetails, + [name]: value.toISOString(), + }; + } else { + // For other cases, directly update the value + return { + ...prevGrantDetails, + [name]: value, + }; + } + }); + };*/ + + //Only works for nothing at the moment, was supposed to be dynamic and work for all textfields + const handleInputChange = (event: React.ChangeEvent) => { + const { value } = event.target; + + setGrantorDetails((prevState) => ({ + ...prevState, + //status: value, + })); + }; + + if (loading) { + return + } + + if (!grantorDetails) { + return
Grantor not found
; + } + + return ( + + + + Dashboard + Grants + Grantor List + Grantor Details + + + + + {showSave && + } + {showEdit && + } + {showCancelEdit && + } + + + + + + + ); +}; + +const DetailsTable = ({ grantorDetails, isEditing, handleInputChange }: any) => { + + const addressType = [ + { + value: 'Business', + label: 'Business', + }, + { + value: 'Personal', + label: 'Personal', + }, + { + value: 'P.O. Box', + label: 'P.O. Box', + }, + ]; + + const grantorType = [ + { + value: 'Private Foundation', + label: 'Private Foundation', + }, + { + value: 'Corporate Partner', + label: 'Corporate Partner', + }, + { + value: 'Federal Government', + label: 'Federal Governmen', + }, + { + value: 'State Government', + label: 'State Government', + }, + { + value: 'Local Government', + label: 'Local Government', + }, + { + value: 'Individual Major Donor', + label: 'Individual Major Donor', + }, + ]; + + const communicationPreference = [ + { + value: 'Email', + label: 'Email', + }, + { + value: 'Phone', + label: 'Phone', + }, + { + value: 'In-person', + label: 'In-person', + }, + { + value: 'Event Participation', + label: 'Event Participation', + }, + ]; + + const recognitionPreference = [ + { + value: 'Public Recognition', + label: 'Public Recognition', + }, + { + value: 'Anonymous', + label: 'Anonymous', + }, + ]; + + return ( + + + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + {addressType.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + {grantorType.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + {communicationPreference.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + {recognitionPreference.map((option) => ( + + {option.label} + + ))} + + + + {/*----------------------------------------------------------------*/} + + + + + + {/*----------------------------------------------------------------*/} + + + + ); +}; + +const styles = { + center: { + display: "flex", + justifyContent: "center", + alignItems: "center", + height: "100vh", + marginLeft: "auto", + marginRight: "auto", + }, + breadcrumb: { + marginLeft: "5px", + marginTop: "8px" + } +}; + +export default GrantorDetailPage; \ No newline at end of file diff --git a/app/(pages)/Grants/Grantor/page.tsx b/app/(pages)/Grants/Grantor/page.tsx new file mode 100644 index 0000000..490e3ab --- /dev/null +++ b/app/(pages)/Grants/Grantor/page.tsx @@ -0,0 +1,273 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import { Grantor } from "@/prisma" +import { + Box, + TextField, + Typography, + Breadcrumbs, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TablePagination, + Paper, + CircularProgress, + TableFooter, + FormControl, + InputLabel, + Select, + MenuItem, + OutlinedInput, + Checkbox, + ListItemText, + SelectChangeEvent, +} from "@mui/material" +import Grid from "@mui/material/Grid2"; +import Link from "next/link" + +const columns = [ + "name", + "type", + "addressLine1", + "addressLine2", + "city", + "state", + "zipcode", + "communicationPreference", + "recognitionPreference", +]; + +const searchOptions = [ + "name", + "type", + "addressLine1", + "city", + "state", + "zipcode", +]; + +export default function GrantorsPage() { + const [grantorsData, setGrantorsData] = useState([]); + const [loading, setLoading] = useState(true); + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(5); + const [totalCount, setTotalCount] = React.useState(0); + const [selectedColumns, setSelectedColumns] = useState([]); + const [searchValue, setSearchValue] = useState(""); + const [searchCriteria, setSearchCriteria] = useState(""); + + const fetchGrantsData = async () => { + try { + const response = await fetch(`/api/grantors?page=${page}&rowsPerPage=${rowsPerPage}&searchCriteria=${searchCriteria}&searchValue=${searchValue}`); + const result = await response.json(); + setGrantorsData(result.data); + setTotalCount(result.count); + setLoading(false); + } catch (error) { + console.error("Error fetching grantors:", error); + setLoading(false); + } + }; + + const handleChangePage = (event: React.MouseEvent | null, newPage: number) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); //Bring back to first page + }; + + const handleColumnChange = (event: SelectChangeEvent) => { + const { + target: { value }, + } = event; + setSelectedColumns( + typeof value === 'string' ? value.split(',') : value, + ); + }; + + const handleSearchChange = (event: React.ChangeEvent) => { + setSearchValue(event.target.value as string); + }; + + const handleCriteriaChange = (event: SelectChangeEvent) => { + setSearchCriteria(event.target.value as string); + }; + + useEffect(() => { + if (typeof window !== 'undefined') { //This ensures the code runs only in the browser + if (sessionStorage.getItem("page") !== "grantorList") { + sessionStorage.clear(); + } + sessionStorage.setItem("page", "grantorList"); + + const savedColumns = sessionStorage.getItem('selectedColumns'); + if (savedColumns) { + setSelectedColumns(JSON.parse(savedColumns)); + } else { + setSelectedColumns(columns); + } + } + }, []); + + useEffect(() => { + if (typeof window !== 'undefined' && selectedColumns.length > 0) { + sessionStorage.setItem('selectedColumns', JSON.stringify(selectedColumns)); + } + }, [selectedColumns]); + + useEffect(() => { + fetchGrantsData(); + }, [page, rowsPerPage, searchValue, searchCriteria]); + + if (loading) { + return + } + + return ( + + + + Dashboard + Grants + Grantor List + + + + + + + Search By + + + + + + + + + Included Columns + + + + + + + + + + + {selectedColumns.includes("name") && Name} + {selectedColumns.includes("type") && Type} + {selectedColumns.includes("addressLine1") && Address Line 1} + {selectedColumns.includes("addressLine2") && Address Line 2} + {selectedColumns.includes("city") && City} + {selectedColumns.includes("state") && State} + {selectedColumns.includes("zipcode") && Zipcode} + {selectedColumns.includes("communicationPreference") && Communication Preference} + {selectedColumns.includes("recognitionPreference") && Recognition Preference} + + + + {grantorsData?.map((grantor) => ( + + {selectedColumns.includes("name") && {grantor.organization.name}} + {selectedColumns.includes("type") && {grantor.type}} + {selectedColumns.includes("addressLine1") && {grantor.organization.address.addressLine1}} + {selectedColumns.includes("addressLine2") && {grantor.organization.address.addressLine2}} + {selectedColumns.includes("city") && {grantor.organization.address.city}} + {selectedColumns.includes("state") && {grantor.organization.address.state}} + {selectedColumns.includes("zipcode") && {grantor.organization.address.zipCode}} + {selectedColumns.includes("communicationPreference") && {grantor.communicationPreference}} + {selectedColumns.includes("recognitionPreference") && {grantor.recognitionPreference}} + + )) ?? null} + + + + + + + + +
+
+
+
+ ); +} + +const styles = { + table: { + minWidth: 650, + }, + tableCellHeader: { + fontWeight: "bold", + border: "1px solid #aaa", + backgroundColor: "#ccc", + }, + tableCell: { + border: "1px solid #ccc", + }, + center: { + display: "flex", + justifyContent: "center", + alignItems: "center", + height: "100vh", + marginLeft: "auto", + marginRight: "auto", + }, + pagination: { + display: "flex", + justifyContent: "left", + width: "100%", + backgroundColor: "#ccc", + }, + breadcrumb: { + marginLeft: "5px", + marginTop: "8px" + } +}; \ No newline at end of file diff --git a/app/Grants/layout.tsx b/app/(pages)/Grants/layout.tsx similarity index 58% rename from app/Grants/layout.tsx rename to app/(pages)/Grants/layout.tsx index 6a15637..31e1a44 100644 --- a/app/Grants/layout.tsx +++ b/app/(pages)/Grants/layout.tsx @@ -1,17 +1,14 @@ import React from "react"; -import { SecondarySideBar } from "../components/SecondarySideBar"; +import { SecondarySideBar } from "../../components/SecondarySideBar"; -export default function GrantsLayout({ - children, -}: { - children: React.ReactNode; -}) { +export default function GrantsLayout({ children }: { children: React.ReactNode }) { return (
{children}
diff --git a/app/(pages)/Grants/page.tsx b/app/(pages)/Grants/page.tsx new file mode 100644 index 0000000..afc0d17 --- /dev/null +++ b/app/(pages)/Grants/page.tsx @@ -0,0 +1,281 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import type { Grant } from "@/prisma"; +import { + Box, + TextField, + Typography, + Breadcrumbs, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TablePagination, + Paper, + CircularProgress, + TableFooter, + FormControl, + InputLabel, + Select, + MenuItem, + OutlinedInput, + Checkbox, + ListItemText, + SelectChangeEvent, +} from "@mui/material" +import Grid from "@mui/material/Grid2"; +import Link from "next/link" + +const columns = [ + "grantor", + "representative", + "name", + "status", + "purpose", + "startDate", + "endDate", + "awardNotificationDate", + "amountAwarded", + "amountRequested", + "proposalDueDate", + "proposalSubmissionDate", +]; + +const searchOptions = [ + "name", + "status", + "grantor" +]; + +export default function GrantsPage() { + const [grantsData, setGrantsData] = useState([]); + const [loading, setLoading] = useState(true); + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(5); + const [totalCount, setTotalCount] = React.useState(0); + const [selectedColumns, setSelectedColumns] = useState([]); + const [searchValue, setSearchValue] = useState(""); + const [searchCriteria, setSearchCriteria] = useState(""); + + const fetchGrantsData = async () => { + try { + const response = await fetch(`/api/grants/get?page=${page}&rowsPerPage=${rowsPerPage}&searchCriteria=${searchCriteria}&searchValue=${searchValue}`); + const result = await response.json(); + setGrantsData(result.data); + setTotalCount(result.count); + console.log(result.data); + setLoading(false); + } catch (error) { + console.error("Error fetching grants:", error); + setLoading(false); + } + }; + + const handleChangePage = (event: React.MouseEvent | null, newPage: number) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); //Bring back to first page + }; + + const handleColumnChange = (event: SelectChangeEvent) => { + const { + target: { value }, + } = event; + setSelectedColumns( + typeof value === "string" ? value.split(",") : value, + ); + }; + + const handleSearchChange = (event: React.ChangeEvent) => { + setSearchValue(event.target.value as string); + }; + + const handleCriteriaChange = (event: SelectChangeEvent) => { + setSearchCriteria(event.target.value as string); + }; + + useEffect(() => { + if (typeof window !== "undefined") { //This ensures the code runs only in the browser + //sessionStorage for selected columns + if (sessionStorage.getItem("page") !== "grantList") { + sessionStorage.clear(); + } + sessionStorage.setItem("page", "grantList"); + + const savedColumns = sessionStorage.getItem("selectedColumns"); + if (savedColumns) { + setSelectedColumns(JSON.parse(savedColumns)); + } else { + setSelectedColumns(columns); + } + } + }, []); + + useEffect(() => { + if (typeof window !== "undefined" && selectedColumns.length > 0) { + sessionStorage.setItem("selectedColumns", JSON.stringify(selectedColumns)); + } + }, [selectedColumns]); + + useEffect(() => { + fetchGrantsData(); + }, [page, rowsPerPage, searchValue, searchCriteria]); + + if (loading) { + return + } + + return ( + + + + Dashboard + Grants + Grant List + + + + + + + Search By + + + + + + + + + Included Columns + + + + + + + + + + + {selectedColumns.includes("grantor") && Grantor} + {selectedColumns.includes("representative") && Representative} + {selectedColumns.includes("name") && Name} + {selectedColumns.includes("status") && Status} + {selectedColumns.includes("purpose") && Purpose} + {selectedColumns.includes("startDate") && Start Date} + {selectedColumns.includes("endDate") && End Date} + {selectedColumns.includes("awardNotificationDate") && Award Notification Date} + {selectedColumns.includes("amountAwarded") && Amount Awarded} + {selectedColumns.includes("amountRequested") && Amount Requested} + {selectedColumns.includes("proposalDueDate") && Proposal Due Date} + {selectedColumns.includes("proposalSubmissionDate") && Proposal Submission Date} + + + + {grantsData?.map((grant) => ( + + {selectedColumns.includes("grantor") && {grant.representativeGrant[0].representative.grantor.organization.name}} + {selectedColumns.includes("representative") && {grant.representativeGrant[0].representative.person.firstName} {grant.representativeGrant[0].representative.person.lastName}} + {selectedColumns.includes("name") && {grant.name}} + {selectedColumns.includes("status") && {grant.status}} + {selectedColumns.includes("purpose") && {grant.purpose}} + {selectedColumns.includes("startDate") && {new Date(grant.startDate).toLocaleDateString()}} + {selectedColumns.includes("endDate") && {new Date(grant.endDate).toLocaleDateString()}} + {selectedColumns.includes("awardNotificationDate") && {grant.awardNotificationDate ? new Date(grant.awardNotificationDate).toLocaleDateString() : "N/A"}} + {selectedColumns.includes("amountAwarded") && {"$" + grant.amountAwarded}} + {selectedColumns.includes("amountRequested") && {"$" + grant.amountRequested}} + {selectedColumns.includes("proposalDueDate") && {new Date(grant.proposalDueDate).toLocaleDateString()}} + {selectedColumns.includes("proposalSubmissionDate") && {grant.proposalSubmissionDate ? new Date(grant.proposalSubmissionDate).toLocaleDateString() : "N/A"}} + + )) ?? null} + + + + + + + + +
+
+
+
+ ); +} + +const styles = { + table: { + minWidth: 650, + }, + tableCellHeader: { + fontWeight: "bold", + border: "1px solid #aaa", + backgroundColor: "#ccc", + }, + tableCell: { + border: "1px solid #ccc", + }, + center: { + display: "flex", + justifyContent: "center", + alignItems: "center", + height: "100vh", + marginLeft: "auto", + marginRight: "auto", + }, + pagination: { + display: "flex", + justifyContent: "left", + width: "100%", + backgroundColor: "#ccc", + }, + breadcrumb: { + marginLeft: "5px", + marginTop: "8px" + } +}; diff --git a/app/(pages)/TemporaryPageImport/page.tsx b/app/(pages)/TemporaryPageImport/page.tsx new file mode 100644 index 0000000..51a7995 --- /dev/null +++ b/app/(pages)/TemporaryPageImport/page.tsx @@ -0,0 +1,5 @@ +import { Import } from "../../components/importCSV"; + +export default function ImportPage() { + ; +} diff --git a/app/Constituents/page.tsx b/app/Constituents/page.tsx deleted file mode 100644 index 37a5806..0000000 --- a/app/Constituents/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Constituents() { - return ( -
-

Constituents Page

-
- ); -} diff --git a/app/Donations/page.tsx b/app/Donations/page.tsx deleted file mode 100644 index e660ecf..0000000 --- a/app/Donations/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Donations() { - return ( -
-

Donations Page

-
- ); -} diff --git a/app/Grants/Add/page.tsx b/app/Grants/Add/page.tsx deleted file mode 100644 index eee721d..0000000 --- a/app/Grants/Add/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function AddGrant() { - return ( -
-

Add Grant Page

-
- ); -} diff --git a/app/Grants/Detail/[id]/page.tsx b/app/Grants/Detail/[id]/page.tsx deleted file mode 100644 index e5cf932..0000000 --- a/app/Grants/Detail/[id]/page.tsx +++ /dev/null @@ -1,438 +0,0 @@ -"use client"; -import React from "react"; -import { useEffect, useState } from "react"; -import axios from "axios"; -import { useParams } from "next/navigation"; -import { Box , TextField, MenuItem, Select, Divider, InputAdornment } from "@mui/material"; -import Grid from '@mui/material/Grid2'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; - -const GrantDetailPage = () => { - const { id } = useParams(); - const [grantDetails, setGrantDetails] = useState(null); - const [isEditing, setIsEditing] = useState(false); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchGrantDetails = async () => { - try { - const response = await axios.get(`/api/grants/${id}`); - setGrantDetails(response.data); - setLoading(false); - } catch (error) { - console.error("Error fetching grant details:", error); - setLoading(false); - } - }; - - if (id) { - fetchGrantDetails(); - } - }, [id]); - - const handleEditClick = () => { - setIsEditing((prevState) => !prevState); - }; - - const handleSaveClick = async () => { - console.log("Save button clicked"); // Add this line - try { - const response = await axios.put(`/api/grant/updateGrant?id=${id}`, { - updatedData: grantDetails, - }); - console.log("Updated grant details:", response.data); - setIsEditing(false); - } catch (error) { - console.error("Error updating grant details:", error); - // Handle error - } - }; - - const handleInputChange = (e: any) => { - const { name, value } = e.target; - setGrantDetails((prevGrantDetails: any) => { - if (Array.isArray(prevGrantDetails[name])) { - // If the field is an array, split the value by comma - const values = value.split(","); - // Check if each item can be parsed as a Date object - const updatedValues = values.map((item: any) => { - const date = new Date(item.trim()); - return isNaN(date.getTime()) ? item.trim() : date.toISOString(); // If it's not a valid date, keep it as string - }); - return { - ...prevGrantDetails, - [name]: updatedValues, - }; - } else if (value instanceof Date) { - // If the value is a Date object, convert it to an ISO 8601 string - return { - ...prevGrantDetails, - [name]: value.toISOString(), - }; - } else { - // For other cases, directly update the value - return { - ...prevGrantDetails, - [name]: value, - }; - } - }); - }; - - if (loading) { - return
Loading...
; - } - - if (!grantDetails) { - return
Grant not found
; - } - - return ( -
-
- -
- {/**/} - -
-
- ); -}; - -const Breadcrumb = () =>
Home / Grants / Grant Details
; - -const Header = ({ handleEditClick, isEditing, handleSaveClick }: any) => ( -
-

Grant Details

-
- {isEditing ? - ( - <> - - - - ) : ( - - )} -
-
-); - -{/* - - handleInputChange({ - target: { name: "grantPeriodStart", value: newValue }, - }) - } - // Directly using TextField as input component - slotProps={{ - textField: { - id: "grant-Period-Start-Text-Field", - label: "Grant Period Start", - variant: "outlined", - sx: { width: '100%', height: '40px', '& .MuiInputBase-root': { height: '40px' } } - } - }} - /> - */} - - - - - - -const DetailsTable = ({ grantDetails, isEditing, handleInputChange }: any) => { - - const status = [ - { - value: 'loiSubmittedStatus', - label: 'LOI Submitted', - }, - { - value: 'porposalSubmittedStatus', - label: 'Proposal Submitted', - }, - { - value: 'awardedStatus', - label: 'Awarded', - }, - { - value: 'declinedStatus', - label: 'Declined', - }, - { - value: 'pedningStatus', - label: 'Pending', - } - ]; - - const quarter = [ - { - value: 'Q1Status', - label: '1', - }, - { - value: 'Q2Status', - label: '2', - }, - { - value: 'Q3Status', - label: '3', - }, - { - value: 'Q4Status', - label: '4', - }, - ]; - - const multiyear = [ - { - value: 'yesMultiYear', - label: 'Yes', - }, - { - value: 'noMultiYear', - label: 'No', - }, - ]; - - const purpose = [ - { - value: 'afterSchoolPurpose', - label: 'After-School Tutoring Program', - }, - { - value: 'summerPurpose', - label: 'Summer Program', - }, - { - value: 'FACEpurpose', - label: 'Family & Community Engagement (FACE)', - }, - { - value: 'nutritionPurpose', - label: 'Nutrition and Meal Programs', - }, - { - value: 'communitySafetyPurpose', - label: 'Community Safety Initiatives ', - }, - ] - - - return ( - - - - - - - - - {/*----------------------------------------------------------------*/} - - - - - - {/*----------------------------------------------------------------*/} - - - $, - }, - }} - /> - - - {/*----------------------------------------------------------------*/} - - - - {status.map((option) => ( - - {option.label} - - ))} - - - - {/*----------------------------------------------------------------*/} - - - - - {purpose.map((option) => ( - - {option.label} - - ))} - - - - {/*----------------------------------------------------------------*/} - - - - - - {/*----------------------------------------------------------------*/} - - - - - - {/*----------------------------------------------------------------*/} - - - - - {quarter.map((option) => ( - - {option.label} - - ))} - - - - {/*----------------------------------------------------------------*/} - - - - - {multiyear.map((option) => ( - - {option.label} - - ))} - - - - {/*----------------------------------------------------------------*/} - - - - - - {/*----------------------------------------------------------------*/} - - - - - - {/*----------------------------------------------------------------*/} - - - - - - - - - ); -}; - - -const GrantorDetailsTable = ({ grantDetails, isEditing, handleInputChange }: any) => { - - - return( - - - - - - - - - - - - - - - ); -}; - - -export default GrantDetailPage; \ No newline at end of file diff --git a/app/Grants/page.tsx b/app/Grants/page.tsx deleted file mode 100644 index 784657d..0000000 --- a/app/Grants/page.tsx +++ /dev/null @@ -1,161 +0,0 @@ -"use client"; -import React, { useState, useEffect } from "react"; -import type { Grant } from "@/prisma"; -import Link from "next/link"; -import { SecondarySideBar } from "../components/SecondarySideBar"; - -export default function GrantsPage() { - const [grantsData, setGrantsData] = useState([]); // State to store grants data - - useEffect(() => { - fetchGrantsData(); - }, []); - - const fetchGrantsData = async () => { - try { - const response = await fetch("/api/grants/"); - const result = await response.json(); - setGrantsData(result.data); - } catch (error) { - console.error("Error fetching grants:", error); - } - }; - - const Breadcrumb = () => ( -
- - Home - - / - Grants -
- ); - - const Header = () => ( -
-

Grants

-
- -
-
- ); - - const SearchBar = () => ( -
- - - -
- ); - - //This table dynamically creates rows with each grant - const GrantsTable = ({ grants }: { grants: Grant[] }) => { - // Debugging - if (!Array.isArray(grants)) { - return
Error: Grants is not an array
; - } - return ( -
- - - - - - - - - - - - - - - - {grants.map((grant) => ( - - - - - - - - - - - - ))} - -
- Organization - - Grant Name - - Grant Status - - Requested Amount - - Awarded Amount - - Restriction - - Report Due Date - - Due Date - - Award Date -
- {grant.Representative - ? grant.Representative[0].FirstName - : "N/A"} - - - {grant.GrantName} - - - {grant.AwardStatus || "Pending"} - - ${grant.AskAmount || "0.00"} - - ${grant.AmountAwarded || "0.00"} - - {grant.FundingRestrictions || "None"} - - {grant.EndOfGrantReportDueDate - ? new Date( - grant.EndOfGrantReportDueDate - ).toLocaleDateString() - : "N/A"} - - {grant.GrantDueDate - ? new Date(grant.GrantDueDate).toLocaleDateString() - : "N/A"} - - {grant.AwardDate - ? new Date(grant.AwardDate).toLocaleDateString() - : "Not Awarded Yet"} -
-
- ); - }; - - return ( -
-
- -
- - -
-
- ); -} diff --git a/app/api/donations/[id]/route.ts b/app/api/donations/[id]/route.ts new file mode 100644 index 0000000..a64e568 --- /dev/null +++ b/app/api/donations/[id]/route.ts @@ -0,0 +1,93 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +// Route handlers are being used (Newer), not API Routes, so we have to use NextRequest/NextResponse +// This file will handle single item operations + +// Fetch single Donation based on id, Ex. http://localhost:3000/api/v1/donations/[id] +export async function GET(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = await params; + try { + const data = await prisma.donation.findUnique({ + where: { + id: id, + }, + // Include the donor info, but only its person property, and only the person's first and last names + include: { + donor: { + select: { + person: { + select: { + firstName: true, + lastName: true, + }, + }, + }, + }, + }, + }); + + if (!data) { + return NextResponse.json({ message: "Donation not found" }, { status: 404 }); + } + + return NextResponse.json({ message: `Successfully fetched donation with ID: ${id}`, data: data }, { status: 200 }); + } catch (error) { + console.error(`Error fetching donation with ID: ${id}\n`, error); + return NextResponse.json({ message: "Donation not found" }, { status: 404 }); + } +} + +// Update a single Donation based on id, and only fields that require updating +export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = await params; + + try { + const { + data: { donation }, + } = await req.json(); + + const updatedDonation = await prisma.donation.update({ + where: { + id: id, + }, + data: { + ...donation, + amount: typeof donation.amount === "string" ? parseFloat(donation.amount) : donation.amount, + taxDeductibleAmount: + typeof donation.taxDeductibleAmount === "string" + ? parseFloat(donation.taxDeductibleAmount) + : donation.taxDeductibleAmount, + }, + }); + + return NextResponse.json( + { + message: `Sucessfully updated donation with ID: ${id}`, + data: updatedDonation, + }, + { status: 200 } + ); + } catch (error) { + console.error(`Error updating donation with ID: ${id}\n`, error); + return NextResponse.json({ message: "Donation not found" }, { status: 404 }); + } +} + +// Delete single Donation based on id +export async function DELETE(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = params; + + try { + const data = await prisma.donation.delete({ + where: { + id: id, + }, + }); + + return NextResponse.json({ message: "Deleted data: ", data: data }, { status: 200 }); + } catch (error) { + console.error(`Error deleting donation with ID: ${id}`, error); + return NextResponse.json({ message: "Donation not found" }, { status: 404 }); + } +} diff --git a/app/api/donations/anonymous/route.ts b/app/api/donations/anonymous/route.ts new file mode 100644 index 0000000..51ad1da --- /dev/null +++ b/app/api/donations/anonymous/route.ts @@ -0,0 +1,43 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +// Add new donation +export async function POST(req: NextRequest) { + try { + const body = await req.json(); + + const newDonation = await prisma.donation.create({ + data: { + type: body.data.type || "", + amount: typeof body.data.amount === "string" ? parseFloat(body.data.amount) : body.data.amount || 0, + item: body.data.item || "", + paymentMethod: body.data.paymentMethod || "Credit Card", + campaign: body.data.campaign || "", + fundDesignation: body.data.fundDesignation || "", + recurringFrequency: body.data.recurringFrequency || "None", + date: new Date(body.data.date) || new Date(), + source: body.data.source || "", + isMatching: body.data.isMatching || false, + taxDeductibleAmount: + typeof body.data.taxDeductibleAmount === "string" + ? parseFloat(body.data.taxDeductibleAmount) + : body.data.taxDeductibleAmount || 0, + receiptSent: body.data.receiptSent || false, + receiptNumber: body.data.receiptNumber || "", + isAnonymous: true, + acknowledgementSent: body.data.acknowledgementSent || false, + }, + }); + + return NextResponse.json( + { + message: `Successfully added donation`, + //data: newDonation, + }, + { status: 200 } + ); + } catch (error) { + console.error(`Error adding donation`, error); + return NextResponse.json({ message: "Error adding donation" }, { status: 500 }); + } +} diff --git a/app/api/donations/existing/route.ts b/app/api/donations/existing/route.ts new file mode 100644 index 0000000..6a6e293 --- /dev/null +++ b/app/api/donations/existing/route.ts @@ -0,0 +1,115 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +const findDonorByEmail = async (email: string) => { + try { + // Find the person with the email + const person = await prisma.person.findUnique({ + where: { + emailAddress: email, + }, + select: { + id: true, + }, + }); + + // Find the organization with the email + const org = await prisma.organization.findUnique({ + where: { + emailAddress: email, + }, + select: { + id: true, + }, + }); + + if (person) { + const donor = await prisma.donor.findUnique({ + where: { + personId: person.id, + }, + select: { + id: true, + }, + }); + + if (donor) { + return { id: donor.id }; + } + } + + if (org) { + const donor = await prisma.donor.findUnique({ + where: { + organizationId: org.id, + }, + select: { + id: true, + }, + }); + + if (donor) { + return { id: donor.id }; + } + } + + // If neither exist + return { donor: null }; + } catch (error) { + console.error("Error finding donor by email:", error); + throw new Error("Error checking email"); + } +}; + +// Add new donation +export async function POST(req: NextRequest) { + try { + const body = await req.json(); + + const donorSearch = await findDonorByEmail(body.data.donorEmail); + + if (!donorSearch.id) { + return NextResponse.json( + { + message: "Donor not found", + }, + { status: 404 } + ); + } + + const newDonation = await prisma.donation.create({ + data: { + type: body.data.type || "", + amount: typeof body.data.amount === "string" ? parseFloat(body.data.amount) : body.data.amount || 0, + item: body.data.item || "", + paymentMethod: body.data.paymentMethod || "Credit Card", + campaign: body.data.campaign || "", + fundDesignation: body.data.fundDesignation || "", + recurringFrequency: body.data.recurringFrequency || "None", + date: new Date(body.data.date) || new Date(), + source: body.data.source || "", + isMatching: body.data.isMatching || false, + taxDeductibleAmount: + typeof body.data.taxDeductibleAmount === "string" + ? parseFloat(body.data.taxDeductibleAmount) + : body.data.taxDeductibleAmount || 0, + receiptSent: body.data.receiptSent || false, + receiptNumber: body.data.receiptNumber || "", + isAnonymous: false, + acknowledgementSent: body.data.acknowledgementSent || false, + donorId: donorSearch.id, + }, + }); + + return NextResponse.json( + { + message: `Successfully added donation`, + //data: newDonation, + }, + { status: 200 } + ); + } catch (error) { + console.error(`Error adding donation`, error); + return NextResponse.json({ message: "Error adding donation" }, { status: 500 }); + } +} diff --git a/app/api/donations/get/route.ts b/app/api/donations/get/route.ts new file mode 100644 index 0000000..e69de29 diff --git a/app/api/donations/route.ts b/app/api/donations/route.ts new file mode 100644 index 0000000..bbd899b --- /dev/null +++ b/app/api/donations/route.ts @@ -0,0 +1,113 @@ +import { Prisma } from "@prisma/client"; +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +// Add new donation +export async function POST(req: NextRequest) { + try { + const body = await req.json(); + + const newDonation = await prisma.donation.create({ + data: { + type: body.data.donation.type || "", + amount: + typeof body.data.donation.amount === "string" + ? parseFloat(body.data.donation.amount) + : body.data.donation.amount || 0, + item: body.data.donation.item || "", + paymentMethod: body.data.donation.paymentMethod || "Credit Card", + campaign: body.data.donation.campaign || "", + fundDesignation: body.data.donation.fundDesignation || "", + recurringFrequency: body.data.donation.recurringFrequency || "None", + date: new Date(body.data.donation.date) || new Date(), + source: body.data.donation.source || "", + isMatching: body.data.donation.isMatching, + taxDeductibleAmount: + typeof body.data.donation.taxDeductibleAmount === "string" + ? parseFloat(body.data.donation.taxDeductibleAmount) + : body.data.donation.taxDeductibleAmount || 0, + receiptSent: body.data.donation.receiptSent || false, + receiptNumber: body.data.donation.receiptNumber || "", + isAnonymous: false, + acknowledgementSent: body.data.donation.acknowledgementSent, + donor: { + create: { + type: body.data.donor.type || "Individual", + communicationPreference: body.data.donor.communicationPreference || "Email", + status: body.data.donor.status || "Active", + notes: body.data.donor.notes || "", + isRetained: body.data.donor.isRetained || false, + ...(body.data.donor.type !== "Individual" + ? { + organization: { + create: { + name: body.data.organization.name || "", + emailAddress: body.data.organization.emailAddress || "", + phoneNumber: body.data.organization.phoneNumber || "", + address: { + create: { + addressLine1: body.data.address.addressLine1 || "", + addressLine2: body.data.address.addressLine2 || "", + city: body.data.address.city || "", + state: body.data.address.state || "", + zipCode: body.data.address.zipCode || "", + type: body.data.address.type || "Residential", + }, + }, + }, + }, + } + : { + person: { + create: { + firstName: body.data.person.firstName || "", + lastName: body.data.person.lastName || "", + emailAddress: body.data.person.emailAddress || "", + phoneNumber: body.data.person.phoneNumber || "", + address: { + create: { + addressLine1: body.data.address.addressLine1 || "", + addressLine2: body.data.address.addressLine2 || "", + city: body.data.address.city || "", + state: body.data.address.state || "", + zipCode: body.data.address.zipCode || "", + type: body.data.address.type || "Residential", + }, + }, + }, + }, + }), + }, + }, + }, + }); + + return NextResponse.json( + { + message: `Successfully added donation`, + //data: newDonation, + }, + { status: 200 } + ); + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") { + const meta = error.meta as { target?: string[] }; + const fields = meta?.target || ["field"]; + const fieldList = fields.join(", "); + return NextResponse.json( + { + message: `A donor with the same ${fieldList} already exists. Please use enter a different one.`, + }, + { status: 400 } + ); + } + return NextResponse.json({ message: "Error adding donation" }, { status: 500 }); + } +} + +// Read +export async function GET() { + const data = await prisma.donation.findMany(); + + return NextResponse.json({ message: "Successful fetch", data: data }, { status: 200 }); +} diff --git a/app/api/donors/[id]/route.ts b/app/api/donors/[id]/route.ts new file mode 100644 index 0000000..020eda5 --- /dev/null +++ b/app/api/donors/[id]/route.ts @@ -0,0 +1,135 @@ +import { Address, Donor, Person, Prisma } from "@prisma/client"; +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +// Fetch single Donor based on id, Ex. http://localhost:3000/api/donors/[id] +export async function GET(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = await params; + try { + const data = await prisma.donor.findUnique({ + where: { + id: id, + }, + // Include the donations info, but limit to a few fields + include: { + donation: { + select: { + id: true, + type: true, + amount: true, + item: true, + paymentMethod: true, + date: true, + }, + }, + // Include the person info, but only first/last names, phone, email, and address + person: { + select: { + firstName: true, + lastName: true, + phoneNumber: true, + emailAddress: true, + address: true, + }, + }, + // + organization: { + select: { + name: true, + emailAddress: true, + address: true, + }, + }, + }, + }); + + if (!data) { + return NextResponse.json({ message: "Donor not found" }, { status: 404 }); + } + + return NextResponse.json({ message: `Successfully fetched donor with ID: ${id}`, data: data }, { status: 200 }); + } catch (error) { + console.error(`Error fetching donor with ID: ${id}\n`, error); + return NextResponse.json({ message: "Donor not found" }, { status: 404 }); + } +} + +// Update a single Donor based on id, and only fields that require updating +export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = await params; + + try { + const { + data: { donor, person, address }, + } = (await req.json()) as { + data: { + donor: Donor; + person: Person; + address: Address; + }; + }; + + const updatedDonorAndPerson = await prisma.donor.update({ + where: { + id: id, + }, + data: { + type: donor.type, + communicationPreference: donor.communicationPreference, + status: donor.status, + notes: donor.notes, + isRetained: donor.isRetained, + + person: { + update: { + ...person, + address: { + update: { + ...address, + }, + }, + }, + }, + }, + }); + + return NextResponse.json( + { + message: `Sucessfully updated donor with ID: ${id}`, + data: updatedDonorAndPerson, + }, + { status: 200 } + ); + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") { + const meta = error.meta as { target?: string[] }; + const fields = meta?.target || ["field"]; + const fieldList = fields.join(", "); + return NextResponse.json( + { + message: `A donor with the same ${fieldList} already exists. Please use enter a different one.`, + }, + { status: 400 } + ); + } + return NextResponse.json({ message: "Donor not found" }, { status: 404 }); + } +} + +// Delete single Donor based on id +export async function DELETE(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = await params; + + try { + const data = await prisma.donor.delete({ + where: { + id: id, + }, + }); + + return NextResponse.json({ message: "Deleted data: ", data: data }, { status: 200 }); + } catch (error) { + console.error(`Error deleting donor with ID: ${id}`, error); + return NextResponse.json({ message: "Donor not found" }, { status: 404 }); + } +} diff --git a/app/api/donors/get/route.ts b/app/api/donors/get/route.ts new file mode 100644 index 0000000..d2dec88 --- /dev/null +++ b/app/api/donors/get/route.ts @@ -0,0 +1,100 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + //For pagination + const pageParam = req.nextUrl.searchParams.get("page"); + const rowsPerPageParam = req.nextUrl.searchParams.get("rowsPerPage"); + const pageNum = pageParam ? parseInt(pageParam, 10) : 0; + const rowsPerPageNum = rowsPerPageParam ? parseInt(rowsPerPageParam, 10) : 5; + //For searching + const searchCriteriaParam = req.nextUrl.searchParams.get("searchCriteria") || ""; + const searchValueParam = req.nextUrl.searchParams.get("searchValue") || ""; + + const where: any = {}; + if (searchCriteriaParam && searchValueParam) { + // Dynamically build the filter based on the criteria and value + switch (searchCriteriaParam) { + case "donor": + where.OR = [ + { + person: { + firstName: { + contains: searchValueParam, + mode: "insensitive", + }, + }, + }, + { + person: { + lastName: { + contains: searchValueParam, + mode: "insensitive", + }, + }, + }, + { + organization: { + name: { + contains: searchValueParam, + mode: "insensitive", + }, + }, + }, + ]; + break; + case "campaign": + where.campaign = { + contains: searchValueParam, + mode: "insensitive", + }; + break; + case "fundDesignation": + where.fundDesignation = { + contains: searchValueParam, + mode: "insensitive", + }; + break; + default: + break; // No filter + } + } + + try { + const data = await prisma.donation.findMany({ + skip: pageNum * rowsPerPageNum, + take: rowsPerPageNum, + where, // Applies search filters if any + include: { + donor: { + include: { + person: { + select: { + firstName: true, + lastName: true, + phoneNumber: true, + emailAddress: true, + address: true, + }, + }, + organization: { + select: { + name: true, + emailAddress: true, + address: true, + }, + }, + }, + }, + }, + }); + const count = await prisma.donation.count({ + where, + }); + + return NextResponse.json({ message: "GET REQUEST", data: data, count: count }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ message: "Error fetching grants", error: error }, { status: 500 }); + } +} diff --git a/app/api/donors/route.ts b/app/api/donors/route.ts new file mode 100644 index 0000000..750c5d1 --- /dev/null +++ b/app/api/donors/route.ts @@ -0,0 +1,87 @@ +import { Prisma } from "@prisma/client"; +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +// Add new donor +export async function POST(req: NextRequest) { + try { + const body = await req.json(); + + const newDonor = await prisma.donor.create({ + data: { + type: body.data.donor.type || "Individual", + communicationPreference: body.data.donor.communicationPreference || "Email", + status: body.data.donor.status || "Active", + notes: body.data.donor.notes || "", + isRetained: body.data.donor.isRetained || false, + ...(body.data.donor.type !== "Individual" + ? { + organization: { + create: { + name: body.data.organization.name || "", + emailAddress: body.data.organization.emailAddress || "", + address: { + create: { + addressLine1: body.data.address.addressLine1 || "", + addressLine2: body.data.address.addressLine2 || "", + city: body.data.address.city || "", + state: body.data.address.state || "", + zipCode: body.data.address.zipCode || "", + type: body.data.address.type || "Residential", + }, + }, + }, + }, + } + : { + person: { + create: { + firstName: body.data.person.firstName || "", + lastName: body.data.person.lastName || "", + emailAddress: body.data.person.emailAddress || "", + phoneNumber: body.data.person.phoneNumber || "", + address: { + create: { + addressLine1: body.data.address.addressLine1 || "", + addressLine2: body.data.address.addressLine2 || "", + city: body.data.address.city || "", + state: body.data.address.state || "", + zipCode: body.data.address.zipCode || "", + type: body.data.address.type || "Residential", + }, + }, + }, + }, + }), + }, + }); + + return NextResponse.json( + { + message: "Successfully created a new donor", + }, + { status: 200 } + ); + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2002") { + const meta = error.meta as { target?: string[] }; + const fields = meta?.target || ["field"]; + const fieldList = fields.join(", "); + return NextResponse.json( + { + message: `A donor with the same ${fieldList} already exists. Please use enter a different one.`, + }, + { status: 400 } + ); + } + + return NextResponse.json({ message: "Failed to create donor" }, { status: 500 }); + } +} + +// Read +export async function GET() { + const data = await prisma.donor.findMany(); + + return NextResponse.json({ message: "GET REQUEST", data: data }, { status: 200 }); +} diff --git a/app/api/grantors/[id]/get/route.ts b/app/api/grantors/[id]/get/route.ts new file mode 100644 index 0000000..9b7ea3b --- /dev/null +++ b/app/api/grantors/[id]/get/route.ts @@ -0,0 +1,26 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = await params; + try { + const data = await prisma.grantor.findUnique({ + where: { + id: id, + }, + include: { + organization: { + include: { + address: true, + }, + }, + }, + }); + console.log(data); + + return NextResponse.json({ data: data }, { status: 200 }); + } catch (error) { + console.error("Error fetching grantor with ID: ", id); + return NextResponse.json({ message: "Grantor item not found" }, { status: 404 }); + } +} diff --git a/app/api/grantors/route.ts b/app/api/grantors/route.ts new file mode 100644 index 0000000..3cd6235 --- /dev/null +++ b/app/api/grantors/route.ts @@ -0,0 +1,119 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +// Route handlers are being used (Newer), not API Routes, so we have to use NextRequest/NextResponse + +// Create +export async function POST(req: NextRequest) { + try { + const body = req.json(); + + return NextResponse.json( + { + message: "POST REQUEST", + receivedData: body, + }, + { status: 200 } + ); + } catch (error) { + console.error("POST ERROR:", error); + } +} + +// Read +export async function GET(req: NextRequest) { + //For pagination + const pageParam = req.nextUrl.searchParams.get("page"); + const rowsPerPageParam = req.nextUrl.searchParams.get("rowsPerPage"); + const pageNum = pageParam ? parseInt(pageParam, 10) : 0; + const rowsPerPageNum = rowsPerPageParam ? parseInt(rowsPerPageParam, 10) : 5; + //For searching + const searchCriteriaParam = req.nextUrl.searchParams.get("searchCriteria") || ""; + const searchValueParam = req.nextUrl.searchParams.get("searchValue") || ""; + + const where: any = {}; + if (searchCriteriaParam && searchValueParam) { + // Dynamically build the filter based on the criteria and value + switch (searchCriteriaParam) { + case "name": + where.organization = { + name: { + contains: searchValueParam, + mode: "insensitive", + }, + }; + break; + case "type": + where.type = { + contains: searchValueParam, + mode: "insensitive", + }; + break; + case "addressLine1": + where.organization = { + address: { + addressLine1: { + contains: searchValueParam, + mode: "insensitive", + }, + }, + }; + break; + case "city": + where.organization = { + address: { + city: { + contains: searchValueParam, + mode: "insensitive", + }, + }, + }; + break; + case "state": + where.organization = { + address: { + state: { + contains: searchValueParam, + mode: "insensitive", + }, + }, + }; + break; + case "zipcode": + where.organization = { + address: { + zipCode: { + contains: searchValueParam, + mode: "insensitive", + }, + }, + }; + break; + default: + break; // No filter + } + } + + try { + const data = await prisma.grantor.findMany({ + skip: pageNum * rowsPerPageNum, + take: rowsPerPageNum, + where, // Applies search filters if any + include: { + organization: { + include: { + address: true, + }, + }, + }, + }); + const count = await prisma.grantor.count({ + where, + }); + + return NextResponse.json({ message: "GET REQUEST", data: data, count: count }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ message: "Error fetching grants", error: error }, { status: 500 }); + } +} diff --git a/app/api/grants/[id]/route.ts b/app/api/grants/[id]/get/route.ts similarity index 62% rename from app/api/grants/[id]/route.ts rename to app/api/grants/[id]/get/route.ts index 6830d98..6e7097a 100644 --- a/app/api/grants/[id]/route.ts +++ b/app/api/grants/[id]/get/route.ts @@ -1,37 +1,50 @@ -import { PrismaClient } from "@prisma/client"; +import prisma from "@/app/utils/db"; import { NextRequest, NextResponse } from "next/server"; // Route handlers are being used (Newer), not API Routes, so we have to use NextRequest/NextResponse // This file will handle single item operations -const prisma = new PrismaClient(); - // Fetch single Grant based on id, Ex. http://localhost:3000/api/grants/[id] -export async function GET( - req: NextRequest, - { params }: { params: { id: string } } -) { - const { id } = params; +export async function GET(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = await params; try { const data = await prisma.grant.findUnique({ where: { - GrantID: id, + id: id, + }, + + include: { + representativeGrant: { + include: { + representative: { + include: { + person: true, + grantor: { + include: { + organization: true, + }, + }, + }, + }, + }, + }, }, }); console.log(data); - return NextResponse.json({ data }, { status: 200 }); + if (!data) { + return NextResponse.json({ message: "Grant not found" }, { status: 404 }); + } + + return NextResponse.json({ message: `Successfully fetched grant with ID: ${id}`, data: data }, { status: 200 }); } catch (error) { - console.error("Error fetching grant with ID: ", id); - return NextResponse.json( - { message: "Grant item not found" }, - { status: 404 } - ); + console.error(`Error fetching grant with ID: ${id}\n`, id); + return NextResponse.json({ message: "Grant not found" }, { status: 404 }); } } // Update single Grant based on id -export async function PUT( +/*export async function PUT( req: NextRequest, { params }: { params: { id: string } } ) { @@ -41,14 +54,14 @@ export async function PUT( const body = await req.json(); //const bodyData = JSON.parse(body) as GrantData; - /* + const updatedData = await prisma.grant.update({ where: { GrantID: id, }, data: bodyData, }); - */ + return NextResponse.json( { message: "Updated grant with id:", id }, { status: 200 } @@ -72,7 +85,7 @@ export async function DELETE( try { const data = await prisma.grant.delete({ where: { - GrantID: id, + id: id, }, }); @@ -87,4 +100,4 @@ export async function DELETE( { status: 404 } ); } -} +}*/ diff --git a/app/api/grants/[id]/patch/route.ts b/app/api/grants/[id]/patch/route.ts new file mode 100644 index 0000000..3c0597f --- /dev/null +++ b/app/api/grants/[id]/patch/route.ts @@ -0,0 +1,57 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = await params; + + try { + const { + data: { grant }, + } = await req.json(); + + const updatedData = await prisma.grant.update({ + where: { + id: id, + }, + data: grant /*{ + ...grant, + representativeGrants: { + update: grant.representativeGrants?.map((repGrant: any) => ({ + where: { + grantId: id, + representativeId: repGrant.representativeId, + }, + data: { + representative: { + update: { + person: { + update: { + firstName: repGrant.representative.person.firstName, + lastName: repGrant.representative.person.lastName, + emailAddress: repGrant.representative.person.emailAddress, + phoneNumber: repGrant.representative.person.phoneNumber, + }, + }, + grantor: { + update: { + organization: { + update: { + name: repGrant.representative.grantor.organization.name, + }, + }, + }, + }, + }, + }, + }, + })), + }, + },*/, + }); + console.log(updatedData); + return NextResponse.json({ message: "Updated grant with id:", id: id }, { status: 200 }); + } catch (error) { + console.error("Error fetching grant with ID: ", id); + return NextResponse.json({ message: "Grant item not found" }, { status: 404 }); + } +} diff --git a/app/api/grants/get/route.ts b/app/api/grants/get/route.ts new file mode 100644 index 0000000..ce789cf --- /dev/null +++ b/app/api/grants/get/route.ts @@ -0,0 +1,85 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +// Read +export async function GET(req: NextRequest) { + //For pagination + const pageParam = req.nextUrl.searchParams.get("page"); + const rowsPerPageParam = req.nextUrl.searchParams.get("rowsPerPage"); + const pageNum = pageParam ? parseInt(pageParam, 10) : 0; + const rowsPerPageNum = rowsPerPageParam ? parseInt(rowsPerPageParam, 10) : 5; + //For searching + const searchCriteriaParam = req.nextUrl.searchParams.get("searchCriteria") || ""; + const searchValueParam = req.nextUrl.searchParams.get("searchValue") || ""; + + const where: any = {}; + if (searchCriteriaParam && searchValueParam) { + // Dynamically build the filter based on the criteria and value + switch (searchCriteriaParam) { + case "name": + where.name = { + contains: searchValueParam, + mode: "insensitive", + }; + break; + case "grantor": + //Nested relation + where.representativeGrant = { + some: { + representative: { + grantor: { + organization: { + name: { + contains: searchValueParam, + mode: "insensitive", + }, + }, + }, + }, + }, + }; + break; + case "status": + where.status = { + contains: searchValueParam, + mode: "insensitive", + }; + break; + default: + break; // No filter + } + } + + try { + const data = await prisma.grant.findMany({ + skip: pageNum * rowsPerPageNum, + take: rowsPerPageNum, + where, // Applies search filters if any + include: { + representativeGrant: { + include: { + representative: { + include: { + person: true, + grantor: { + include: { + organization: true, + }, + }, + }, + }, + }, + }, + }, + }); + const count = await prisma.grant.count({ + where, + }); + console.log(data); + + return NextResponse.json({ message: "GET REQUEST", data: data, count: count }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ message: "Error fetching grants", error: error }, { status: 500 }); + } +} diff --git a/app/api/grants/post/route.ts b/app/api/grants/post/route.ts new file mode 100644 index 0000000..284033d --- /dev/null +++ b/app/api/grants/post/route.ts @@ -0,0 +1,63 @@ +import prisma from "@/app/utils/db"; +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest, res: NextResponse) { + const body = await req.json(); + + try { + const newGrant = await prisma.grant.create({ + data: { + name: body.name, + status: body.status, + amountRequested: body.amountRequested, + amountAwarded: body.amountAwarded, + purpose: body.purpose, + startDate: body.startDate, + endDate: body.endDate, + isMultipleYears: body.isMultipleYears, + quarter: body.quarter, + acknowledgementSent: body.acknowledgementSent, + awardNotificationDate: body.awardNotificationDate, + fundingArea: body.fundingArea, + proposalDueDate: body.proposalDueDate, + proposalSummary: body.proposalSummary, + proposalSubmissionDate: body.proposalSubmissionDate, + applicationType: body.applicationType, + internalOwner: body.internalOwner, + fundingRestriction: body.fundingRestriction, + matchingRequirement: body.matchingRequirement, + useArea: body.useArea, + isEligibleForRenewal: body.isEligibleForRenewal, + renewalApplicationDate: body.renewalApplicationDate, + renewalAwardStatus: body.renewalAwardStatus, + }, + }); + + return NextResponse.json({ message: "POST REQUEST", grant: newGrant }, { status: 200 }); + } catch (error) { + return NextResponse.json({ message: "Error creating grants", error: error }, { status: 500 }); + } +} + +/*export default async function handler(req: NextApiRequest, res: NextApiResponse) { + if (req.method === 'POST') { + const { title, description, amount } = req.body; + + try { + const newGrant = await prisma.grant.create({ + data: { + title, + description, + amount: parseFloat(amount), // Assuming amount is a number + }, + }); + + res.status(200).json(newGrant); + } catch (error) { + res.status(500).json({ error: 'Failed to create grant' }); + } + } else { + res.status(405).end(); // Method Not Allowed + } +} +*/ diff --git a/app/api/grants/route.ts b/app/api/grants/route.ts deleted file mode 100644 index 30084cd..0000000 --- a/app/api/grants/route.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { PrismaClient } from '@prisma/client'; -import { NextRequest, NextResponse } from 'next/server'; - -// Route handlers are being used (Newer), not API Routes, so we have to use NextRequest/NextResponse - -const prisma = new PrismaClient(); - -// Create -export async function POST(req: NextRequest) { - try { - const body = req.json(); - - return NextResponse.json( - { - message: 'POST REQUEST', - receivedData: body, - }, - { status: 200 } - ); - } catch (error) { - console.error('POST ERROR:', error); - } -} - -// Read -export async function GET() { - const data = await prisma.grant.findMany(); - - return NextResponse.json( - { message: 'GET REQUEST', data: data }, - { status: 200 } - ); -} - -// Update - -// Delete diff --git a/app/api/import/route.ts b/app/api/import/route.ts new file mode 100644 index 0000000..246bb53 --- /dev/null +++ b/app/api/import/route.ts @@ -0,0 +1,47 @@ +import { NextResponse, NextRequest } from "next/server"; +import { parse } from "csv-parse/sync"; + +type RecordType = { + [key: string]: string | number | null; +}; + +export async function POST(req: NextRequest) { + try { + const formData = await req.formData(); + const file = formData.get("csv") as File; + + if (!file) { + return NextResponse.json({ error: "No file uploaded" }, { status: 400 }); + } + + const fileContent = await file.text(); + + const records = parse(fileContent, { + columns: true, + skip_empty_lines: true, + relax_column_count: true, + }); + + // Remvoe trailing white spaces in every cell + const normalizedRecords = records.map((record: Record) => { + const normalizedRecord: Record = {}; + + for (const key in record) { + const trimmedKey = key.trim(); + const value = record[key]; + + normalizedRecord[trimmedKey] = typeof value === "string" ? value.trim() : value; + } + + return normalizedRecord; + }); + + const funds = normalizedRecords.map((record: RecordType) => record["Kids-U Program"]).filter(Boolean); + console.log("Fund:", funds); + + return NextResponse.json({ message: "CSV parsed successfully" }, { status: 200 }); + } catch (error) { + console.error("Error processing request:", error); + return NextResponse.json({ error: "Internal server error" }, { status: 500 }); + } +} diff --git a/app/api/organizations/route.ts b/app/api/organizations/route.ts deleted file mode 100644 index dbc3b97..0000000 --- a/app/api/organizations/route.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { PrismaClient } from '@prisma/client'; -import { NextRequest, NextResponse } from 'next/server'; - -const prisma = new PrismaClient(); - -// Create -export async function POST(req: NextRequest) { - try { - const body = req.json(); - - return NextResponse.json( - { - message: 'POST REQUEST', - receivedData: body, - }, - { status: 200 } - ); - } catch (error) { - console.error('POST ERROR:', error); - } -} - -// Fetch all organizations -export async function GET() { - const data = await prisma.organization.findMany(); - - return NextResponse.json( - { message: 'GET REQUEST', data: data }, - { status: 200 } - ); -} - -// Update - -// Delete diff --git a/app/api/representatives/route.ts b/app/api/representatives/route.ts deleted file mode 100644 index 2cda4b0..0000000 --- a/app/api/representatives/route.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { PrismaClient } from '@prisma/client'; -import { NextRequest, NextResponse } from 'next/server'; - -const prisma = new PrismaClient(); - -// Create -export async function POST(req: NextRequest) { - try { - const body = req.json(); - - return NextResponse.json( - { - message: 'POST REQUEST', - receivedData: body, - }, - { status: 200 } - ); - } catch (error) { - console.error('POST ERROR:', error); - } -} - -// Fetch all representatives -export async function GET() { - const data = await prisma.representative.findMany(); - - return NextResponse.json( - { message: 'GET REQUEST', data: data }, - { status: 200 } - ); -} - -// Update - -// Delete diff --git a/app/components/Grants/GrantAddComponents/GrantInformationInput.tsx b/app/components/Grants/GrantAddComponents/GrantInformationInput.tsx new file mode 100644 index 0000000..1555a3f --- /dev/null +++ b/app/components/Grants/GrantAddComponents/GrantInformationInput.tsx @@ -0,0 +1,75 @@ +import { MenuItem, Select, TextField, Typography } from "@mui/material"; +import { green } from "@mui/material/colors"; +import { Box } from "@mui/system"; +import React from "react"; + +const TypographyStyle = { + width: "100%", + display: "flex", + justifyContent: "flex-start", + fontWeight: "bold", + fontSize: "16px", + color: "#333", + marginBottom: "8px", +}; + +interface Props { + title: string; + type: "email" | "tel" | "text" | "date" | "password" | "dropdown" | "number"; + dropdown?: string[]; + width?: "S" | "M" | "L" | "XL"; +} + +const widthMap: Record = { + S: "165px", + M: "200px", + L: "350px", + XL: "100%", +}; + +const GrantInformationInput: React.FC = ({ + title, + type, + dropdown, + width = "M", +}) => { + return ( + + {title} + {type === "dropdown" && dropdown ? ( + + ) : ( + + )} + + ); +}; + +export default GrantInformationInput; diff --git a/app/components/MainSidebar.tsx b/app/components/MainSidebar.tsx index 0ec01b6..ea13a20 100644 --- a/app/components/MainSidebar.tsx +++ b/app/components/MainSidebar.tsx @@ -1,26 +1,48 @@ import React from "react"; -import Link from "next/link"; +import { List, ListItem, Link } from "@mui/material"; +import NextLink from "next/link"; + +type ListItem = { + name: string; + reference: string; +}; + +const MainSidebarItems: ListItem[] = [ + { name: "Dashboard", reference: "/" }, + { name: "Constituents", reference: "/Constituents" }, + { name: "Donations", reference: "/Donations" }, + { name: "Grants", reference: "/Grants" }, +]; export default function MainSidebar() { return ( -
-
    -
  • - Dashboard -
  • -
  • - Constituents -
  • -
  • - Donations -
  • -
  • - Grants -
  • -
  • - Volunteers -
  • -
-
+ + {MainSidebarItems.map((item, index) => ( + + + {item.name} + + + ))} + ); } + +const styles = { + container: { + backgroundColor: "#09111e", + width: "8rem", + minHeight: "100vh", + display: "flex", + flexDirection: "column", + }, + button: { + color: "white", + width: "100%", + borderRadius: 1, + p: 1, + px: 0.5, + fontSize: "0.95rem", + "&:hover": { backgroundColor: "grey.600" }, + }, +}; diff --git a/app/components/SecondarySideBar.tsx b/app/components/SecondarySideBar.tsx index bc20fa5..098373e 100644 --- a/app/components/SecondarySideBar.tsx +++ b/app/components/SecondarySideBar.tsx @@ -1,4 +1,5 @@ -import Link from "next/link"; +import NextLink from "next/link"; +import { List, ListItem, Link } from "@mui/material"; type ListItem = { name: string; @@ -7,17 +8,33 @@ type ListItem = { export const SecondarySideBar = ({ items }: { items: ListItem[] }) => { return ( -
-
    - {items.map((item, index) => ( -
  • - {item.name} -
  • - ))} -
-
+ + {items.map((item, index) => ( + + + {item.name} + + + ))} + ); }; + +const styles = { + container: { + backgroundColor: "#0d1a2d", + width: "7rem", + minHeight: "100vh", + display: "flex", + flexDirection: "column", + }, + button: { + color: "white", + width: "100%", + borderRadius: 1, + p: 1, + px: 0.5, + fontSize: "0.95rem", + "&:hover": { backgroundColor: "grey.600" }, + }, +}; diff --git a/app/components/TopNavigationBar.tsx b/app/components/TopNavigationBar.tsx new file mode 100644 index 0000000..e2f21a7 --- /dev/null +++ b/app/components/TopNavigationBar.tsx @@ -0,0 +1,70 @@ +'use client'; +import React from 'react'; +import AppBar from '@mui/material/AppBar'; +import Toolbar from '@mui/material/Toolbar'; +import Typography from '@mui/material/Typography'; +import Box from '@mui/material/Box'; +import IconButton from '@mui/material/IconButton'; +import Avatar from '@mui/material/Avatar'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import { useState } from 'react'; + +export default function TopNavigationBar() { + const [anchorEl, setAnchorEl] = useState(null); + + const handleMenuOpen = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleMenuClose = () => { + setAnchorEl(null); + }; + + return ( + + + + + + Kids-U Admin + + + + + + Admin Profile + + + + + + Profile + Settings + Logout + + + + + ); +} + + diff --git a/app/components/donations/DetailFooter.tsx b/app/components/donations/DetailFooter.tsx new file mode 100644 index 0000000..2600673 --- /dev/null +++ b/app/components/donations/DetailFooter.tsx @@ -0,0 +1,152 @@ +import { Box, Button, Tooltip } from "@mui/material"; +import { useRouter } from "next/navigation"; +import { useEffect, useState } from "react"; +import { FieldErrors, UseFormHandleSubmit } from "react-hook-form"; +import { DonationFormProps, DonorFormProps } from "../formComponents/FormInputProps"; + +type FooterProps = { + id: string; + name: string; + href: string; + apiUrl: string; + handleSubmit: UseFormHandleSubmit; + isDirty: boolean; + errors: FieldErrors; +}; + +export const DetailFooter = ({ id, name, href, apiUrl, handleSubmit, isDirty, errors }: FooterProps) => { + const router = useRouter(); + + const [isButtonDisabled, setIsButtonDisabled] = useState(true); + + const seconds: number = 4000; + const handleButtonDisable = () => { + setTimeout(() => { + setIsButtonDisabled(false); + }, seconds); + }; + + // Disable button for n seconds on refresh/load + useEffect(() => { + handleButtonDisable(); + }, []); + + // Disable button after it has been pressed for n seconds + useEffect(() => { + handleButtonDisable(); + }, [isButtonDisabled]); + + const handleSave = async (data: DonorFormProps | DonationFormProps) => { + // If fields not changed, don't save + if (!isDirty || Object.keys(errors).length > 0) { + alert("Cannot save when fields are unchanged or there are validation errors."); + return; + } + try { + setIsButtonDisabled(true); + + const requestBody = JSON.stringify({ data }); + + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}${apiUrl}/${id}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: requestBody, + }); + + if (!response.ok) { + const errorData = await response.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + alert("Successfully updated data."); + } catch (error) { + alert(error); + console.error(error); + } + }; + + const handleDelete = async () => { + const remove = confirm(`Are you sure you would like to delete this ${name}?\nThis cannot be undone.`); + + if (remove) { + try { + setIsButtonDisabled(true); + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}${apiUrl}/${id}`, { + method: "DELETE", + }); + + if (!response.ok) { + const errorData = await response.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + alert(`Successfully deleted ${name} data`); + router.push(href); + } catch (error) { + alert(error); + console.error(error); + } + } + }; + + const handleCancel = () => { + router.push(href); + }; + + return ( + + 0 + ? "Cannot save because there are validation errors." + : "Save all changes." + } + > + + + + + + + + + + + + + + + + ); +}; + +const styles = { + footerContainer: { + display: "flex", + gap: 1, + py: 2, + gridColumn: "span 3", + }, + buttonContained: { + backgroundColor: "#1a345b", + }, + buttonOutlined: { + borderColor: "black", + color: "black", + }, +}; diff --git a/app/components/donations/MiniDonationTable.tsx b/app/components/donations/MiniDonationTable.tsx new file mode 100644 index 0000000..286a7b3 --- /dev/null +++ b/app/components/donations/MiniDonationTable.tsx @@ -0,0 +1,261 @@ +import { + Box, + Table, + TableHead, + TableRow, + TableCell, + TableBody, + TableSortLabel, + TablePagination, + TableFooter, + IconButton, + TableContainer, + useTheme, +} from "@mui/material"; +import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft"; +import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight"; +import LastPageIcon from "@mui/icons-material/LastPage"; +import FirstPageIcon from "@mui/icons-material/FirstPage"; +import Link from "next/link"; +import { useEffect, useState } from "react"; +import React from "react"; +import { DonationTableState } from "../../types/states"; + +function descendingComparator(a: T, b: T, orderBy: keyof T) { + if (b[orderBy] < a[orderBy]) { + return -1; + } + if (b[orderBy] > a[orderBy]) { + return 1; + } + return 0; +} + +type Order = "asc" | "desc"; + +function getComparator( + order: Order, + orderBy: Key +): (a: { [key in Key]: number | string | Date }, b: { [key in Key]: number | string | Date }) => number { + return order === "desc" + ? (a, b) => descendingComparator(a, b, orderBy) + : (a, b) => -descendingComparator(a, b, orderBy); +} + +type TableProps = { + onRequestSort: (event: React.MouseEvent, property: keyof DonationTableState) => void; + order: Order; + orderBy: string; +}; + +type HeadCell = { + id: keyof DonationTableState; + numeric: boolean; + label: string; +}; + +const headCells: HeadCell[] = [ + { + id: "type", + numeric: false, + label: "Donation Type", + }, + { + id: "amount", + numeric: true, + label: "Donation Amount / Item(s) Value", + }, + { + id: "item", + numeric: false, + label: "Item", + }, + { + id: "paymentMethod", + numeric: false, + label: "Method", + }, + { + id: "date", + numeric: false, + label: "Date", + }, +]; + +interface TablePaginationActionsProps { + count: number; + page: number; + rowsPerPage: number; + onPageChange: (event: React.MouseEvent, newPage: number) => void; +} + +function TablePaginationActions(props: TablePaginationActionsProps) { + const theme = useTheme(); + const { count, page, rowsPerPage, onPageChange } = props; + + const handleFirstPageButtonClick = (event: React.MouseEvent) => { + onPageChange(event, 0); + }; + + const handleBackButtonClick = (event: React.MouseEvent) => { + onPageChange(event, page - 1); + }; + + const handleNextButtonClick = (event: React.MouseEvent) => { + onPageChange(event, page + 1); + }; + + const handleLastPageButtonClick = (event: React.MouseEvent) => { + onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1)); + }; + + return ( + + + {theme.direction === "rtl" ? : } + + + {theme.direction === "rtl" ? : } + + = Math.ceil(count / rowsPerPage) - 1} + aria-label="next page" + > + {theme.direction === "rtl" ? : } + + = Math.ceil(count / rowsPerPage) - 1} + aria-label="last page" + > + {theme.direction === "rtl" ? : } + + + ); +} + +export const TableHeader = (props: TableProps) => { + const { order, orderBy, onRequestSort } = props; + + const createSortHandler = (property: keyof DonationTableState) => (event: React.MouseEvent) => { + onRequestSort(event, property); + }; + + return ( + + + {headCells.map((headCell) => ( + + + {headCell.label} + + + ))} + + + ); +}; + +export const MiniDonationsTable = ({ donations }: { donations: DonationTableState[] }) => { + const [order, setOrder] = React.useState("asc"); + const [orderBy, setOrderBy] = useState("type"); + + useEffect(() => {}); + + const visibleRows = React.useMemo( + () => [...donations].sort(getComparator(order, orderBy)), + [order, orderBy, donations] + ); + + const handleSort = (event: React.MouseEvent, property: keyof DonationTableState) => { + const isAscending: boolean = orderBy === property && order === "asc"; + setOrder(isAscending ? "desc" : "asc"); + setOrderBy(property); + }; + + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(5); + + const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - donations.length) : 0; + + const handleChangePage = (event: React.MouseEvent | null, newPage: number) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + return ( + + + + + {visibleRows.map((donation) => { + return ( + + + + {donation.type} + + + + ${donation.amount} + + {donation.type !== "In-Kind" ? "" : donation.item} + {donation.type !== "In-Kind" ? donation.paymentMethod : ""} + {new Date(donation.date).toLocaleDateString()} + + ); + })} + + + + + + + +
+
+ ); +}; + +const styles = { + table: { + minWidth: 750, + }, + tableCellHeader: { + fontWeight: "bold", + }, + tableCell: { + borderTop: "1px solid #ccc", + }, +}; diff --git a/app/components/donations/add/AddDonorFooter.tsx b/app/components/donations/add/AddDonorFooter.tsx new file mode 100644 index 0000000..46878f6 --- /dev/null +++ b/app/components/donations/add/AddDonorFooter.tsx @@ -0,0 +1,118 @@ +import { Box, Button, Tooltip } from "@mui/material"; +import { useRouter } from "next/navigation"; +import { useEffect, useState } from "react"; +import { FieldErrors, UseFormHandleSubmit } from "react-hook-form"; +import { AddDonationDonorFormProps, DonorFormProps } from "../../formComponents/FormInputProps"; + +type FooterProps = { + handleSubmit: UseFormHandleSubmit; + isDirty: boolean; + errors: FieldErrors; +}; + +export const AddDonorFooter = ({ handleSubmit, isDirty, errors }: FooterProps) => { + const router = useRouter(); + + const [isButtonDisabled, setIsButtonDisabled] = useState(true); + + const seconds: number = 4000; + const handleButtonDisable = () => { + setTimeout(() => { + setIsButtonDisabled(false); + }, seconds); + }; + + // Disable button for n seconds on refresh/load + useEffect(() => { + handleButtonDisable(); + }, []); + + // Disable button after it has been pressed for n seconds + useEffect(() => { + handleButtonDisable(); + }, [isButtonDisabled]); + + const handleAdd = async (data: DonorFormProps) => { + if (!isDirty || Object.keys(errors).length > 0) { + alert("Cannot add when fields are unchanged or there are validation errors."); + return; + } + + try { + setIsButtonDisabled(true); + const requestBody = JSON.stringify({ data }); + + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/donors/`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: requestBody, + }); + + if (!response.ok) { + const errorData = await response.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + alert("Successfully added data."); + location.reload(); + } catch (error) { + alert(error); + console.error(error); + } + }; + + const handleCancel = () => { + router.push("/Donors"); + }; + + return ( + + 0 + ? "Cannot add because there are validation errors." + : "Add item." + } + > + + + + + + + + + + + + ); +}; + +const styles = { + footerContainer: { + display: "flex", + gap: 1, + py: 2, + gridColumn: "span 3", + }, + buttonContained: { + backgroundColor: "#1a345b", + }, + buttonOutlined: { + borderColor: "black", + color: "black", + }, +}; diff --git a/app/components/donations/add/AddFooter.tsx b/app/components/donations/add/AddFooter.tsx new file mode 100644 index 0000000..026b34c --- /dev/null +++ b/app/components/donations/add/AddFooter.tsx @@ -0,0 +1,194 @@ +import { Box, Button, Tooltip } from "@mui/material"; +import { useRouter } from "next/navigation"; +import { useEffect, useState } from "react"; +import { FieldErrors, UseFormHandleSubmit } from "react-hook-form"; +import { AddDonationDonorFormProps } from "../../formComponents/FormInputProps"; +import { DonationState } from "@/app/types/states"; + +type FooterProps = { + donorMode: string; + email: string; + handleSubmit: UseFormHandleSubmit; + isDirty: boolean; + errors: FieldErrors; +}; + +export const AddFooter = ({ donorMode, email, handleSubmit, isDirty, errors }: FooterProps) => { + const router = useRouter(); + + const [isButtonDisabled, setIsButtonDisabled] = useState(true); + + const seconds: number = 4000; + const handleButtonDisable = () => { + setTimeout(() => { + setIsButtonDisabled(false); + }, seconds); + }; + + // Disable button for n seconds on refresh/load + useEffect(() => { + handleButtonDisable(); + }, []); + + // Disable button after it has been pressed for n seconds + useEffect(() => { + handleButtonDisable(); + }, [isButtonDisabled]); + + const addAnonymousDonor = async (data: DonationState) => { + try { + const requestBody = JSON.stringify({ data }); + + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/donations/anonymous`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: requestBody, + }); + + if (!response.ok) { + const errorData = await response.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + alert("Successfully added data."); + location.reload(); + } catch (error) { + alert("Error adding data"); + console.error(error); + } + }; + + const addNewDonor = async (data: AddDonationDonorFormProps) => { + try { + const requestBody = JSON.stringify({ data }); + + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/donations/`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: requestBody, + }); + + if (!response.ok) { + const errorData = await response.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + alert("Successfully added data."); + location.reload(); + } catch (error) { + alert("Error adding data"); + console.error(error); + } + }; + + const addExistingDonor = async (data: DonationState) => { + try { + const requestBody = JSON.stringify({ + data: { + ...data, + donorEmail: email, + }, + }); + + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/donations/existing`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: requestBody, + }); + + if (!response.ok) { + const errorData = await response.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + + alert("Successfully added data."); + location.reload(); + } catch (error) { + alert(error); + console.error(error); + } + }; + + const handleAdd = async (data: AddDonationDonorFormProps) => { + // If fields not changed, don't add + if (!isDirty || Object.keys(errors).length > 0) { + alert("Cannot add when fields are unchanged or there are validation errors."); + return; + } + + setIsButtonDisabled(true); + switch (donorMode) { + case "Anonymous": + addAnonymousDonor(data.donation); + break; + case "New": + addNewDonor(data); + break; + case "Existing": + addExistingDonor(data.donation); + break; + default: + return; + } + }; + + const handleCancel = () => { + router.push("/Donations"); + }; + + return ( + + 0 + ? "Cannot add because there are validation errors." + : "Add item." + } + > + + + + + + + + + + + + ); +}; + +const styles = { + footerContainer: { + display: "flex", + gap: 1, + py: 2, + gridColumn: "span 3", + }, + buttonContained: { + backgroundColor: "#1a345b", + }, + buttonOutlined: { + borderColor: "black", + color: "black", + }, +}; diff --git a/app/components/formComponents/FormInputCheckbox.tsx b/app/components/formComponents/FormInputCheckbox.tsx new file mode 100644 index 0000000..9c7e7bb --- /dev/null +++ b/app/components/formComponents/FormInputCheckbox.tsx @@ -0,0 +1,22 @@ +import React from "react"; +import { Checkbox, FormControl, FormControlLabel } from "@mui/material"; +import { Controller } from "react-hook-form"; +import { FormInputProps } from "./FormInputProps"; + +export const FormInputCheckbox: React.FC = ({ name, control, required, label, readOnly }) => { + return ( + ( + + onChange(e.target.checked)} disabled={readOnly} />} + label={label} + /> + + )} + /> + ); +}; diff --git a/app/components/formComponents/FormInputDate.tsx b/app/components/formComponents/FormInputDate.tsx new file mode 100644 index 0000000..1cfdf9d --- /dev/null +++ b/app/components/formComponents/FormInputDate.tsx @@ -0,0 +1,34 @@ +import { Controller } from "react-hook-form"; +import { FormInputProps } from "./FormInputProps"; +import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; +import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFnsV3"; + +export const FormInputDate = ({ + name, + control, + label, + required, + sx, +}: FormInputProps) => { + return ( + + ( + + )} + /> + + ); +}; diff --git a/app/components/formComponents/FormInputDropdown.tsx b/app/components/formComponents/FormInputDropdown.tsx new file mode 100644 index 0000000..6d6b9ee --- /dev/null +++ b/app/components/formComponents/FormInputDropdown.tsx @@ -0,0 +1,45 @@ +import { MenuItem } from "@mui/material"; +import { Controller } from "react-hook-form"; +import TextField from "@mui/material/TextField"; +import { FormInputSelectProps, MenuItemType } from "./FormInputProps"; + +export const FormInputDropdown: React.FC = ({ + name, + control, + label, + required, + sx, + readOnly, + menuItems = [], +}) => { + return ( + ( + + {menuItems.map((item: MenuItemType) => ( + + {item.label} + + ))} + + )} + /> + ); +}; diff --git a/app/components/formComponents/FormInputProps.ts b/app/components/formComponents/FormInputProps.ts new file mode 100644 index 0000000..fe89e43 --- /dev/null +++ b/app/components/formComponents/FormInputProps.ts @@ -0,0 +1,289 @@ +import { Control } from "react-hook-form"; +import { SxProps, Theme } from "@mui/material"; +import { AddressState, DonationState, DonorState, OrganizationState, PersonState } from "@/app/types/states"; + +export type MenuItem = { + label: string; + value: string; +}; + +export type CheckBoxItem = { + label: string; + value: boolean; +}; + +export type DonationFormProps = { + donation: DonationState; +}; + +export type DonorFormProps = { + donor: DonorState; + person?: PersonState; + organization?: OrganizationState; + address: AddressState; +}; + +export type AddDonationDonorFormProps = DonationFormProps & DonorFormProps; + +export type FormInputProps = { + name: string; + control?: Control; + label: string; + required?: boolean; + setValue?: any; + readOnly?: boolean; + sx?: SxProps; +}; + +export type FormInputTextProps = FormInputProps & { + maxLength?: number; + fullWidth?: boolean; + multiline?: boolean; + rows?: number; + type?: string; +}; + +export type FormInputSelectProps = FormInputProps & { + menuItems: MenuItem[]; +}; + +export const donorTypes: MenuItem[] = [ + { + label: "Individual", + value: "Individual", + }, + { + label: "Corporate", + value: "Corporate", + }, + { + label: "Foundation", + value: "Foundation", + }, +]; + +export const donorCommPreferences: MenuItem[] = [ + { + label: "Email", + value: "Email", + }, + { + label: "Mail", + value: "Mail", + }, + { + label: "Phone", + value: "Phone", + }, +]; + +export const donorStatuses: MenuItem[] = [ + { + label: "Active", + value: "Active", + }, + { + label: "Lapsed", + value: "Lapsed", + }, + { + label: "Major Donor", + value: "Major Donor", + }, + { + label: "First Time Donor", + value: "First Time Donor", + }, +]; + +export const donorSegments: MenuItem[] = [ + { + label: "High Value Donor", + value: "High Value Donor", + }, + { + label: "Lapsed", + value: "Lapsed", + }, + { + label: "First Time Donor", + value: "First Time Donor", + }, +]; + +export const addressTypes: MenuItem[] = [ + { + label: "Residential", + value: "Residential", + }, + { + label: "Commercial", + value: "Commercial", + }, +]; + +export const statesChoices: MenuItem[] = [ + { value: "AL", label: "AL - Alabama" }, + { value: "AK", label: "AK - Alaska" }, + { value: "AZ", label: "AZ - Arizona" }, + { value: "AR", label: "AR - Arkansas" }, + { value: "CA", label: "CA - California" }, + { value: "CO", label: "CO - Colorado" }, + { value: "CT", label: "CT - Connecticut" }, + { value: "DE", label: "DE - Delaware" }, + { value: "DC", label: "DC - District Of Columbia" }, + { value: "FL", label: "FL - Florida" }, + { value: "GA", label: "GA - Georgia" }, + { value: "HI", label: "HI - Hawaii" }, + { value: "ID", label: "ID - Idaho" }, + { value: "IL", label: "IL - Illinois" }, + { value: "IN", label: "IN - Indiana" }, + { value: "IA", label: "IA - Iowa" }, + { value: "KS", label: "KS - Kansas" }, + { value: "KY", label: "KY - Kentucky" }, + { value: "LA", label: "LA - Louisiana" }, + { value: "ME", label: "ME - Maine" }, + { value: "MD", label: "MD - Maryland" }, + { value: "MA", label: "MA - Massachusetts" }, + { value: "MI", label: "MI - Michigan" }, + { value: "MN", label: "MN - Minnesota" }, + { value: "MS", label: "MS - Mississippi" }, + { value: "MO", label: "MO - Missouri" }, + { value: "MT", label: "MT - Montana" }, + { value: "NE", label: "NE - Nebraska" }, + { value: "NV", label: "NV - Nevada" }, + { value: "NH", label: "NH - New Hampshire" }, + { value: "NJ", label: "NJ - New Jersey" }, + { value: "NM", label: "NM - New Mexico" }, + { value: "NY", label: "NY - New York" }, + { value: "NC", label: "NC - North Carolina" }, + { value: "ND", label: "ND - North Dakota" }, + { value: "OH", label: "OH - Ohio" }, + { value: "OK", label: "OK - Oklahoma" }, + { value: "OR", label: "OR - Oregon" }, + { value: "PA", label: "PA - Pennsylvania" }, + { value: "PR", label: "PR - Puerto Rico" }, + { value: "RI", label: "RI - Rhode Island" }, + { value: "SC", label: "SC - South Carolina" }, + { value: "SD", label: "SD - South Dakota" }, + { value: "TN", label: "TN - Tennessee" }, + { value: "TX", label: "TX - Texas" }, + { value: "UT", label: "UT - Utah" }, + { value: "VT", label: "VT - Vermont" }, + { value: "VI", label: "VI - Virgin Islands" }, + { value: "VA", label: "VA - Virginia" }, + { value: "WA", label: "WA - Washington" }, + { value: "WV", label: "WV - West Virginia" }, + { value: "WI", label: "WI - Wisconsin" }, + { value: "WY", label: "WY - Wyoming" }, +]; + +export const donationTypes: MenuItem[] = [ + { + label: "One-Time", + value: "One-Time", + }, + { + label: "Recurring", + value: "Recurring", + }, + { + label: "Pledge", + value: "Pledge", + }, + { + label: "In-Kind", + value: "In-Kind", + }, +]; + +export const paymentMethods: MenuItem[] = [ + { + label: "Credit Card", + value: "Credit Card", + }, + { + label: "Check", + value: "Check", + }, + { + label: "Bank Transfer", + value: "Bank Transfer", + }, + { + label: "Cash", + value: "Cash", + }, + { + label: "ACH", + value: "ACH", + }, + { + label: "PayPal", + value: "PayPal", + }, + { + label: "Venmo", + value: "Venmo", + }, + { + label: "Zelle", + value: "Zelle", + }, +]; + +export const recurringFrequencies: MenuItem[] = [ + { + label: "None", + value: "None", + }, + { + label: "Monthly", + value: "Monthly", + }, + { + label: "Quarterly", + value: "Quarterly", + }, + { + label: "Annually", + value: "Annually", + }, +]; + +export const donationSources: MenuItem[] = [ + { + label: "Website", + value: "Website", + }, + { + label: "Social Media", + value: "Social Media", + }, + { + label: "Event", + value: "Event", + }, + { + label: "Email", + value: "Email", + }, + { + label: "Direct Mail", + value: "Direct Mail", + }, + { + label: "Referral", + value: "Referral", + }, + { + label: "Other", + value: "Other", + }, +]; + +export const donorModes: MenuItem[] = [ + { label: "Anonymous", value: "Anonymous" }, + { label: "New", value: "New" }, + { label: "Existing", value: "Existing" }, +]; diff --git a/app/components/formComponents/FormInputTextfield.tsx b/app/components/formComponents/FormInputTextfield.tsx new file mode 100644 index 0000000..be11453 --- /dev/null +++ b/app/components/formComponents/FormInputTextfield.tsx @@ -0,0 +1,114 @@ +import { Controller } from "react-hook-form"; +import TextField from "@mui/material/TextField"; +import { FormInputTextProps } from "./FormInputProps"; +import { InputAdornment } from "@mui/material"; + +export const FormInputTextfield = ({ + name, + control, + label, + required, + sx, + maxLength, + fullWidth, + multiline, + rows, + type, + readOnly, +}: FormInputTextProps) => { + return ( + { + const handleZip = (event: React.ChangeEvent) => { + const cursorPosition = event.target.selectionStart; + + if (!isNaN(Number(event.target.value))) { + onChange(Number(event.target.value).toString().slice(0, 5)); + + setTimeout(() => { + event.target.selectionStart = event.target.selectionEnd = + cursorPosition; + }, 0); + } + }; + + const handleCurrency = (event: React.ChangeEvent) => { + const val = event.target.value; + + // Allow only numbers or a period + const num = val.replace(/[^0-9.]/g, ""); + + // Allow only one period + const numSplit = num.split("."); + const formattedNum = + numSplit.length > 2 + ? `${numSplit[0]}.${numSplit.slice(1).join("")}` + : num; + + // Remove leading zero case + if ( + formattedNum.startsWith("0") && + formattedNum.length > 1 && + formattedNum[1] !== "." + ) { + onChange(parseFloat(formattedNum.substring(1))); + return; + } + + // Case of empty string or just period, reset to 0 + if (formattedNum === "" || formattedNum === ".") { + onChange(0); + return; + } + onChange(formattedNum); + }; + + let onChangeHandler; + switch (type) { + case "zip": + onChangeHandler = handleZip; + break; + case "currency": + onChangeHandler = handleCurrency; + break; + default: + onChangeHandler = onChange; + } + + return ( + $ + ) : null, + readOnly: readOnly, + }, + htmlInput: { + ...(maxLength ? { maxLength: maxLength } : {}), + }, + }} + /> + ); + }} + /> + ); +}; diff --git a/app/components/importCSV.tsx b/app/components/importCSV.tsx new file mode 100644 index 0000000..da551cb --- /dev/null +++ b/app/components/importCSV.tsx @@ -0,0 +1,142 @@ +"use client"; +import { Box, Button, TextField } from "@mui/material"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; + +export const Import = () => { + const [file, setFile] = useState(null); + + /* + const { + handleSubmit, + control, + reset, + setValue, + formState: { isDirty, isValid, errors }, + } = useForm({ + mode: "onChange", + defaultValues: { + name: "", + status: "", + amountRequested: "", + amountAwarded: "", + purpose: "", + startDate: "", + endDate: "", + isMultipleYears: "", + quarter: "", + acknowledgementSent: "", + awardNotificationDate: "", + fundingArea: "", + internalProposalDueDate: "", + proposalDueDate: "", + proposalSummary: "", + proposalSubmissionDate: "", + applicationType: "", + internalOwner: "", + fundingRestriction: "", + matchingRequirement: "", + useArea: "", + isEligibleForRenewal: "", + renewalApplicationDate: "", + renewalAwardStatus: "", + //representativeGrant: "", + //grantAttachment: "", + }, + }); +*/ + const handleSubmitFile = async (event: React.FormEvent) => { + event.preventDefault(); + + if (!file) return; + + try { + const formData = new FormData(); + formData.append("csv", file); + + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/csv`, { + method: "POST", + body: formData, + }); + + if (!response.ok) { + const errorData = await response.json(); + const message = errorData?.message || "Something went wrong"; + throw new Error(message); + } + } catch (error) { + alert(error); + console.error(error); + } + }; + + return ( + + + ) => setFile(event.target.files?.[0] || null)} + variant="outlined" + slotProps={{ + htmlInput: { accept: ".csv" }, + }} + /> + + + + +

+ There are specific fields to import to grants. (then donations/donor stuff too...)
+ These are the grant fields for the database schema so far, depending on Kids-U current excel sheet data, you + will need to get their specific column names, and add a default value for anything that their excel sheet does + not cover. +
+
+

+

name

+

status

+

amountRequested

+

amountAwarded

+

purpose

+

startDate

+

endDate

+

isMultipleYears

+

quarter

+

acknowledgementSent

+

awardNotificationDate

+

fundingArea

+

internalProposalDueDate

+

proposalDueDate

+

proposalSummary

+

proposalSubmissionDate

+

applicationType

+

internalOwner

+

fundingRestriction

+

matchingRequirement

+

useArea

+

isEligibleForRenewal

+

renewalApplicationDate

+

renewalAwardStatus

+

representativeGrant

+

grantAttachment

+
+
+ ); +}; + +const styles = { + container: { + p: 4, + display: "flex", + flexDirection: "column", + gap: 2, + }, + uploadContainer: { + p: 4, + display: "flex", + justifyContent: "center", + alignItems: "center", + }, +}; diff --git a/app/globals.css b/app/globals.css index 13c7002..c9016a6 100644 --- a/app/globals.css +++ b/app/globals.css @@ -10,9 +10,16 @@ body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + + html, body { + width: 100%; + overflow-x: hidden; + } code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } + + \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index 75912a4..12a9686 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,6 @@ import MainSidebar from "./components/MainSidebar"; import "./globals.css"; +import TopNavigationBar from "./components/TopNavigationBar"; export const metadata = { title: "KIDSU Donor Volunteer Database", @@ -15,8 +16,12 @@ export default function RootLayout({ -
{children}
+
+ +
{children}
+
); } + diff --git a/app/loading.tsx b/app/loading.tsx new file mode 100644 index 0000000..4a24b4e --- /dev/null +++ b/app/loading.tsx @@ -0,0 +1,16 @@ +import { Box, CircularProgress } from "@mui/material"; + +export default function Loading() { + return ( + + + + ); +} diff --git a/app/page.tsx b/app/page.tsx index 580cc85..ad611fe 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,7 +1,393 @@ +"use client"; +import * as React from "react"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import { ThemeProvider, createTheme } from "@mui/material/styles"; +import { PieChart } from "@mui/x-charts/PieChart"; +import LinearProgress from "@mui/material/LinearProgress/LinearProgress"; + +const theme = createTheme({ + palette: { + primary: { + main: "#FFEAF1", + }, + secondary: { + main: "#FFF2D8", + }, + success: { + main: "#D5FFDE", + }, + info: { + main: "#ECCBFF", + }, + warning: { + main: "#D093FF", + }, + text: { + primary: "#000000", + }, + }, +}); + export default function Home() { return ( -
-

Dashboard/Home Page

-
+ + + {/* Box 1: Total Volunteers */} + + + 250 + + + Total Volunteers + + + + {/* Box 2: Total Donors */} + + + 400 + + + Total Donors + + + + {/* Box 3: Total Grants */} + + + 630 + + + Total Grants + + + + {/* Box 4: Text for Upcoming Events */} + + + Upcoming Events + + + Community/guest speaker event + + + + {/* Box 5: Date or number of days left until event */} + + + In + + + 5 Days + + + + {/* Box 6: Tasks */} + + + Tasks + + + {/* Random tasks */} + + - Follow up with grant applicants. + + + - Schedule next volunteer meeting. + + + - Send thank-you notes to donors. + + + - Review upcoming event logistics. + + + - Update the donor database. + + + - Contact local businesses for potential sponsorships. + + + - Create a flyer for the next charity drive. + + + - Assign roles for the upcoming volunteer event. + + + - Add recent donor contributions to the database. + + + - Analyze volunteer participation trends over the last quarter. + + + - Partner with other non-profits for collaborative events. + + + - Post updates about ongoing campaigns on social media. + + + + + {/* Box 7: Key Metrics */} + + + Key Metrics + + + + + Volunteer Hours Logged + + + 1,200 hrs + + + + + + Average Donation Amount + + + $50 + + + + + + Pending Grant Applications + + + 15 + + + + + {/* Box 8: Campaign Performance */} + + + Campaign Performance + + + + + + {" "} + Medical + + + {" "} + General + + + {" "} + Education + + + {" "} + Clothing + + + {" "} + Holiday Event + + + + + {/* Box 9: Fundraising Progress */} + + + Fundraising Progress + + + $2,000 raised out of $5,000 goal + + + + + ); } diff --git a/app/types/states.ts b/app/types/states.ts new file mode 100644 index 0000000..b465816 --- /dev/null +++ b/app/types/states.ts @@ -0,0 +1,114 @@ +import { Address, Donation, Donor } from "@prisma/client"; + +export type DonorState = { + type: string; + communicationPreference: string; + status: string; + notes: string; + isRetained: boolean; +}; + +export type OrganizationState = { + name: string; + emailAddress: string; +}; + +export type PersonState = { + firstName: string; + lastName: string; + emailAddress: string; + phoneNumber?: string | null; +}; + +export type AddressState = { + addressLine1: string; + addressLine2?: string | null; + city: string; + state: string; + zipCode: string; + type: string; +}; + +export type DonationState = { + type: string; + amount: number; + item?: string | null; + paymentMethod?: string | null; + campaign: string; + fundDesignation: string; + date: Date; + recurringFrequency: string; + source: string; + isMatching: boolean; + taxDeductibleAmount?: number | null; + receiptSent?: boolean | null; + receiptNumber?: string | null; + isAnonymous: boolean; + acknowledgementSent: boolean; +}; + +export type DonationResponse = { + data: Donation & { + donor: { + person: { + firstName: string; + lastName: string; + }; + }; + }; +}; + +export type DonorResponse = { + data: Donor & { + person: { + firstName: string; + lastName: string; + emailAddress: string; + phoneNumber?: string | null; + address?: Address | null; + }; + donation: { + id: string; + type: string; + amount: number; + item?: string | null; + paymentMethod?: string | null; + date: Date; + }[]; + organization: { + name: string; + emailAddress: string; + address?: Address | null; + }; + }; +}; + +export type DonationTableState = { + id: string; + type: string; + amount: number; + item: string; + paymentMethod: string; + date: Date; +}; + +//////// + +export type donorResponse = { + data: Donor & { + person: { + firstName: string; + lastName: string; + phoneNumber: string; + emailAddress: string; + address: Address; + }; + donation: { + id: string; + type: string; + amount: number; + item: string; + paymentMethod: string; + }; + }; +}; diff --git a/app/utils/constituentController.js b/app/utils/constituentController.js deleted file mode 100644 index 0590417..0000000 --- a/app/utils/constituentController.js +++ /dev/null @@ -1,86 +0,0 @@ -const { PrismaClient } = require('@prisma/client'); -const prisma = new PrismaClient(); - -const createConstituent = async (data) => { - try { - const newConstituent = await prisma.constituent.create({ - data: { - FirstName: data.FirstName, - LastName: data.LastName, - StreetAddress: data.StreetAddress, - City: data.City, - State: data.State, - Zipcode: data.Zipcode, - Country: data.Country, - EmailAddress: data.EmailAddress, - PhoneNumber: data.PhoneNumber, - AreaCode: data.AreaCode, - }, - }); - return newConstituent; - } catch (error) { - throw new Error(`Unable to create constituent: ${error}`); - } -}; - -const getConstituents = async () => { - try { - const constituents = await prisma.constituent.findMany(); - return constituents; - } catch (error) { - throw new Error(`Unable to fetch constituents: ${error}`); - } -}; - -const getConstituentById = async (id) => { - try { - const constituent = await prisma.constituent.findUnique({ - where: { ConstituentID: id }, - }); - return constituent; - } catch (error) { - throw new Error(`Unable to fetch constituent: ${error}`); - } -}; - -const updateConstituent = async (id, data) => { - try { - const updatedConstituent = await prisma.constituent.update({ - where: { ConstituentID: id }, - data: { - FirstName: data.FirstName, - LastName: data.LastName, - StreetAddress: data.StreetAddress, - City: data.City, - State: data.State, - Zipcode: data.Zipcode, - Country: data.Country, - EmailAddress: data.EmailAddress, - PhoneNumber: data.PhoneNumber, - AreaCode: data.AreaCode, - }, - }); - return updatedConstituent; - } catch (error) { - throw new Error(`Unable to update constituent: ${error}`); - } -}; - -const deleteConstituent = async (id) => { - try { - await prisma.constituent.delete({ - where: { ConstituentID: id }, - }); - return 'Constituent deleted successfully'; - } catch (error) { - throw new Error(`Unable to delete constituent: ${error}`); - } -}; - -module.exports = { - createConstituent, - getConstituents, - getConstituentById, - updateConstituent, - deleteConstituent, -}; diff --git a/app/utils/db.ts b/app/utils/db.ts new file mode 100644 index 0000000..49b0e2d --- /dev/null +++ b/app/utils/db.ts @@ -0,0 +1,14 @@ +import { PrismaClient } from "@prisma/client"; + +const prismaClientSingleton = () => { + return new PrismaClient(); +}; +declare const globalThis: { + prismaGlobal: ReturnType; +} & typeof global; + +const prisma = globalThis.prismaGlobal ?? prismaClientSingleton(); + +if (process.env.NODE_ENV !== "production") globalThis.prismaGlobal = prisma; + +export default prisma; diff --git a/app/utils/grantorTestData.ts b/app/utils/grantorTestData.ts new file mode 100644 index 0000000..262b3ed --- /dev/null +++ b/app/utils/grantorTestData.ts @@ -0,0 +1,56 @@ +type Grantor = { + id: string; + websiteLink: string | null; + addressId: string; + name: string; + contactTitle: string; + type: string; + communicationPreference: string; + recognitionPreference: string; + internalRelationshipManager: string; + // representative Representative[] + // address Address @relation(fields: [id], references: [id]) +}; + +export const grantors: Grantor[] = [ + { + id: "1", + websiteLink: "www.ron.business", + addressId: "9319 Chisholm Trail", + name: "gonzalooooooo", + contactTitle: "Assistant Manager", + type: "Organization", + communicationPreference: "the telly", + recognitionPreference: "recognizer", + internalRelationshipManager: "Jeanie Aird", + }, + { + id: "2", + websiteLink: "www.utrejects.com", + addressId: "The White House", + name: "Saanvi", + contactTitle: "CEO", + type: "Company", + communicationPreference: "teleprompter", + recognitionPreference: "recognizer", + internalRelationshipManager: "Taz", + }, + +]; + +/* + +model Representative { + id String @id @default(uuid()) + positionTitle String + personId String @unique + grantorId String + person Person @relation(fields: [personId], references: [id]) + grantor Grantor @relation(fields: [grantorId], references: [id]) + representativeGrant RepresentativeGrant[] +} + + + + + }*/ diff --git a/migration_lock.toml b/migration_lock.toml deleted file mode 100644 index fbffa92..0000000 --- a/migration_lock.toml +++ /dev/null @@ -1,3 +0,0 @@ -# Please do not edit this file manually -# It should be added in your version-control system (i.e. Git) -provider = "postgresql" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 03a2d8e..e513667 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,34 +8,40 @@ "name": "next-js-template", "version": "0.1.0", "dependencies": { - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "@mui/material": "^6.1.2", + "@emotion/react": "^11.13.5", + "@emotion/styled": "^11.13.5", + "@mui/icons-material": "^6.1.10", + "@mui/material": "^6.1.9", + "@mui/x-charts": "^7.23.0", "@mui/x-date-pickers": "^7.19.0", - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "@mui/material": "^6.1.5", "@opentelemetry/api": "^1.9.0", "@prisma/client": "^5.12.1", "@types/node": "20.6.5", "@types/react": "18.2.22", "axios": "^1.6.8", + "connect": "^3.7.0", + "cookie": "^0.7.1", + "csv-parse": "^5.6.0", "date-fns": "^4.1.0", "dayjs": "^1.11.13", "eslint": "8.50.0", "eslint-config-next": "13.5.2", - "express": "^4.19.2", - "next": "^15.0.4-canary.19", + "mime": "^4.0.4", + "next": "^15.0.2", "prettier": "^3.3.3", + "qs": "^6.13.0", "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-hook-form": "^7.53.2", "react-router-dom": "^6.27.0", "typescript": "^5.2.2" }, "devDependencies": { "@types/express": "^4.17.21", + "@types/react-text-mask": "^5.4.14", "autoprefixer": "^10.4.19", "postcss": "^8.4.40", - "prisma": "^5.19.1", + "prisma": "^6.0.1", "tailwindcss": "^3.4.7" } }, @@ -67,13 +73,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", - "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.2", - "@babel/types": "^7.26.0", + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -114,172 +120,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.26.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.6", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.26.3" }, "bin": { "parser": "bin/babel-parser.js" @@ -315,16 +161,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", + "@babel/types": "^7.26.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -333,9 +179,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -345,27 +191,17 @@ "node": ">=6.9.0" } }, - "node_modules/@emnapi/runtime": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", - "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@emotion/babel-plugin": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", - "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.2.0", + "@emotion/serialize": "^1.3.3", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", @@ -375,14 +211,14 @@ } }, "node_modules/@emotion/cache": { - "version": "11.13.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", - "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0", "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.0", + "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "stylis": "4.2.0" } @@ -409,17 +245,17 @@ "license": "MIT" }, "node_modules/@emotion/react": { - "version": "11.13.3", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", - "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/cache": "^11.13.0", - "@emotion/serialize": "^1.3.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "hoist-non-react-statics": "^3.3.1" }, @@ -433,15 +269,15 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", - "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", "license": "MIT", "dependencies": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/unitless": "^0.10.0", - "@emotion/utils": "^1.4.1", + "@emotion/utils": "^1.4.2", "csstype": "^3.0.2" } }, @@ -452,17 +288,17 @@ "license": "MIT" }, "node_modules/@emotion/styled": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", - "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", + "@emotion/babel-plugin": "^11.13.5", "@emotion/is-prop-valid": "^1.3.0", - "@emotion/serialize": "^1.3.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0" + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" }, "peerDependencies": { "@emotion/react": "^11.0.0-rc.0", @@ -481,18 +317,18 @@ "license": "MIT" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", - "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", "license": "MIT", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", - "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", "license": "MIT" }, "node_modules/@emotion/weak-memoize": { @@ -501,279 +337,78 @@ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "license": "MIT" }, - "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", - "debug": "^4.3.1", - "globals": "^11.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "engines": { - "node": ">=6.9.0" + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "license": "MIT", "engines": { - "node": ">=4" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@emotion/babel-plugin": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", - "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.2.0", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.13.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", - "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "^0.9.0", - "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.0", - "@emotion/weak-memoize": "^0.4.0", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", - "license": "MIT" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", - "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "^0.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", - "license": "MIT" - }, - "node_modules/@emotion/react": { - "version": "11.13.3", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", - "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/cache": "^11.13.0", - "@emotion/serialize": "^1.3.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0", - "@emotion/weak-memoize": "^0.4.0", - "hoist-non-react-statics": "^3.3.1" + "type-fest": "^0.20.2" }, - "peerDependencies": { - "react": ">=16.8.0" + "engines": { + "node": ">=8" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@emotion/serialize": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", - "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", + "node_modules/@eslint/js": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", + "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", "license": "MIT", - "dependencies": { - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.10.0", - "@emotion/utils": "^1.4.1", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", - "license": "MIT" - }, - "node_modules/@emotion/styled": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", - "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/is-prop-valid": "^1.3.0", - "@emotion/serialize": "^1.3.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0" - }, - "peerDependencies": { - "@emotion/react": "^11.0.0-rc.0", - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/unitless": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", - "license": "MIT" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", - "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", - "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", - "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==", - "license": "MIT" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", - "license": "MIT" - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", - "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { @@ -784,375 +419,33 @@ "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "license": "BSD-3-Clause" - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", - "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", - "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.0.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", - "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", - "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", - "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", - "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", - "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", - "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", - "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", - "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", - "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.0.5" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", - "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", - "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.0.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", - "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.0.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", - "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", - "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.0.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", - "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.2.0" + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node": ">=10.10.0" } }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", - "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "license": "Apache-2.0", "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=12.22" }, "funding": { - "url": "https://opencollective.com/libvips" + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "license": "BSD-3-Clause" + }, "node_modules/@img/sharp-win32-x64": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", @@ -1220,9 +513,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -1268,32 +561,58 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.7.tgz", - "integrity": "sha512-POuIBi80BZBogQkG4PQKIGwy4QFwB+kOr+OI4k7Znh7LqMAIhwB9OC00l6M+w1GrZJYj3T8R5WX8G6QAIvoVEw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.2.0.tgz", + "integrity": "sha512-Nn5PSkUqbDrvezpiiiYZiAbX4SFEiy3CbikUL6pWOXEUsq+L1j50OOyyUIHpaX2Hr+5V5UxTh+fPeC4nsGNhdw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.2.0.tgz", + "integrity": "sha512-WR1EEhGOSvxAsoTSzWZBlrWFjul8wziDrII4rC3PvMBHhBYBqEc2n/0aamfFbwkH5EiYb96aqc6kYY6tB310Sw==", "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^6.2.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@mui/material": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.7.tgz", - "integrity": "sha512-KsjujQL/A2hLd1PV3QboF+W6SSL5QqH6ZlSuQoeYz9r69+TnyBFIevbYLxdjJcJmGBjigL5pfpn7hTGop+vhSg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.2.0.tgz", + "integrity": "sha512-7FXXUPIyYzP02a7GvqwJ7ocmdP+FkvLvmy/uxG1TDmTlsr8nEClQp75uxiVznJqAY/jJy4d+Rj/fNWNxwidrYQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.1.7", - "@mui/system": "^6.1.7", + "@mui/core-downloads-tracker": "^6.2.0", + "@mui/system": "^6.2.0", "@mui/types": "^7.2.19", - "@mui/utils": "^6.1.7", + "@mui/utils": "^6.2.0", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1", - "react-is": "^18.3.1", + "react-is": "^19.0.0", "react-transition-group": "^4.4.5" }, "engines": { @@ -1306,7 +625,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.1.7", + "@mui/material-pigment-css": "^6.2.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1327,13 +646,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.7.tgz", - "integrity": "sha512-uLbfUSsug5K0LVkv0PI6Flste3le8+6WSL2omdTiYde93P89Qr7pKr8TA6d2yXfr+Bm+SvD8/fGnkaRwFkryuQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.2.0.tgz", + "integrity": "sha512-lYd2MrVddhentF1d/cMXKnwlDjr/shbO3A2eGq22PCYUoZaqtAGZMc0U86KnJ/Sh5YzNYePqTOaaowAN8Qea8A==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.1.7", + "@mui/utils": "^6.2.0", "prop-types": "^15.8.1" }, "engines": { @@ -1354,14 +673,14 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.7.tgz", - "integrity": "sha512-Ou4CxN7MQmwrfG1Pu6EYjPgPChQXxPDJrwgizLXlRPOad5qAq4gYXRuzrGQ2DfGjjwmJhjI8T6A0SeapAZPGig==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.2.0.tgz", + "integrity": "sha512-rV4YCu6kcCjMnHFXU/tQcL6XfYVfFVR8n3ZVNGnk2rpXnt/ctOPJsF+eUQuhkHciueLVKpI06+umr1FxWWhVmQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@emotion/cache": "^11.13.1", - "@emotion/serialize": "^1.3.2", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1388,16 +707,16 @@ } }, "node_modules/@mui/system": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.7.tgz", - "integrity": "sha512-qbMGgcC/FodpuRSfjXlEDdbNQaW++eATh0vNBcPUv2/YXSpReoOpoT9FhogxEBNks+aQViDXBRZKh6HX2fVmwg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.2.0.tgz", + "integrity": "sha512-DCeqev9Cd4f4pm3O1lqSGW/DIHHBG6ZpqMX9iIAvN4asYv+pPWv2/lKov9kWk5XThhxFnGSv93SRNE1kNRRg5Q==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.1.7", - "@mui/styled-engine": "^6.1.7", + "@mui/private-theming": "^6.2.0", + "@mui/styled-engine": "^6.2.0", "@mui/types": "^7.2.19", - "@mui/utils": "^6.1.7", + "@mui/utils": "^6.2.0", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1442,17 +761,17 @@ } }, "node_modules/@mui/utils": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.7.tgz", - "integrity": "sha512-Gr7cRZxBoZ0BIa3Xqf/2YaUrBLyNPJvXPQH3OsD9WMZukI/TutibbQBVqLYpgqJn8pKSjbD50Yq2auG0wI1xOw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-77CaFJi+OIi2SjbPwCis8z5DXvE0dfx9hBz5FguZHt1VYFlWEPCWTHcMsQCahSErnfik5ebLsYK8+D+nsjGVfw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", "@mui/types": "^7.2.19", - "@types/prop-types": "^15.7.13", + "@types/prop-types": "^15.7.14", "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-is": "^18.3.1" + "react-is": "^19.0.0" }, "engines": { "node": ">=14.0.0" @@ -1471,47 +790,29 @@ } } }, - "node_modules/@mui/core-downloads-tracker": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.2.tgz", - "integrity": "sha512-1oE4U38/TtzLWRYWEm/m70dUbpcvBx0QvDVg6NtpOmSNQC1Mbx0X/rNvYDdZnn8DIsAiVQ+SZ3am6doSswUQ4g==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - } - }, - "node_modules/@mui/material": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.2.tgz", - "integrity": "sha512-5TtHeAVX9D5d2LYfB1GAUn29BcVETVsrQ76Dwb2SpAfQGW3JVy4deJCAd0RrIkI3eEUrsl0E4xuBdreszxdTTg==", + "node_modules/@mui/x-charts": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-7.23.2.tgz", + "integrity": "sha512-wLeogvQZZtyrAOdG06mDzIQSHBSAB09Uy16AYRUcMxVObi7Fs0i3TJUMpQHMYz1/1DvE1u8zstDgVpVfk8/iCA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.25.6", - "@mui/core-downloads-tracker": "^6.1.2", - "@mui/system": "^6.1.2", - "@mui/types": "^7.2.17", - "@mui/utils": "^6.1.2", - "@popperjs/core": "^2.11.8", - "@types/react-transition-group": "^4.4.11", + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-charts-vendor": "7.20.0", + "@mui/x-internals": "7.23.0", + "@react-spring/rafz": "^9.7.5", + "@react-spring/web": "^9.7.5", "clsx": "^2.1.1", - "csstype": "^3.1.3", - "prop-types": "^15.8.1", - "react-is": "^18.3.1", - "react-transition-group": "^4.4.5" + "prop-types": "^15.8.1" }, "engines": { "node": ">=14.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.1.2", - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1521,180 +822,41 @@ }, "@emotion/styled": { "optional": true - }, - "@mui/material-pigment-css": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/material/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, - "node_modules/@mui/private-theming": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.2.tgz", - "integrity": "sha512-S8WcjZdNdi++8UhrrY8Lton5h/suRiQexvdTfdcPAlbajlvgM+kx+uJstuVIEyTb3gMkxzIZep87knZ0tqcR0g==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.6", - "@mui/utils": "^6.1.2", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/styled-engine": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.2.tgz", - "integrity": "sha512-uKOfWkR23X39xj7th2nyTcCHqInTAXtUnqD3T5qRVdJcOPvu1rlgTleTwJC/FJvWZJBU6ieuTWDhbcx5SNViHQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.6", - "@emotion/cache": "^11.13.1", - "@emotion/sheet": "^1.4.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } - } - }, - "node_modules/@mui/system": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.2.tgz", - "integrity": "sha512-mzW7F1ZMIYS1aLON48Nrk9c65OrVEVQ+R4lUcTWs1lCSul0VGK23eo4dmY0NX5PS7Oe4xz3P5B9tQZZ7SYgxcg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.6", - "@mui/private-theming": "^6.1.2", - "@mui/styled-engine": "^6.1.2", - "@mui/types": "^7.2.17", - "@mui/utils": "^6.1.2", - "clsx": "^2.1.1", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/types": { - "version": "7.2.17", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.17.tgz", - "integrity": "sha512-oyumoJgB6jDV8JFzRqjBo2daUuHpzDjoO/e3IrRhhHo/FxJlaVhET6mcNrKHUq2E+R+q3ql0qAtvQ4rfWHhAeQ==", - "license": "MIT", - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true } } }, - "node_modules/@mui/utils": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.2.tgz", - "integrity": "sha512-6+B1YZ8cCBWD1fc3RjqpclF9UA0MLUiuXhyCO+XowD/Z2ku5IlxeEhHHlgglyBWFGMu4kib4YU3CDsG5/zVjJQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.6", - "@mui/types": "^7.2.17", - "@types/prop-types": "^15.7.13", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^18.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "node_modules/@mui/x-charts-vendor": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts-vendor/-/x-charts-vendor-7.20.0.tgz", + "integrity": "sha512-pzlh7z/7KKs5o0Kk0oPcB+sY0+Dg7Q7RzqQowDQjpy5Slz6qqGsgOB5YUzn0L+2yRmvASc4Pe0914Ao3tMBogg==", + "license": "MIT AND ISC", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@types/d3-color": "^3.1.3", + "@types/d3-delaunay": "^6.0.4", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-scale": "^4.0.8", + "@types/d3-shape": "^3.1.6", + "@types/d3-time": "^3.0.3", + "d3-color": "^3.1.0", + "d3-delaunay": "^6.0.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "d3-time": "^3.1.0", + "delaunator": "^5.0.1", + "robust-predicates": "^3.0.2" } }, - "node_modules/@mui/utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, "node_modules/@mui/x-date-pickers": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.19.0.tgz", - "integrity": "sha512-OIQ+IxgL2Si7DP68sw1ImcHXZtAmklHcyo/oqP4HuJZ2lVnP5sJkoXrksfumL1wjWKJkecONFz3unAqViKXzCQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.23.2.tgz", + "integrity": "sha512-Kt9VsEnShaBKiaastTYku66UIWptgc9UMA16d0G/0TkfIsvZrAD3iacQR6HHAXWspaFshdfsRmW2JAoFhzKZsg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.25.6", - "@mui/utils": "^5.16.6", - "@mui/x-internals": "7.18.0", + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-internals": "7.23.0", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -1717,10 +879,10 @@ "dayjs": "^1.10.7", "luxon": "^3.0.2", "moment": "^2.29.4", - "moment-hijri": "^2.1.2", + "moment-hijri": "^2.1.2 || ^3.0.0", "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -1748,106 +910,34 @@ "optional": true }, "moment-jalaali": { - "optional": true - } - } - }, - "node_modules/@mui/x-date-pickers/node_modules/@mui/utils": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", - "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/types": "^7.2.15", - "@types/prop-types": "^15.7.12", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^18.3.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/x-date-pickers/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, - "node_modules/@mui/x-internals": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.18.0.tgz", - "integrity": "sha512-lzCHOWIR0cAIY1bGrWSprYerahbnH5C31ql/2OWCEjcngL2NAV1M6oKI2Vp4HheqzJ822c60UyWyapvyjSzY/A==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.6", - "@mui/utils": "^5.16.6" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "react": "^17.0.0 || ^18.0.0" + "optional": true + } } }, - "node_modules/@mui/x-internals/node_modules/@mui/utils": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", - "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", + "node_modules/@mui/x-internals": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.23.0.tgz", + "integrity": "sha512-bPclKpqUiJYIHqmTxSzMVZi6MH51cQsn5U+8jskaTlo3J4QiMeCYJn/gn7YbeR9GOZFp8hetyHjoQoVHKRXCig==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/types": "^7.2.15", - "@types/prop-types": "^15.7.12", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^18.3.1" + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/@mui/x-internals/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, "node_modules/@next/env": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.0.4-canary.19.tgz", - "integrity": "sha512-OpioeuVzT9OsXVjefodLQ1B/US5lUlio5dwoJH7NLRXgYqOUBybFDDZOQ+PXzF0f55bFYjsoRFq6YnZzVkj1lA==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.0.tgz", + "integrity": "sha512-UcCO481cROsqJuszPPXJnb7GGuLq617ve4xuAyyNG4VSSocJNtMU5Fsx+Lp6mlN8c7W58aZLc5y6D/2xNmaK+w==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { @@ -1859,122 +949,10 @@ "glob": "7.1.7" } }, - "node_modules/@next/swc-darwin-arm64": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.4-canary.19.tgz", - "integrity": "sha512-n8BF+fPreS7uBUQO/6+F13FVtV/namLoS+9nqIYXL4ZyYVYWfIJKPDbjqoUK8rOnvAlBDoBSXbN9VsmMdW5sQQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.4-canary.19.tgz", - "integrity": "sha512-iDyFGSUuxPeCCOwuo5nj8usUiZXwmtQOM0RpTSO1GAGIeDH49BWWqEYIiRFcS8dhEyDGZNl3SlRS4xmHaeT8cg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.4-canary.19.tgz", - "integrity": "sha512-qV2xF7V1yLuNnDZQ6bkzDuZbUGV7ofYv0Q9IgogPTx2pwChpwSXVK2OQAoU9BqVcIMBThVdVa5ILMWvoG5TfEw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.4-canary.19.tgz", - "integrity": "sha512-nykBD1+5RrtqC5fT87wt3CPx04q8tUKKCixHzdmXIcycEYP+RTEucq04gvEITkHuC6DYg9IOGKeqlQqSugRYWA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.0.4-canary.19.tgz", - "integrity": "sha512-aJFVPeFSdQwQmhBll8XW+e8yrYF0M6AKLUsXOUkAd6XvP1m/8Waps+DNkdMmjI1eD89b+C9SufjP8S1HO+LWgQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.0.4-canary.19.tgz", - "integrity": "sha512-owcSYpr0sLz94LJPgQ1z/FgoFsY40uHMG1nZBD0ar2Cj5/zbeHGzATpLoeg6UWG2M441KBRpeTPvNGIfTEQ4xQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.4-canary.19.tgz", - "integrity": "sha512-dyeltaQ40350j+FExwrlV4YXZnYXQE/SQ17JEQHucOX9lrlUJ/XtwIEJSLSeu+fVjWq5gu6uV6wQejquwECngg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.4-canary.19.tgz", - "integrity": "sha512-dbhxrOJXrE5Z1QTb9iArnc9MZRTinP76vKrxu1yvKHJJ1tXIe8wwpXAmPP4tK4wZ9mnlJIMc8fpuoNla38cFNA==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.0.tgz", + "integrity": "sha512-J1YdKuJv9xcixzXR24Dv+4SaDKc2jj31IVUEMdO5xJivMTXuE6MAdIi4qPjSymHuFG8O5wbfWKnhJUcHHpj5CA==", "cpu": [ "x64" ], @@ -2061,16 +1039,6 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, "node_modules/@prisma/client": { "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.22.0.tgz", @@ -2090,53 +1058,125 @@ } }, "node_modules/@prisma/debug": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", - "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.0.1.tgz", + "integrity": "sha512-jQylgSOf7ibTVxqBacnAlVGvek6fQxJIYCQOeX2KexsfypNzXjJQSS2o5s+Mjj2Np93iSOQUaw6TvPj8syhG4w==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/engines": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz", - "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.0.1.tgz", + "integrity": "sha512-4hxzI+YQIR2uuDyVsDooFZGu5AtixbvM2psp+iayDZ4hRrAHo/YwgA17N23UWq7G6gRu18NvuNMb48qjP3DPQw==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "5.22.0", - "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", - "@prisma/fetch-engine": "5.22.0", - "@prisma/get-platform": "5.22.0" + "@prisma/debug": "6.0.1", + "@prisma/engines-version": "5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e", + "@prisma/fetch-engine": "6.0.1", + "@prisma/get-platform": "6.0.1" } }, "node_modules/@prisma/engines-version": { - "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", - "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==", + "version": "5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e.tgz", + "integrity": "sha512-JmIds0Q2/vsOmnuTJYxY4LE+sajqjYKhLtdOT6y4imojqv5d/aeVEfbBGC74t8Be1uSp0OP8lxIj2OqoKbLsfQ==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz", - "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.0.1.tgz", + "integrity": "sha512-T36bWFVGeGYYSyYOj9d+O9G3sBC+pAyMC+jc45iSL63/Haq1GrYjQPgPMxrEj9m739taXrupoysRedQ+VyvM/Q==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "5.22.0", - "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", - "@prisma/get-platform": "5.22.0" + "@prisma/debug": "6.0.1", + "@prisma/engines-version": "5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e", + "@prisma/get-platform": "6.0.1" } }, "node_modules/@prisma/get-platform": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz", - "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.0.1.tgz", + "integrity": "sha512-zspC9vlxAqx4E6epMPMLLBMED2VD8axDe8sPnquZ8GOsn6tiacWK0oxrGK4UAHYzYUVuMVUApJbdXB2dFpLhvg==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "5.22.0" + "@prisma/debug": "6.0.1" + } + }, + "node_modules/@react-spring/animated": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.5.tgz", + "integrity": "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==", + "license": "MIT", + "dependencies": { + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.5.tgz", + "integrity": "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==", + "license": "MIT", + "dependencies": { + "@react-spring/animated": "~9.7.5", + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.5.tgz", + "integrity": "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==", + "license": "MIT" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.5.tgz", + "integrity": "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==", + "license": "MIT", + "dependencies": { + "@react-spring/rafz": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.5.tgz", + "integrity": "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==", + "license": "MIT" + }, + "node_modules/@react-spring/web": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.5.tgz", + "integrity": "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==", + "license": "MIT", + "dependencies": { + "@react-spring/animated": "~9.7.5", + "@react-spring/core": "~9.7.5", + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/@remix-run/router": { @@ -2167,12 +1207,12 @@ "license": "Apache-2.0" }, "node_modules/@swc/helpers": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", - "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.8.0" } }, "node_modules/@types/body-parser": { @@ -2196,6 +1236,57 @@ "@types/node": "*" } }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -2254,20 +1345,10 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "license": "MIT" }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "license": "MIT" - }, "node_modules/@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "license": "MIT", - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", "license": "MIT" }, "node_modules/@types/qs": { @@ -2295,21 +1376,22 @@ "csstype": "^3.0.2" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", - "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", + "node_modules/@types/react-text-mask": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/@types/react-text-mask/-/react-text-mask-5.4.14.tgz", + "integrity": "sha512-VkQuH+7Ol+ue/EFe9EFqJAmDe3ay5VML29l3aJkdzAriMhiprJOmdAFjZ3jOT6p3+nBgEUHxaQtUgg8k8Sk5wA==", + "dev": true, "license": "MIT", "dependencies": { "@types/react": "*" } }, "node_modules/@types/react-transition-group": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", - "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", "license": "MIT", - "dependencies": { + "peerDependencies": { "@types/react": "*" } }, @@ -2469,19 +1551,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", @@ -2602,12 +1671,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, "node_modules/array-includes": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", @@ -2826,13 +1889,9 @@ } }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -2864,21 +1923,6 @@ "npm": ">=6" } }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2898,52 +1942,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "license": "MIT" - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2955,16 +1953,11 @@ } }, "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", "dependencies": { - "fill-range": "^7.1.1", "fill-range": "^7.1.1" }, "engines": { @@ -3015,38 +2008,45 @@ "node": ">=10.16.0" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "license": "MIT", - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "function-bind": "^1.1.2" }, "engines": { - "node": ">= 0.4", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.2.tgz", + "integrity": "sha512-0lk0PHFe/uz0vl527fG9CgdE9WdafjDbCXvBbs+LUv000TVt2Jjhqbs4Jwm8gz070w8xXyEAxrPOMullsxXeGg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "get-intrinsic": "^1.2.5" }, "engines": { "node": ">= 0.4" @@ -3075,9 +2075,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001680", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", - "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", + "version": "1.0.30001688", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001688.tgz", + "integrity": "sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==", "funding": [ { "type": "opencollective", @@ -3177,15 +2177,6 @@ "node": ">=12.5.0" } }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3243,32 +2234,34 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", "license": "MIT", "dependencies": { - "safe-buffer": "5.2.1" + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.10.0" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", - "engines": { - "node": ">= 0.6" + "dependencies": { + "ms": "2.0.0" } }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/convert-source-map": { @@ -3278,36 +2271,14 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -3324,15 +2295,6 @@ "node": ">=10" } }, - "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -3366,6 +2328,127 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, + "node_modules/csv-parse": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.6.0.tgz", + "integrity": "sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -3440,9 +2523,9 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3463,18 +2546,11 @@ "license": "MIT" }, "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" @@ -3482,9 +2558,6 @@ "engines": { "node": ">= 0.4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3506,6 +2579,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3515,27 +2597,6 @@ "node": ">=0.4.0" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/detect-libc": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", @@ -3594,14 +2655,18 @@ "csstype": "^3.0.2" } }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/eastasianwidth": { @@ -3615,13 +2680,12 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT", "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.63", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.63.tgz", - "integrity": "sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA==", + "version": "1.5.73", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz", + "integrity": "sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==", "dev": true, "license": "ISC" }, @@ -3631,19 +2695,6 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/enhanced-resolve": { "version": "5.17.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", @@ -3666,15 +2717,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-abstract": { "version": "1.23.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz", @@ -3736,34 +2778,10 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -3839,14 +2857,14 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -3869,7 +2887,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT", "license": "MIT" }, "node_modules/escape-string-regexp": { @@ -3966,19 +2983,19 @@ } }, "node_modules/eslint-config-next/node_modules/eslint-import-resolver-typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz", - "integrity": "sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", "license": "ISC", "dependencies": { "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.3.5", + "debug": "^4.3.7", "enhanced-resolve": "^5.15.0", - "eslint-module-utils": "^2.8.1", "fast-glob": "^3.3.2", "get-tsconfig": "^4.7.5", "is-bun-module": "^1.0.2", - "is-glob": "^4.0.3" + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -4313,86 +3330,14 @@ "node": ">=4.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", - "license": "MIT", - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -4474,17 +3419,17 @@ } }, "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~2.0.0", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "engines": { @@ -4500,12 +3445,42 @@ "ms": "2.0.0" } }, + "node_modules/finalhandler/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -4608,15 +3583,6 @@ "node": ">= 6" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -4631,36 +3597,12 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -4698,16 +3640,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -4824,12 +3771,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4878,10 +3825,13 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -4890,9 +3840,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -4943,44 +3893,6 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -5046,13 +3958,13 @@ "node": ">= 0.4" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", "engines": { - "node": ">= 0.10" + "node": ">=12" } }, "node_modules/is-array-buffer": { @@ -5093,12 +4005,15 @@ } }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5118,13 +4033,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.0.tgz", + "integrity": "sha512-kR5g0+dXf/+kXnqI+lu0URKYPKgICtHGGNCDSB10AaUFj3o/HkB3u7WfpRBJGFopxxY0oH3ux7ZsDjLtK7xqvw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5134,9 +4049,9 @@ } }, "node_modules/is-bun-module": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.2.1.tgz", - "integrity": "sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", "license": "MIT", "dependencies": { "semver": "^7.6.3" @@ -5170,11 +4085,13 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -5209,12 +4126,15 @@ } }, "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz", + "integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5291,12 +4211,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.0.tgz", + "integrity": "sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5315,13 +4236,15 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5358,12 +4281,13 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.0.tgz", + "integrity": "sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5373,12 +4297,14 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.0.tgz", + "integrity": "sha512-qS8KkNNXUZ/I+nX6QT8ZS1/Yx0A444yhzdTKxCzKkNjQ9sHErBxJnJAgh+f5YhusYECEcjo4XcyH87hn6+ks0A==", "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bind": "^1.0.7", + "has-symbols": "^1.0.3", + "safe-regex-test": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -5455,16 +4381,17 @@ "license": "ISC" }, "node_modules/iterator.prototype": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", - "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.4.tgz", + "integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==", "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "reflect.getprototypeof": "^1.0.8", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5515,9 +4442,9 @@ } }, "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -5526,18 +4453,6 @@ "node": ">=6" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -5550,12 +4465,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "license": "MIT" }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -5636,13 +4545,16 @@ } }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, "license": "MIT", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { @@ -5691,30 +4603,13 @@ "dev": true, "license": "ISC" }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", + "node_modules/math-intrinsics": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", + "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==", "license": "MIT", "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - }, - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, "node_modules/merge2": { @@ -5726,26 +4621,12 @@ "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "license": "MIT", "dependencies": { - "braces": "^3.0.3", "braces": "^3.0.3", "picomatch": "^2.3.1" }, @@ -5754,16 +4635,18 @@ } }, "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.4.tgz", + "integrity": "sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==", + "funding": [ + "https://github.com/sponsors/broofa" + ], "license": "MIT", "bin": { - "mime": "cli.js" + "mime": "bin/cli.js" }, "engines": { - "node": ">=4" + "node": ">=16" } }, "node_modules/mime-db": { @@ -5837,9 +4720,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -5860,24 +4743,15 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "license": "MIT" }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/next": { - "version": "15.0.4-canary.19", - "resolved": "https://registry.npmjs.org/next/-/next-15.0.4-canary.19.tgz", - "integrity": "sha512-TFYV2o4v8gqti5JNKaUujI1rsPQyNkZ2NZCpcOhme+LlP99yD+IUOibCRvveySNNZuH2pvUzpzJsXMjpZOc9PA==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/next/-/next-15.1.0.tgz", + "integrity": "sha512-QKhzt6Y8rgLNlj30izdMbxAwjHMFANnLwDwZ+WQh5sMhyt4lEBqDK9QpvWHtIM4rINKPoJ8aiRZKg5ULSybVHw==", "license": "MIT", "dependencies": { - "@next/env": "15.0.4-canary.19", + "@next/env": "15.1.0", "@swc/counter": "0.1.3", - "@swc/helpers": "0.5.13", + "@swc/helpers": "0.5.15", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", @@ -5890,22 +4764,22 @@ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.0.4-canary.19", - "@next/swc-darwin-x64": "15.0.4-canary.19", - "@next/swc-linux-arm64-gnu": "15.0.4-canary.19", - "@next/swc-linux-arm64-musl": "15.0.4-canary.19", - "@next/swc-linux-x64-gnu": "15.0.4-canary.19", - "@next/swc-linux-x64-musl": "15.0.4-canary.19", - "@next/swc-win32-arm64-msvc": "15.0.4-canary.19", - "@next/swc-win32-x64-msvc": "15.0.4-canary.19", + "@next/swc-darwin-arm64": "15.1.0", + "@next/swc-darwin-x64": "15.1.0", + "@next/swc-linux-arm64-gnu": "15.1.0", + "@next/swc-linux-arm64-musl": "15.1.0", + "@next/swc-linux-x64-gnu": "15.1.0", + "@next/swc-linux-x64-musl": "15.1.0", + "@next/swc-win32-arm64-msvc": "15.1.0", + "@next/swc-win32-x64-msvc": "15.1.0", "sharp": "^0.33.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "babel-plugin-react-compiler": "*", - "react": "^18.2.0 || 19.0.0-rc-380f5d67-20241113", - "react-dom": "^18.2.0 || 19.0.0-rc-380f5d67-20241113", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "peerDependenciesMeta": { @@ -5952,9 +4826,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true, "license": "MIT" }, @@ -6099,19 +4973,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -6205,30 +5066,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", - "license": "MIT", "engines": { "node": ">= 0.8" } @@ -6283,16 +5125,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "license": "MIT", - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "license": "MIT" - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -6452,19 +5284,6 @@ } } }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/postcss-load-config/node_modules/yaml": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", @@ -6535,9 +5354,9 @@ } }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -6550,20 +5369,20 @@ } }, "node_modules/prisma": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.22.0.tgz", - "integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.0.1.tgz", + "integrity": "sha512-CaMNFHkf+DDq8zq3X/JJsQ4Koy7dyWwwtOKibkT/Am9j/tDxcfbg7+lB1Dzhx18G/+RQCMgjPYB61bhRqteNBQ==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/engines": "5.22.0" + "@prisma/engines": "6.0.1" }, "bin": { "prisma": "build/index.js" }, "engines": { - "node": ">=16.13" + "node": ">=18.18" }, "optionalDependencies": { "fsevents": "2.3.3" @@ -6586,19 +5405,6 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -6615,16 +5421,11 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", + "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6", "side-channel": "^1.0.6" }, "engines": { @@ -6654,32 +5455,6 @@ ], "license": "MIT" }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -6697,7 +5472,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -6706,10 +5480,26 @@ "react": "^18.3.1" } }, + "node_modules/react-hook-form": { + "version": "7.54.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.54.0.tgz", + "integrity": "sha512-PS05+UQy/IdSbJNojBypxAo9wllhHgGmyr8/dyGQcPoiMf3e7Dfb9PWYVRco55bLbxH9S+1yDDJeTdlYCSxO3A==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", + "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==", "license": "MIT" }, "node_modules/react-router": { @@ -6760,22 +5550,6 @@ "react-dom": ">=16.6.0" } }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "license": "BSD-3-Clause", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -6800,18 +5574,19 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz", + "integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", + "dunder-proto": "^1.0.0", + "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" + "gopd": "^1.2.0", + "which-builtin-type": "^1.2.0" }, "engines": { "node": ">= 0.4" @@ -6905,6 +5680,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6929,14 +5710,15 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -6946,26 +5728,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", @@ -6983,19 +5745,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT", - "license": "MIT" - }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -7012,83 +5766,6 @@ "node": ">=10" } }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -7121,13 +5798,6 @@ "node": ">= 0.4" } }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC", - "license": "ISC" - }, "node_modules/sharp": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", @@ -7190,15 +5860,69 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -7255,15 +5979,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -7273,15 +5988,11 @@ "node": ">=0.10.0" } }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "license": "MIT" }, "node_modules/streamsearch": { "version": "1.1.0", @@ -7412,15 +6123,18 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7430,15 +6144,19 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7536,12 +6254,6 @@ "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", "license": "MIT" }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", - "license": "MIT" - }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -7637,9 +6349,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz", - "integrity": "sha512-r4MeXnfBmSOuKUWmXe6h2CcyfzJCEk4F0pptO5jlnYSIViUkVmsawj80N5h2lO3gwcmSb4n3PuN+e+GC1Guylw==", + "version": "3.4.16", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.16.tgz", + "integrity": "sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==", "dev": true, "license": "MIT", "dependencies": { @@ -7652,7 +6364,7 @@ "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.6", - "lilconfig": "^2.1.0", + "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", @@ -7712,21 +6424,11 @@ "node": ">=0.8" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "license": "MIT", - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -7734,20 +6436,10 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "node_modules/ts-api-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", - "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "license": "MIT", "engines": { "node": ">=16" @@ -7805,20 +6497,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", @@ -7853,9 +6531,9 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz", + "integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -7863,7 +6541,8 @@ "for-each": "^0.3.3", "gopd": "^1.0.1", "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.13", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -7873,17 +6552,17 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -7893,9 +6572,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -7925,7 +6604,6 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", - "license": "MIT", "engines": { "node": ">= 0.8" } @@ -7986,15 +6664,6 @@ "node": ">= 0.4.0" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8011,32 +6680,36 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.0.tgz", + "integrity": "sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==", "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.0", + "is-number-object": "^1.1.0", + "is-string": "^1.1.0", + "is-symbol": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-builtin-type": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", - "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.0.tgz", + "integrity": "sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==", "license": "MIT", "dependencies": { + "call-bind": "^1.0.7", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", + "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", "is-regex": "^1.1.4", "is-weakref": "^1.0.2", @@ -8071,9 +6744,9 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz", + "integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", diff --git a/package.json b/package.json index 154ee7e..abc33dc 100644 --- a/package.json +++ b/package.json @@ -10,34 +10,41 @@ "lint": "next lint" }, "dependencies": { - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "@mui/material": "^6.1.5", - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "@mui/material": "^6.1.2", + "@mui/icons-material": "^6.1.10", "@mui/x-date-pickers": "^7.19.0", + "@emotion/react": "^11.13.5", + "@emotion/styled": "^11.13.5", + "@mui/material": "^6.1.9", + "@mui/x-charts": "^7.23.0", "@opentelemetry/api": "^1.9.0", "@prisma/client": "^5.12.1", "@types/node": "20.6.5", "@types/react": "18.2.22", "axios": "^1.6.8", + "csv-parse": "^5.6.0", "date-fns": "^4.1.0", + "connect": "^3.7.0", + "cookie": "^0.7.1", "dayjs": "^1.11.13", "eslint": "8.50.0", "eslint-config-next": "13.5.2", - "express": "^4.19.2", - "next": "^15.0.4-canary.19", + "express": "^4.21.0", + "mime": "^4.0.4", + "next": "^15.0.2", "prettier": "^3.3.3", + "qs": "^6.13.0", "react": "^18.3.1", "react-router-dom": "^6.27.0", + "react-hook-form": "^7.53.2", + "react-dom": "^18.3.1", "typescript": "^5.2.2" }, "devDependencies": { "@types/express": "^4.17.21", + "@types/react-text-mask": "^5.4.14", "autoprefixer": "^10.4.19", "postcss": "^8.4.40", - "prisma": "^5.19.1", + "prisma": "^6.0.1", "tailwindcss": "^3.4.7" } } diff --git a/prisma/index.ts b/prisma/index.ts index 874c25b..66f8df4 100644 --- a/prisma/index.ts +++ b/prisma/index.ts @@ -1,52 +1,73 @@ import { + Person as PPerson, + Organization as POrganization, + User as PUser, + Address as PAddress, Grant as PGrant, + GrantAttachment as PGrantAttachment, Representative as PRepresentative, - Event as PEvent, - VolunteerEvent as PVolunteerEvent, - Organization as POrganization, - Donation as PDonation, - Volunteer as PVolunteer, - Constituent as PConstituent, + Grantor as PGrantor, + RepresentativeGrant as PRepresentativeGrant, Donor as PDonor, -} from '@prisma/client'; + Donation as PDonation +} from "@prisma/client"; + +//import { Donor, Address, Donation } from "@prisma/client"; export type Grant = PGrant & { - Representative: Representative[]; + representativeGrant: RepresentativeGrant[]; + grantAttachment: GrantAttachment[]; }; -export type Representative = PRepresentative & { - Organization: Organization; - Grants: Grant[]; -}; +export type GrantAttachment = PGrantAttachment & { + grantor: Grantor; +} -export type Event = PEvent & { - VolunteersAtteneded: VolunteerEvent[]; +export type Grantor = PGrantor & { + organization: Organization; + representatives: Representative[]; }; -export type VolunteerEvent = PVolunteerEvent & { - Event: Event; - Volunteer: Volunteer; +export type Representative = PRepresentative & { + person: Person; + grantor: Grantor; + representativeGrant: RepresentativeGrant[]; }; -export type Organization = POrganization & { - Representatives: Representative[]; + +export type RepresentativeGrant = PRepresentativeGrant & { + grant: Grant; + representative: Representative; }; export type Donation = PDonation & { - Donor: Donor; -}; + donor: Donor; +} -export type Volunteer = PVolunteer & { - Constituent: Constituent; - VolunteerEvents: VolunteerEvent[]; -}; +export type Donor = PDonor & { + donations: Donation[]; + person: Person; + organization: Organization; +} -export type Constituent = PConstituent & { - Donors: Donor[]; - Volunteers: Volunteer[]; +export type Organization = POrganization & { + grantor: Grantor; + address: Address; + donor: Donor; }; -export type Donor = PDonor & { - Constituent: Constituent; - Donations: Donation[]; +export type Person = PPerson & { + donor: Donor; + representative: Representative; + address: Address; + user: User; }; + +export type User = PUser & { + person: Person; +} + +export type Address = PAddress & { + person: Person; + organization: Organization; +} diff --git a/prisma/migrations/20240911210846_/migration.sql b/prisma/migrations/20240911210846_/migration.sql deleted file mode 100644 index 1df48cc..0000000 --- a/prisma/migrations/20240911210846_/migration.sql +++ /dev/null @@ -1,54 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `GrantDueDate` on the `Grant` table. All the data in the column will be lost. - - The primary key for the `Representative` table will be changed. If it partially fails, the table could be left without primary key constraint. - - You are about to drop the column `RepresentativeEmail` on the `Representative` table. All the data in the column will be lost. - - You are about to drop the column `RepresentativeFirstName` on the `Representative` table. All the data in the column will be lost. - - You are about to drop the column `RepresentativeID` on the `Representative` table. All the data in the column will be lost. - - You are about to drop the column `RepresentativeLastName` on the `Representative` table. All the data in the column will be lost. - - You are about to drop the column `RepresentativePhone` on the `Representative` table. All the data in the column will be lost. - - A unique constraint covering the columns `[Email]` on the table `Representative` will be added. If there are existing duplicate values, this will fail. - - A unique constraint covering the columns `[Phone]` on the table `Representative` will be added. If there are existing duplicate values, this will fail. - - Added the required column `DueDate` to the `Grant` table without a default value. This is not possible if the table is not empty. - - Added the required column `Email` to the `Representative` table without a default value. This is not possible if the table is not empty. - - Added the required column `FirstName` to the `Representative` table without a default value. This is not possible if the table is not empty. - - The required column `ID` was added to the `Representative` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. - - Added the required column `LastName` to the `Representative` table without a default value. This is not possible if the table is not empty. - -*/ --- DropForeignKey -ALTER TABLE "_GrantToRepresentative" DROP CONSTRAINT "_GrantToRepresentative_B_fkey"; - --- DropIndex -DROP INDEX "Representative_RepresentativeEmail_key"; - --- DropIndex -DROP INDEX "Representative_RepresentativePhone_key"; - --- AlterTable -ALTER TABLE "Grant" DROP COLUMN "GrantDueDate", -ADD COLUMN "DueDate" TIMESTAMP(3) NOT NULL; - --- AlterTable -ALTER TABLE "Representative" DROP CONSTRAINT "Representative_pkey", -DROP COLUMN "RepresentativeEmail", -DROP COLUMN "RepresentativeFirstName", -DROP COLUMN "RepresentativeID", -DROP COLUMN "RepresentativeLastName", -DROP COLUMN "RepresentativePhone", -ADD COLUMN "Email" TEXT NOT NULL, -ADD COLUMN "FirstName" TEXT NOT NULL, -ADD COLUMN "ID" TEXT NOT NULL, -ADD COLUMN "LastName" TEXT NOT NULL, -ADD COLUMN "Phone" TEXT, -ADD CONSTRAINT "Representative_pkey" PRIMARY KEY ("ID"); - --- CreateIndex -CREATE UNIQUE INDEX "Representative_Email_key" ON "Representative"("Email"); - --- CreateIndex -CREATE UNIQUE INDEX "Representative_Phone_key" ON "Representative"("Phone"); - --- AddForeignKey -ALTER TABLE "_GrantToRepresentative" ADD CONSTRAINT "_GrantToRepresentative_B_fkey" FOREIGN KEY ("B") REFERENCES "Representative"("ID") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20240920195955_/migration.sql b/prisma/migrations/20240920195955_/migration.sql deleted file mode 100644 index 80eae56..0000000 --- a/prisma/migrations/20240920195955_/migration.sql +++ /dev/null @@ -1,184 +0,0 @@ --- CreateTable -CREATE TABLE "Constituent" ( - "ConstituentID" TEXT NOT NULL, - "FirstName" TEXT NOT NULL, - "LastName" TEXT NOT NULL, - "StreetAddress" TEXT NOT NULL, - "City" TEXT NOT NULL, - "State" TEXT NOT NULL, - "Zipcode" TEXT NOT NULL, - "Country" TEXT NOT NULL, - "EmailAddress" TEXT NOT NULL, - "PhoneNumber" TEXT, - "AreaCode" TEXT, - - CONSTRAINT "Constituent_pkey" PRIMARY KEY ("ConstituentID") -); - --- CreateTable -CREATE TABLE "Volunteer" ( - "VolunteerID" TEXT NOT NULL, - "DOB" TIMESTAMP(3) NOT NULL, - "Age" INTEGER NOT NULL, - "EmergencyContact" TEXT, - "EventsAttended" TEXT[], - "AgreementToMediaUse" BOOLEAN, - "TrainingCompletion" TEXT, - "BackgroundCheckCompletion" BOOLEAN, - "IsOverEighteen" BOOLEAN, - "ConstituentID" TEXT NOT NULL, - - CONSTRAINT "Volunteer_pkey" PRIMARY KEY ("VolunteerID") -); - --- CreateTable -CREATE TABLE "Donor" ( - "DonorID" TEXT NOT NULL, - "ContactPreference" TEXT, - "NotesResources" TEXT, - "ConstituentID" TEXT NOT NULL, - - CONSTRAINT "Donor_pkey" PRIMARY KEY ("DonorID") -); - --- CreateTable -CREATE TABLE "Donation" ( - "DonationID" TEXT NOT NULL, - "AmountDonated" DOUBLE PRECISION NOT NULL, - "DateReceived" TIMESTAMP(3) NOT NULL, - "FundingAreas" TEXT[], - "KidsUPrograms" TEXT[], - "DueDate" TIMESTAMP(3), - "DonorID" TEXT NOT NULL, - - CONSTRAINT "Donation_pkey" PRIMARY KEY ("DonationID") -); - --- CreateTable -CREATE TABLE "Organization" ( - "OrganizationID" TEXT NOT NULL, - "WebsiteForFunder" TEXT, - "StreetAddress" TEXT NOT NULL, - "City" TEXT NOT NULL, - "State" TEXT NOT NULL, - "Zipcode" TEXT NOT NULL, - "Country" TEXT NOT NULL, - "OrganizationName" TEXT NOT NULL, - "PortalForGrantApplication" TEXT, - "NotesAboutLoginInfo" TEXT, - - CONSTRAINT "Organization_pkey" PRIMARY KEY ("OrganizationID") -); - --- CreateTable -CREATE TABLE "Representative" ( - "ID" TEXT NOT NULL, - "FirstName" TEXT NOT NULL, - "LastName" TEXT NOT NULL, - "Email" TEXT NOT NULL, - "Phone" TEXT, - "PositionInCompany" TEXT NOT NULL, - "OrganizationID" TEXT NOT NULL, - - CONSTRAINT "Representative_pkey" PRIMARY KEY ("ID") -); - --- CreateTable -CREATE TABLE "Grant" ( - "GrantID" TEXT NOT NULL, - "GrantName" TEXT NOT NULL, - "AwardStatus" TEXT NOT NULL, - "GrantDueDate" TIMESTAMP(3) NOT NULL, - "ContactType" TEXT NOT NULL, - "FundingAreas" TEXT[], - "KidsUProgram" TEXT[], - "GrantOpeningDates" TIMESTAMP(3)[], - "AskDate" TIMESTAMP(3), - "AwardDate" TIMESTAMP(3), - "ReportingDates" TIMESTAMP(3)[], - "TypeOfReporting" TEXT, - "DateToReapplyForGrant" TIMESTAMP(3), - "WaitingPeriodToReapply" INTEGER, - "FundingRestrictions" TEXT, - "AskAmount" DOUBLE PRECISION NOT NULL, - "AmountAwarded" DOUBLE PRECISION NOT NULL, - "EndOfGrantReportDueDate" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Grant_pkey" PRIMARY KEY ("GrantID") -); - --- CreateTable -CREATE TABLE "Event" ( - "EventID" TEXT NOT NULL, - "NameOfEvent" TEXT NOT NULL, - "Date" TIMESTAMP(3) NOT NULL, - "Time" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "Event_pkey" PRIMARY KEY ("EventID") -); - --- CreateTable -CREATE TABLE "VolunteerEvent" ( - "ID" TEXT NOT NULL, - "VolunteerID" TEXT NOT NULL, - "EventID" TEXT NOT NULL, - "LoginTime" TIMESTAMP(3) NOT NULL, - "LogoutTime" TIMESTAMP(3) NOT NULL, - "LoggedHours" INTEGER NOT NULL, - - CONSTRAINT "VolunteerEvent_pkey" PRIMARY KEY ("ID") -); - --- CreateTable -CREATE TABLE "_GrantToRepresentative" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL -); - --- CreateIndex -CREATE UNIQUE INDEX "Constituent_EmailAddress_key" ON "Constituent"("EmailAddress"); - --- CreateIndex -CREATE UNIQUE INDEX "Constituent_PhoneNumber_key" ON "Constituent"("PhoneNumber"); - --- CreateIndex -CREATE UNIQUE INDEX "Organization_OrganizationName_key" ON "Organization"("OrganizationName"); - --- CreateIndex -CREATE UNIQUE INDEX "Representative_Email_key" ON "Representative"("Email"); - --- CreateIndex -CREATE UNIQUE INDEX "Representative_Phone_key" ON "Representative"("Phone"); - --- CreateIndex -CREATE UNIQUE INDEX "Grant_GrantName_key" ON "Grant"("GrantName"); - --- CreateIndex -CREATE UNIQUE INDEX "_GrantToRepresentative_AB_unique" ON "_GrantToRepresentative"("A", "B"); - --- CreateIndex -CREATE INDEX "_GrantToRepresentative_B_index" ON "_GrantToRepresentative"("B"); - --- AddForeignKey -ALTER TABLE "Volunteer" ADD CONSTRAINT "Volunteer_ConstituentID_fkey" FOREIGN KEY ("ConstituentID") REFERENCES "Constituent"("ConstituentID") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Donor" ADD CONSTRAINT "Donor_ConstituentID_fkey" FOREIGN KEY ("ConstituentID") REFERENCES "Constituent"("ConstituentID") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Donation" ADD CONSTRAINT "Donation_DonorID_fkey" FOREIGN KEY ("DonorID") REFERENCES "Donor"("DonorID") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Representative" ADD CONSTRAINT "Representative_OrganizationID_fkey" FOREIGN KEY ("OrganizationID") REFERENCES "Organization"("OrganizationID") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "VolunteerEvent" ADD CONSTRAINT "VolunteerEvent_EventID_fkey" FOREIGN KEY ("EventID") REFERENCES "Event"("EventID") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "VolunteerEvent" ADD CONSTRAINT "VolunteerEvent_VolunteerID_fkey" FOREIGN KEY ("VolunteerID") REFERENCES "Volunteer"("VolunteerID") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_GrantToRepresentative" ADD CONSTRAINT "_GrantToRepresentative_A_fkey" FOREIGN KEY ("A") REFERENCES "Grant"("GrantID") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_GrantToRepresentative" ADD CONSTRAINT "_GrantToRepresentative_B_fkey" FOREIGN KEY ("B") REFERENCES "Representative"("ID") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20241212180625_/migration.sql b/prisma/migrations/20241212180625_/migration.sql new file mode 100644 index 0000000..bd49353 --- /dev/null +++ b/prisma/migrations/20241212180625_/migration.sql @@ -0,0 +1,223 @@ +-- CreateEnum +CREATE TYPE "Role" AS ENUM ('VOLUNTEER', 'ADMIN'); + +-- CreateTable +CREATE TABLE "Person" ( + "id" TEXT NOT NULL, + "firstName" TEXT NOT NULL, + "lastName" TEXT NOT NULL, + "emailAddress" TEXT NOT NULL, + "phoneNumber" TEXT, + + CONSTRAINT "Person_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Organization" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "emailAddress" TEXT, + + CONSTRAINT "Organization_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "User" ( + "id" TEXT NOT NULL, + "role" "Role" NOT NULL, + "personId" TEXT, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Address" ( + "id" TEXT NOT NULL, + "addressLine1" TEXT NOT NULL, + "addressLine2" TEXT, + "city" TEXT NOT NULL, + "state" TEXT NOT NULL, + "zipCode" TEXT NOT NULL, + "type" TEXT NOT NULL, + "personId" TEXT, + "organizationId" TEXT, + + CONSTRAINT "Address_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Grantor" ( + "id" TEXT NOT NULL, + "type" TEXT NOT NULL, + "websiteLink" TEXT, + "communicationPreference" TEXT NOT NULL, + "recognitionPreference" TEXT NOT NULL, + "internalRelationshipManager" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Grantor_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Representative" ( + "id" TEXT NOT NULL, + "positionTitle" TEXT NOT NULL, + "personId" TEXT NOT NULL, + "grantorId" TEXT NOT NULL, + + CONSTRAINT "Representative_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Grant" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "status" TEXT NOT NULL, + "amountRequested" DOUBLE PRECISION NOT NULL, + "amountAwarded" DOUBLE PRECISION NOT NULL DEFAULT 0, + "purpose" TEXT NOT NULL, + "startDate" TIMESTAMP(3) NOT NULL, + "endDate" TIMESTAMP(3) NOT NULL, + "isMultipleYears" BOOLEAN NOT NULL, + "quarter" TEXT NOT NULL, + "acknowledgementSent" BOOLEAN NOT NULL, + "awardNotificationDate" TIMESTAMP(3), + "fundingArea" TEXT NOT NULL, + "internalProposalDueDate" TIMESTAMP(3), + "proposalDueDate" TIMESTAMP(3) NOT NULL, + "proposalSummary" TEXT, + "proposalSubmissionDate" TIMESTAMP(3), + "applicationType" TEXT NOT NULL, + "internalOwner" TEXT NOT NULL, + "fundingRestriction" TEXT, + "matchingRequirement" TEXT, + "useArea" TEXT NOT NULL, + "isEligibleForRenewal" BOOLEAN NOT NULL, + "renewalApplicationDate" TIMESTAMP(3), + "renewalAwardStatus" TEXT, + + CONSTRAINT "Grant_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "GrantAttachment" ( + "id" TEXT NOT NULL, + "grantId" TEXT NOT NULL, + "document" TEXT NOT NULL, + + CONSTRAINT "GrantAttachment_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "RepresentativeGrant" ( + "grantId" TEXT NOT NULL, + "representativeId" TEXT NOT NULL, + + CONSTRAINT "RepresentativeGrant_pkey" PRIMARY KEY ("grantId","representativeId") +); + +-- CreateTable +CREATE TABLE "Donor" ( + "id" TEXT NOT NULL, + "type" TEXT NOT NULL, + "communicationPreference" TEXT NOT NULL, + "status" TEXT NOT NULL, + "notes" TEXT NOT NULL, + "isRetained" BOOLEAN NOT NULL, + "personId" TEXT, + "organizationId" TEXT, + + CONSTRAINT "Donor_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Donation" ( + "id" TEXT NOT NULL, + "type" TEXT NOT NULL, + "amount" DOUBLE PRECISION NOT NULL, + "item" TEXT, + "paymentMethod" TEXT, + "campaign" TEXT, + "fundDesignation" TEXT NOT NULL, + "recurringFrequency" TEXT, + "date" TIMESTAMP(3) NOT NULL, + "source" TEXT NOT NULL, + "isMatching" BOOLEAN NOT NULL, + "taxDeductibleAmount" DOUBLE PRECISION, + "receiptSent" BOOLEAN, + "receiptNumber" TEXT, + "isAnonymous" BOOLEAN NOT NULL, + "acknowledgementSent" BOOLEAN NOT NULL, + "donorId" TEXT, + + CONSTRAINT "Donation_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Person_emailAddress_key" ON "Person"("emailAddress"); + +-- CreateIndex +CREATE UNIQUE INDEX "Person_phoneNumber_key" ON "Person"("phoneNumber"); + +-- CreateIndex +CREATE UNIQUE INDEX "Organization_emailAddress_key" ON "Organization"("emailAddress"); + +-- CreateIndex +CREATE UNIQUE INDEX "User_personId_key" ON "User"("personId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Address_personId_key" ON "Address"("personId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Address_organizationId_key" ON "Address"("organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Grantor_organizationId_key" ON "Grantor"("organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Representative_personId_key" ON "Representative"("personId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Grant_name_key" ON "Grant"("name"); + +-- CreateIndex +CREATE UNIQUE INDEX "Donor_personId_key" ON "Donor"("personId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Donor_organizationId_key" ON "Donor"("organizationId"); + +-- AddForeignKey +ALTER TABLE "User" ADD CONSTRAINT "User_personId_fkey" FOREIGN KEY ("personId") REFERENCES "Person"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Address" ADD CONSTRAINT "Address_personId_fkey" FOREIGN KEY ("personId") REFERENCES "Person"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Address" ADD CONSTRAINT "Address_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Grantor" ADD CONSTRAINT "Grantor_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Representative" ADD CONSTRAINT "Representative_personId_fkey" FOREIGN KEY ("personId") REFERENCES "Person"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Representative" ADD CONSTRAINT "Representative_grantorId_fkey" FOREIGN KEY ("grantorId") REFERENCES "Grantor"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "GrantAttachment" ADD CONSTRAINT "GrantAttachment_grantId_fkey" FOREIGN KEY ("grantId") REFERENCES "Grant"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "RepresentativeGrant" ADD CONSTRAINT "RepresentativeGrant_grantId_fkey" FOREIGN KEY ("grantId") REFERENCES "Grant"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "RepresentativeGrant" ADD CONSTRAINT "RepresentativeGrant_representativeId_fkey" FOREIGN KEY ("representativeId") REFERENCES "Representative"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Donor" ADD CONSTRAINT "Donor_personId_fkey" FOREIGN KEY ("personId") REFERENCES "Person"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Donor" ADD CONSTRAINT "Donor_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Donation" ADD CONSTRAINT "Donation_donorId_fkey" FOREIGN KEY ("donorId") REFERENCES "Donor"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6248b9a..fcd89ee 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -18,9 +18,9 @@ model Person { lastName String emailAddress String @unique phoneNumber String? @unique + address Address? donor Donor? representative Representative? - address Address? user User? } @@ -40,148 +40,17 @@ model User { person Person? @relation(fields: [personId], references: [id]) } -//volunteer database information -model Volunteer { - id String @id @default(uuid()) - ssn String @unique - username String - password String - firstName String - lastName String - emailAddress String @unique - phoneNumber String? @unique - preferredName String? - addressLine String - city String - state String - zipCode String - usCitizen Boolean - driversLicense Boolean - reliableTransport Boolean - speakSpanish Boolean - emergencyContact EmergencyContact? - referenceName String - volunteerAttendances VolunteerAttendance[] - eventRegistrations EventRegistration[] - mailRecipients MailRecipient[] - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt -} - -model EmergencyContact { - id String @id @default(uuid()) - name String - relationship String - phoneNumber String - volunteerId String @unique - volunteer Volunteer @relation(fields: [volunteerId], references: [id]) -} - -model VolunteerAttendance { - id String @id @default(uuid()) - hoursWorked Float - checkInTime DateTime - checkOutTime DateTime - volunteerId String - volunteer Volunteer @relation(fields: [volunteerId], references: [id]) - eventId String - event Event @relation(fields: [eventId], references: [id]) -} - -model Event { - id String @id @default(uuid()) - name String - schedule DateTime - description String - locationId String - location Location @relation(fields: [locationId], references: [id]) - volunteerAttendances VolunteerAttendance[] - eventRegistrations EventRegistration[] -} - -model EventRegistration { - id String @id @default(uuid()) - eventGroup String - date DateTime - referrelSource String - reasonForVolunteering String - eSignature String - volunteerId String - volunteer Volunteer @relation(fields: [volunteerId], references: [id]) - eventId String - event Event @relation(fields: [eventId], references: [id]) -} - -model Location { - id String @id @default(uuid()) - name String - address String - city String - state String - zipCode String - phoneNumber String - emailAddress String - hours String - events Event[] - admins Admin[] -} +//Volunteer profile and Admin profile -model Admin { - id String @id @default(uuid()) - username String - password String - firstName String - lastName String - locationId String - location Location @relation(fields: [locationId], references: [id]) - mails Mail[] -} - -model Mail { - id String @id @default(uuid()) - subjectLine String - body String - creationDateTime DateTime - scheduledDateTime DateTime - attachments String[] // Changed to array of strings - adminId String - admin Admin @relation(fields: [adminId], references: [id]) - mailRecipients MailRecipient[] -} - -model MailRecipient { - id String @id @default(uuid()) - recipientType RecipientType - deliveryStatus DeliveryStatus - volunteerId String - volunteer Volunteer @relation(fields: [volunteerId], references: [id]) - mailId String - mail Mail @relation(fields: [mailId], references: [id]) -} - -enum RecipientType { - PRIMARY - CC - BCC -} - -enum DeliveryStatus { - PENDING - SENT - FAILED -} - -//donor grant database information model Address { id String @id @default(uuid()) addressLine1 String - addressLine2 String + addressLine2 String? city String state String zipCode String type String personId String? @unique - grantorId String? @unique organizationId String? @unique person Person? @relation(fields: [personId], references: [id]) organization Organization? @relation(fields: [organizationId], references: [id]) @@ -222,20 +91,20 @@ model Grant { isMultipleYears Boolean quarter String acknowledgementSent Boolean - awardNotificationDate DateTime + awardNotificationDate DateTime? fundingArea String //specific area or general internalProposalDueDate DateTime? proposalDueDate DateTime - proposalSummary String - proposalSubmissionDate DateTime + proposalSummary String? + proposalSubmissionDate DateTime? applicationType String internalOwner String fundingRestriction String? matchingRequirement String? useArea String //specific area or general isEligibleForRenewal Boolean - renewalApplicationDate DateTime - renewalAwardStatus String + renewalApplicationDate DateTime? + renewalAwardStatus String? representativeGrant RepresentativeGrant[] grantAttachment GrantAttachment[] } @@ -264,10 +133,10 @@ model Donor { status String notes String isRetained Boolean - personId String? @unique - organizationId String? @unique donation Donation[] + personId String? @unique person Person? @relation(fields: [personId], references: [id]) + organizationId String? @unique organization Organization? @relation(fields: [organizationId], references: [id]) } @@ -278,16 +147,16 @@ model Donation { item String? paymentMethod String? campaign String? - date DateTime fundDesignation String - recurringFrequency String + recurringFrequency String? + date DateTime source String isMatching Boolean - receiptSent Boolean - receiptNumber String @default(uuid()) - taxDeductableAmount Float + taxDeductibleAmount Float? + receiptSent Boolean? + receiptNumber String? @default(uuid()) isAnonymous Boolean acknowledgementSent Boolean - donorId String - donor Donor @relation(fields: [donorId], references: [id]) + donorId String? + donor Donor? @relation(fields: [donorId], references: [id]) } diff --git a/test.js b/test.js deleted file mode 100644 index a7754de..0000000 --- a/test.js +++ /dev/null @@ -1,184 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (g && (g = 0, op[0] && (_ = 0)), _) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; -Object.defineProperty(exports, "__esModule", { value: true }); -var client_1 = require("@prisma/client"); -var prisma = new client_1.PrismaClient(); -// Make sure to empty database before using. -function main() { - return __awaiter(this, void 0, void 0, function () { - var createManyGrants; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, prisma.grant.createMany({ - data: [ - { GrantName: "Mock Grant One", - FundingAreas: ["Education"], - KidsUProgram: ["Afterschool Tutoring"], - FundingRestrictions: "None", - ContactType: "Email Grant", - GrantOpeningDates: [new Date("2023-01-01"), new Date("2023-02-01"), new Date("2023-03-01")], - EndOfGrantReportDueDate: new Date("2025-01-31"), - GrantDueDate: new Date("2024-09-15"), - AskDate: new Date("2023-06-15"), - AwardDate: null, - ReportingDates: [new Date("2024-01-15"), new Date("2024-07-15")], - TypeOfReporting: "Quarterly", - DateToReapplyForGrant: new Date("2025-06-01"), - WaitingPeriodToReapply: 2, - AskAmount: 50000.00, - AwardStatus: "Declined", - AmountAwarded: 0.00 }, - { GrantName: "Mock Grant Two", - FundingAreas: ["Education"], - KidsUProgram: ["Youth Empowerment"], - FundingRestrictions: "None", - ContactType: "Email Grant", - GrantOpeningDates: [new Date("2023-04-01"), new Date("2023-05-01"), new Date("2023-06-01")], - EndOfGrantReportDueDate: new Date("2025-03-31"), - GrantDueDate: new Date("2026-04-06"), - AskDate: new Date("2023-07-15"), - AwardDate: null, - ReportingDates: [new Date("2024-04-15"), new Date("2024-10-15")], - TypeOfReporting: "Biannually", - DateToReapplyForGrant: new Date("2025-07-01"), - WaitingPeriodToReapply: 3, - AskAmount: 6500.00, - AwardStatus: "Pending", - AmountAwarded: 0.00, }, - { GrantName: "Mock Grant Three", - FundingAreas: ["Education"], - KidsUProgram: ["After School Tutoring"], - FundingRestrictions: "A mock restriction", - ContactType: "John Smith", - GrantOpeningDates: [new Date("2000-08-12"), new Date("2001-05-01"), new Date("2023-06-01")], - EndOfGrantReportDueDate: new Date("2007-09-23"), - GrantDueDate: new Date("2008-02-17"), - AskDate: new Date("2001-08-15"), - AwardDate: new Date("2001-06-01"), - ReportingDates: [new Date("2004-04-01"), new Date("2005-10-15")], - TypeOfReporting: "Yearly", - DateToReapplyForGrant: new Date("2009-12-01"), - WaitingPeriodToReapply: 2, - AskAmount: 16500.00, - AwardStatus: "Accepted", - AmountAwarded: 1000.00, }, - { GrantName: "Mock Grant Four", - FundingAreas: ["Education"], - KidsUProgram: ["Youth Empowerment"], - FundingRestrictions: "None", - ContactType: "Email Grant", - GrantOpeningDates: [new Date("2030-06-24"), new Date("2035-07-21"), new Date("2040-08-16")], - EndOfGrantReportDueDate: new Date("2040-12-20"), - GrantDueDate: new Date("2040-12-21"), - AskDate: new Date("2031-07-16"), - AwardDate: new Date("2031-10-24"), - ReportingDates: [new Date("2035-04-15"), new Date("2037-11-15")], - TypeOfReporting: "Biannually", - DateToReapplyForGrant: new Date("2045-07-25"), - WaitingPeriodToReapply: 3, - AskAmount: 30000.00, - AwardStatus: "Accepted", - AmountAwarded: 15000.00 }, - { GrantName: "Mock Grant Five", - FundingAreas: ["Education"], - KidsUProgram: ["Marketing Video"], - FundingRestrictions: "None", - ContactType: "Company Website", - GrantOpeningDates: [new Date("2026-05-01"), new Date("2027-06-01"), new Date("2028-07-01")], - EndOfGrantReportDueDate: new Date("2028-04-31"), - GrantDueDate: new Date("2029-05-05"), - AskDate: new Date("2026-08-25"), - AwardDate: null, - ReportingDates: [new Date("2027-04-25"), new Date("2027-10-25")], - TypeOfReporting: "Biannually", - DateToReapplyForGrant: new Date("2028-07-30"), - WaitingPeriodToReapply: 1, - AskAmount: 20000.00, - AwardStatus: "Pending", - AmountAwarded: 0.00, }, - { GrantName: "Mock Grant Six", - FundingAreas: ["Education"], - KidsUProgram: ["New Site"], - FundingRestrictions: "None", - ContactType: "Email Grant", - GrantOpeningDates: [new Date("2010-10-10"), new Date("2011-11-11"), new Date("2012-12-12")], - EndOfGrantReportDueDate: new Date("2013-01-13"), - GrantDueDate: new Date("2014-02-14"), - AskDate: new Date("2010-09-09"), - AwardDate: null, - ReportingDates: [new Date("2011-05-05"), new Date("2012-06-06")], - TypeOfReporting: "Quarterly", - DateToReapplyForGrant: new Date("2014-03-14"), - WaitingPeriodToReapply: 5, - AskAmount: 18000.00, - AwardStatus: "Declined", - AmountAwarded: 0.00, }, - { GrantName: "Mock Grant Seven", - FundingAreas: ["Education"], - KidsUProgram: ["After School Tutoring"], - FundingRestrictions: "Another mock restriction", - ContactType: "Jane Doe", - GrantOpeningDates: [new Date("2008-04-16"), new Date("2009-06-18"), new Date("2010-08-20")], - EndOfGrantReportDueDate: new Date("2012-12-24"), - GrantDueDate: new Date("2014-02-14"), - AskDate: new Date("2008-09-05"), - AwardDate: new Date("2009-08-16"), - ReportingDates: [new Date("2009-05-05"), new Date("2010-06-06")], - TypeOfReporting: "Biannually", - DateToReapplyForGrant: new Date("2015-09-23"), - WaitingPeriodToReapply: 2, - AskAmount: 13500.00, - AwardStatus: "Awarded", - AmountAwarded: 10000.00, } - ] - })]; - case 1: - createManyGrants = _a.sent(); - return [2 /*return*/]; - } - }); - }); -} -main() - .catch(function (e) { throw e; }) - .finally(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, prisma.$disconnect()]; - case 1: return [2 /*return*/, _a.sent()]; - } -}); }); }); diff --git a/test.ts b/test.ts deleted file mode 100644 index ff14cf5..0000000 --- a/test.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { PrismaClient, Prisma } from '@prisma/client' - -const prisma = new PrismaClient() - -// Make sure to empty database before using. - -async function main() { - //Grant stuff below this block. This is constituents and organization mock data. - - //Create one mock constituient. - /*const newConstituent = await prisma.constituent.create({ - data: { - FirstName: 'first', - LastName: 'last', - StreetAddress: '123 Something St.', - City: 'SomewhereCity', - State:'SomeState', - Zipcode: 'SomeZipcode', - Country: 'SomeCountry', - EmailAddress: 'email@example.com' - }, - select: { - FirstName: true, - LastName: true - } - }) - - //Create multiple organizations. - const createManyOrg = await prisma.organization.createMany({ - data: [ - { StreetAddress: '123 Something St.', City: 'SomewhereCity', State:'SomeState', - Zipcode: 'SomeZipcode', Country: 'SomeCountry', OrganizationName: 'SomeOrganization' }, - { StreetAddress: '456 Test Rd.', City: 'TestCity', State:'TestState', - Zipcode: 'TestZipcode', Country: 'TestCountry', OrganizationName: 'TestOrganization'}, - { StreetAddress: '789 A St.', City: 'ACity', State:'AState', - Zipcode: 'AZipcode', Country: 'ACountry', OrganizationName: 'AOrganization' }, - { StreetAddress: '789 A St.', City: 'ACity', State:'AState', - Zipcode: 'AZipcode', Country: 'ACountry', OrganizationName: 'AOrganization' }, - ], - skipDuplicates: true, - }) - const organizations = await prisma.organization.findMany() - console.log(JSON.stringify(organizations));*/ - - //Create multiple grants. - const createManyGrants = await prisma.grant.createMany({ - data: [ - {GrantName: "Mock Grant One", - FundingAreas: ["Education"], - KidsUProgram: ["Afterschool Tutoring"], - FundingRestrictions: "None", - ContactType: "Email Grant", - GrantOpeningDates: [new Date("2023-01-01"), new Date("2023-02-01"), new Date("2023-03-01")], - EndOfGrantReportDueDate: new Date("2025-01-31"), - GrantDueDate: new Date("2024-09-15"), - AskDate: new Date("2023-06-15"), - AwardDate: null, - ReportingDates: [new Date("2024-01-15"), new Date("2024-07-15")], - TypeOfReporting: "Quarterly", - DateToReapplyForGrant: new Date("2025-06-01"), - WaitingPeriodToReapply: 2, - AskAmount: 50000.00, - AwardStatus: "Declined", - AmountAwarded: 0.00}, - - {GrantName: "Mock Grant Two", - FundingAreas: ["Education"], - KidsUProgram: ["Youth Empowerment"], - FundingRestrictions: "None", - ContactType: "Email Grant", - GrantOpeningDates: [new Date("2023-04-01"), new Date("2023-05-01"), new Date("2023-06-01")], - EndOfGrantReportDueDate: new Date("2025-03-31"), - GrantDueDate: new Date("2026-04-06"), - AskDate: new Date("2023-07-15"), - AwardDate: null, - ReportingDates: [new Date("2024-04-15"), new Date("2024-10-15")], - TypeOfReporting: "Biannually", - DateToReapplyForGrant: new Date("2025-07-01"), - WaitingPeriodToReapply: 3, - AskAmount: 6500.00, - AwardStatus: "Pending", - AmountAwarded: 0.00,}, - - {GrantName: "Mock Grant Three", - FundingAreas: ["Education"], - KidsUProgram: ["After School Tutoring"], - FundingRestrictions: "A mock restriction", - ContactType: "John Smith", - GrantOpeningDates: [new Date("2000-08-12"), new Date("2001-05-01"), new Date("2023-06-01")], - EndOfGrantReportDueDate: new Date("2007-09-23"), - GrantDueDate: new Date("2008-02-17"), - AskDate: new Date("2001-08-15"), - AwardDate: new Date("2001-06-01"), - ReportingDates: [new Date("2004-04-01"), new Date("2005-10-15")], - TypeOfReporting: "Yearly", - DateToReapplyForGrant: new Date("2009-12-01"), - WaitingPeriodToReapply: 2, - AskAmount: 16500.00, - AwardStatus: "Accepted", - AmountAwarded: 1000.00,}, - - {GrantName: "Mock Grant Four", - FundingAreas: ["Education"], - KidsUProgram: ["Youth Empowerment"], - FundingRestrictions: "None", - ContactType: "Email Grant", - GrantOpeningDates: [new Date("2030-06-24"), new Date("2035-07-21"), new Date("2040-08-16")], - EndOfGrantReportDueDate: new Date("2040-12-20"), - GrantDueDate: new Date("2040-12-21"), - AskDate: new Date("2031-07-16"), - AwardDate: new Date("2031-10-24"), - ReportingDates: [new Date("2035-04-15"), new Date("2037-11-15")], - TypeOfReporting: "Biannually", - DateToReapplyForGrant: new Date("2045-07-25"), - WaitingPeriodToReapply: 3, - AskAmount: 30000.00, - AwardStatus: "Accepted", - AmountAwarded: 15000.00}, - - {GrantName: "Mock Grant Five", - FundingAreas: ["Education"], - KidsUProgram: ["Marketing Video"], - FundingRestrictions: "None", - ContactType: "Company Website", - GrantOpeningDates: [new Date("2026-05-01"), new Date("2027-06-01"), new Date("2028-07-01")], - EndOfGrantReportDueDate: new Date("2028-04-31"), - GrantDueDate: new Date("2029-05-05"), - AskDate: new Date("2026-08-25"), - AwardDate: null, - ReportingDates: [new Date("2027-04-25"), new Date("2027-10-25")], - TypeOfReporting: "Biannually", - DateToReapplyForGrant: new Date("2028-07-30"), - WaitingPeriodToReapply: 1, - AskAmount: 20000.00, - AwardStatus: "Pending", - AmountAwarded: 0.00,}, - - {GrantName: "Mock Grant Six", - FundingAreas: ["Education"], - KidsUProgram: ["New Site"], - FundingRestrictions: "None", - ContactType: "Email Grant", - GrantOpeningDates: [new Date("2010-10-10"), new Date("2011-11-11"), new Date("2012-12-12")], - EndOfGrantReportDueDate: new Date("2013-01-13"), - GrantDueDate: new Date("2014-02-14"), - AskDate: new Date("2010-09-09"), - AwardDate: null, - ReportingDates: [new Date("2011-05-05"), new Date("2012-06-06")], - TypeOfReporting: "Quarterly", - DateToReapplyForGrant: new Date("2014-03-14"), - WaitingPeriodToReapply: 5, - AskAmount: 18000.00, - AwardStatus: "Declined", - AmountAwarded: 0.00,}, - - {GrantName: "Mock Grant Seven", - FundingAreas: ["Education"], - KidsUProgram: ["After School Tutoring"], - FundingRestrictions: "Another mock restriction", - ContactType: "Jane Doe", - GrantOpeningDates: [new Date("2008-04-16"), new Date("2009-06-18"), new Date("2010-08-20")], - EndOfGrantReportDueDate: new Date("2012-12-24"), - GrantDueDate: new Date("2014-02-14"), - AskDate: new Date("2008-09-05"), - AwardDate: new Date("2009-08-16"), - ReportingDates: [new Date("2009-05-05"), new Date("2010-06-06")], - TypeOfReporting: "Biannually", - DateToReapplyForGrant: new Date("2015-09-23"), - WaitingPeriodToReapply: 2, - AskAmount: 13500.00, - AwardStatus: "Awarded", - AmountAwarded: 10000.00,} - ] - }) -} - -main() - .catch( e => { throw e }) - .finally( async () => await prisma.$disconnect() ) - diff --git a/tsconfig.json b/tsconfig.json index 41fd213..36c68b3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -33,7 +33,7 @@ "app/pages/home.js", "app/utils/getOrganization.js", "frontend/src/pages/ApiTestPage.js", - "app/Grants/Detail/[id]/page.tsx" + "app/(pages)/Grants/Detail/[id]/page.tsx" ], "exclude": ["node_modules"] }