add filters for all routes
This commit is contained in:
@@ -1,7 +1,11 @@
|
|||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
import src.models as models
|
import src.models as models
|
||||||
|
|
||||||
def get_all(session: Session, names: list[str], types: list[str]) -> list[models.ProductorPublic]:
|
def get_all(
|
||||||
|
session: Session,
|
||||||
|
names: list[str],
|
||||||
|
types: list[str]
|
||||||
|
) -> list[models.ProductorPublic]:
|
||||||
statement = select(models.Productor)
|
statement = select(models.Productor)
|
||||||
if len(names) > 0:
|
if len(names) > 0:
|
||||||
statement = statement.where(models.Productor.name.in_(names))
|
statement = statement.where(models.Productor.name.in_(names))
|
||||||
|
|||||||
@@ -14,7 +14,12 @@ def get_products(
|
|||||||
types: list[str] = Query([]),
|
types: list[str] = Query([]),
|
||||||
productors: list[str] = Query([]),
|
productors: list[str] = Query([]),
|
||||||
):
|
):
|
||||||
return service.get_all(session, names, productors, types)
|
return service.get_all(
|
||||||
|
session,
|
||||||
|
names,
|
||||||
|
productors,
|
||||||
|
types,
|
||||||
|
)
|
||||||
|
|
||||||
@router.get('/{id}', response_model=models.ProductPublic)
|
@router.get('/{id}', response_model=models.ProductPublic)
|
||||||
def get_product(id: int, session: Session = Depends(get_session)):
|
def get_product(id: int, session: Session = Depends(get_session)):
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ def get_all(
|
|||||||
names: list[str],
|
names: list[str],
|
||||||
productors: list[str],
|
productors: list[str],
|
||||||
types: list[str],
|
types: list[str],
|
||||||
|
|
||||||
) -> list[models.ProductPublic]:
|
) -> list[models.ProductPublic]:
|
||||||
statement = select(models.Product)
|
statement = select(models.Product)
|
||||||
if len(names) > 0:
|
if len(names) > 0:
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
import src.models as models
|
import src.models as models
|
||||||
|
|
||||||
def get_all(session: Session) -> list[models.ShipmentPublic]:
|
def get_all(
|
||||||
|
session: Session,
|
||||||
|
names: list[str],
|
||||||
|
dates: list[str],
|
||||||
|
forms: list[int]
|
||||||
|
) -> list[models.ShipmentPublic]:
|
||||||
statement = select(models.Shipment)
|
statement = select(models.Shipment)
|
||||||
|
if len(names) > 0:
|
||||||
|
statement = statement.where(models.Shipment.name.in_(names))
|
||||||
|
if len(dates) > 0:
|
||||||
|
statement = statement.where(models.Shipment.date.in_(list(map(lambda x: datetime.strptime(x, '%Y-%m-%d'), dates))))
|
||||||
|
if len(forms) > 0:
|
||||||
|
statement = statement.join(models.Form).where(models.Form.name.in_(forms))
|
||||||
return session.exec(statement.order_by(models.Shipment.name)).all()
|
return session.exec(statement.order_by(models.Shipment.name)).all()
|
||||||
|
|
||||||
def get_one(session: Session, shipment_id: int) -> models.ShipmentPublic:
|
def get_one(session: Session, shipment_id: int) -> models.ShipmentPublic:
|
||||||
|
|||||||
@@ -1,15 +1,26 @@
|
|||||||
from fastapi import APIRouter, HTTPException, Depends
|
from fastapi import APIRouter, HTTPException, Depends, Query
|
||||||
import src.messages as messages
|
import src.messages as messages
|
||||||
import src.models as models
|
import src.models as models
|
||||||
from src.database import get_session
|
from src.database import get_session
|
||||||
from sqlmodel import Session
|
from sqlmodel import Session
|
||||||
import src.shipments.service as service
|
import src.shipments.service as service
|
||||||
from src.auth.auth import get_current_user
|
from src.auth.auth import get_current_user
|
||||||
|
|
||||||
router = APIRouter(prefix='/shipments')
|
router = APIRouter(prefix='/shipments')
|
||||||
|
|
||||||
@router.get('/', response_model=list[models.ShipmentPublic], )
|
@router.get('/', response_model=list[models.ShipmentPublic], )
|
||||||
def get_shipments(session: Session = Depends(get_session)):
|
def get_shipments(
|
||||||
return service.get_all(session)
|
session: Session = Depends(get_session),
|
||||||
|
names: list[str] = Query([]),
|
||||||
|
dates: list[str] = Query([]),
|
||||||
|
forms: list[str] = Query([]),
|
||||||
|
):
|
||||||
|
return service.get_all(
|
||||||
|
session,
|
||||||
|
names,
|
||||||
|
dates,
|
||||||
|
forms,
|
||||||
|
)
|
||||||
|
|
||||||
@router.get('/{id}', response_model=models.ShipmentPublic)
|
@router.get('/{id}', response_model=models.ShipmentPublic)
|
||||||
def get_shipment(id: int, session: Session = Depends(get_session)):
|
def get_shipment(id: int, session: Session = Depends(get_session)):
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
import src.models as models
|
import src.models as models
|
||||||
|
|
||||||
def get_all(session: Session) -> list[models.UserPublic]:
|
def get_all(
|
||||||
|
session: Session,
|
||||||
|
names: list[str],
|
||||||
|
emails: list[str],
|
||||||
|
) -> list[models.UserPublic]:
|
||||||
statement = select(models.User)
|
statement = select(models.User)
|
||||||
|
if len(names) > 0:
|
||||||
|
statement = statement.where(models.User.name.in_(names))
|
||||||
|
if len(emails) > 0:
|
||||||
|
statement = statement.where(models.User.email.in_(emails))
|
||||||
return session.exec(statement.order_by(models.User.name)).all()
|
return session.exec(statement.order_by(models.User.name)).all()
|
||||||
|
|
||||||
def get_one(session: Session, user_id: int) -> models.UserPublic:
|
def get_one(session: Session, user_id: int) -> models.UserPublic:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from fastapi import APIRouter, HTTPException, Depends
|
from fastapi import APIRouter, HTTPException, Depends, Query
|
||||||
import src.messages as messages
|
import src.messages as messages
|
||||||
import src.models as models
|
import src.models as models
|
||||||
from src.database import get_session
|
from src.database import get_session
|
||||||
@@ -8,8 +8,16 @@ import src.users.service as service
|
|||||||
router = APIRouter(prefix='/users')
|
router = APIRouter(prefix='/users')
|
||||||
|
|
||||||
@router.get('/', response_model=list[models.UserPublic])
|
@router.get('/', response_model=list[models.UserPublic])
|
||||||
def get_users(session: Session = Depends(get_session)):
|
def get_users(
|
||||||
return service.get_all(session)
|
session: Session = Depends(get_session),
|
||||||
|
names: list[str] = Query([]),
|
||||||
|
emails: list[str] = Query([]),
|
||||||
|
):
|
||||||
|
return service.get_all(
|
||||||
|
session,
|
||||||
|
names,
|
||||||
|
emails,
|
||||||
|
)
|
||||||
|
|
||||||
@router.get('/{id}', response_model=models.UserPublic)
|
@router.get('/{id}', response_model=models.UserPublic)
|
||||||
def get_users(id: int, session: Session = Depends(get_session)):
|
def get_users(id: int, session: Session = Depends(get_session)):
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>frontend</title>
|
<title>Amap Croix-luizet</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -121,5 +121,5 @@
|
|||||||
"error deleting shipment": "error deleting shipment",
|
"error deleting shipment": "error deleting shipment",
|
||||||
"there is no contract for now": "there is no contract for now.",
|
"there is no contract for now": "there is no contract for now.",
|
||||||
"the product unit will be assigned to the quantity requested in the form": "the product unit will be assigned to the quantity requested in the form",
|
"the product unit will be assigned to the quantity requested in the form": "the product unit will be assigned to the quantity requested in the form",
|
||||||
"all theses informations are for contract generation, no informations is stored outside of contracts": "all theses informations are for contract generation, no informations is stored outside of contracts."
|
"all theses informations are for contract generation": "all theses informations are for contract generation."
|
||||||
}
|
}
|
||||||
@@ -134,5 +134,5 @@
|
|||||||
"there is no contract for now": "Il n'y a pas de contrats pour le moment.",
|
"there is no contract for now": "Il n'y a pas de contrats pour le moment.",
|
||||||
|
|
||||||
"the product unit will be assigned to the quantity requested in the form": "L'unité de vente du produit définit l'unité associée a la quantité demandée dans le formulaire des amapiens.",
|
"the product unit will be assigned to the quantity requested in the form": "L'unité de vente du produit définit l'unité associée a la quantité demandée dans le formulaire des amapiens.",
|
||||||
"all theses informations are for contract generation, no informations is stored outside of contracts": "ces informations sont nécéssaires pour la génération de contrat, aucune information personnelle n'est gardée ailleurs que dans les contrats générés."
|
"all theses informations are for contract generation": "ces informations sont nécéssaires pour la génération de contrat."
|
||||||
}
|
}
|
||||||
@@ -3,11 +3,11 @@ nav {
|
|||||||
justify-self: left;
|
justify-self: left;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
background-color: var(--mantine-color-blue-4);
|
background-color: var(--mantine-color-blue-4);
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navLink {
|
.navLink {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-right: 1rem;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,34 @@
|
|||||||
import { NavLink } from "react-router";
|
import { NavLink } from "react-router";
|
||||||
import { t } from "@/config/i18n";
|
import { t } from "@/config/i18n";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
import { Group } from "@mantine/core";
|
||||||
|
import { Config } from "@/config/config";
|
||||||
|
|
||||||
export function Navbar() {
|
export function Navbar() {
|
||||||
return (
|
return (
|
||||||
<nav>
|
<nav>
|
||||||
|
<Group>
|
||||||
|
<NavLink
|
||||||
|
className={"navLink"}
|
||||||
|
aria-label={t('home')}
|
||||||
|
to="/"
|
||||||
|
>
|
||||||
|
{t("home", {capfirst: true})}
|
||||||
|
</NavLink>
|
||||||
|
<NavLink
|
||||||
|
className={"navLink"}
|
||||||
|
aria-label={t('dashboard')}
|
||||||
|
to="/dashboard/productors"
|
||||||
|
>
|
||||||
|
{t("dashboard", {capfirst: true})}
|
||||||
|
</NavLink>
|
||||||
|
</Group>
|
||||||
<NavLink
|
<NavLink
|
||||||
className={"navLink"}
|
className={"navLink"}
|
||||||
to="/"
|
aria-label={t("login with keycloak")}
|
||||||
|
to={`${Config.backend_uri}/auth/login`}
|
||||||
>
|
>
|
||||||
{t("home", {capfirst: true})}
|
{t("login with keycloak", {capfirst: true})}
|
||||||
</NavLink>
|
|
||||||
<NavLink
|
|
||||||
className={"navLink"}
|
|
||||||
to="/dashboard/productors"
|
|
||||||
>
|
|
||||||
{t("dashboard", {capfirst: true})}
|
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default function ProductorRow({
|
|||||||
<Table.Td>
|
<Table.Td>
|
||||||
{
|
{
|
||||||
productor.payment_methods.map((value) =>(
|
productor.payment_methods.map((value) =>(
|
||||||
<Badge ml="xs">
|
<Badge key={value.name} ml="xs">
|
||||||
{t(value.name, {capfirst: true})}
|
{t(value.name, {capfirst: true})}
|
||||||
</Badge>
|
</Badge>
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -4,18 +4,23 @@ import { t } from "@/config/i18n";
|
|||||||
|
|
||||||
export type ShipmentFiltersProps = {
|
export type ShipmentFiltersProps = {
|
||||||
names: string[];
|
names: string[];
|
||||||
|
forms: string[];
|
||||||
filters: URLSearchParams;
|
filters: URLSearchParams;
|
||||||
onFilterChange: (values: string[], filter: string) => void;
|
onFilterChange: (values: string[], filter: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ShipmentsFilters({
|
export default function ShipmentsFilters({
|
||||||
names,
|
names,
|
||||||
|
forms,
|
||||||
filters,
|
filters,
|
||||||
onFilterChange
|
onFilterChange
|
||||||
}: ShipmentFiltersProps) {
|
}: ShipmentFiltersProps) {
|
||||||
const defaultNames = useMemo(() => {
|
const defaultNames = useMemo(() => {
|
||||||
return filters.getAll("names")
|
return filters.getAll("names")
|
||||||
}, [filters]);
|
}, [filters]);
|
||||||
|
const defaultForms = useMemo(() => {
|
||||||
|
return filters.getAll("forms")
|
||||||
|
}, [filters]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group>
|
<Group>
|
||||||
@@ -28,6 +33,18 @@ export default function ShipmentsFilters({
|
|||||||
onFilterChange(values, 'names')
|
onFilterChange(values, 'names')
|
||||||
}}
|
}}
|
||||||
clearable
|
clearable
|
||||||
|
searchable
|
||||||
|
/>
|
||||||
|
<MultiSelect
|
||||||
|
aria-label={t("filter by form", {capfirst: true})}
|
||||||
|
placeholder={t("filter by form", {capfirst: true})}
|
||||||
|
data={forms}
|
||||||
|
defaultValue={defaultForms}
|
||||||
|
onChange={(values: string[]) => {
|
||||||
|
onFilterChange(values, 'forms')
|
||||||
|
}}
|
||||||
|
clearable
|
||||||
|
searchable
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export default function ShipmentModal({
|
|||||||
const { data: allForms } = getForms();
|
const { data: allForms } = getForms();
|
||||||
const { data: allProducts } = getProducts(new URLSearchParams("types=1"));
|
const { data: allProducts } = getProducts(new URLSearchParams("types=1"));
|
||||||
const { data: allProductors } = getProductors()
|
const { data: allProductors } = getProductors()
|
||||||
|
|
||||||
const formsSelect = useMemo(() => {
|
const formsSelect = useMemo(() => {
|
||||||
return allForms?.map(form => ({value: String(form.id), label: `${form.name} ${form.season}`}))
|
return allForms?.map(form => ({value: String(form.id), label: `${form.name} ${form.season}`}))
|
||||||
}, [allForms]);
|
}, [allForms]);
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export function Contract() {
|
|||||||
shipment.products
|
shipment.products
|
||||||
);
|
);
|
||||||
if (total < (form?.minimum_shipment_value || 0)) {
|
if (total < (form?.minimum_shipment_value || 0)) {
|
||||||
return shipment.id; // mark shipment as invalid
|
return shipment.id;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
@@ -125,8 +125,18 @@ export function Contract() {
|
|||||||
}
|
}
|
||||||
}, [inputForm, inputRefs, isShipmentsMinimumValue, form]);
|
}, [inputForm, inputRefs, isShipmentsMinimumValue, form]);
|
||||||
|
|
||||||
|
|
||||||
if (!form)
|
if (!form)
|
||||||
return <Loader/>;
|
return (
|
||||||
|
<Group
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
h="80vh"
|
||||||
|
w="100%"
|
||||||
|
>
|
||||||
|
<Loader color="pink"/>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -134,7 +144,7 @@ export function Contract() {
|
|||||||
<Title order={2}>{form.name}</Title>
|
<Title order={2}>{form.name}</Title>
|
||||||
<Title order={3}>{t("informations", {capfirst: true})}</Title>
|
<Title order={3}>{t("informations", {capfirst: true})}</Title>
|
||||||
<Text size="sm">
|
<Text size="sm">
|
||||||
{t("all theses informations are for contract generation, no informations is stored outside of contracts", {capfirst: true})}
|
{t("all theses informations are for contract generation", {capfirst: true})}
|
||||||
</Text>
|
</Text>
|
||||||
<Group grow>
|
<Group grow>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import FormModal from "@/components/Forms/Modal";
|
|||||||
import FormRow from "@/components/Forms/Row";
|
import FormRow from "@/components/Forms/Row";
|
||||||
import type { Form, FormInputs } from "@/services/resources/forms";
|
import type { Form, FormInputs } from "@/services/resources/forms";
|
||||||
import FilterForms from "@/components/Forms/Filter";
|
import FilterForms from "@/components/Forms/Filter";
|
||||||
import { notifications } from "@mantine/notifications";
|
|
||||||
|
|
||||||
export function Forms() {
|
export function Forms() {
|
||||||
const [ searchParams, setSearchParams ] = useSearchParams();
|
const [ searchParams, setSearchParams ] = useSearchParams();
|
||||||
@@ -59,11 +58,7 @@ export function Forms() {
|
|||||||
minimum_shipment_value: Number(form.minimum_shipment_value),
|
minimum_shipment_value: Number(form.minimum_shipment_value),
|
||||||
});
|
});
|
||||||
closeModal();
|
closeModal();
|
||||||
notifications.show({
|
}, [createFormMutation, closeModal]);
|
||||||
title: t("success", {capfirst: true}),
|
|
||||||
message: t("successfully created form", {capfirst: true}),
|
|
||||||
});
|
|
||||||
}, [createFormMutation]);
|
|
||||||
|
|
||||||
const handleEditForm = useCallback(async (form: FormInputs, id?: number) => {
|
const handleEditForm = useCallback(async (form: FormInputs, id?: number) => {
|
||||||
if (!id)
|
if (!id)
|
||||||
@@ -80,11 +75,7 @@ export function Forms() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
closeModal();
|
closeModal();
|
||||||
notifications.show({
|
}, [editFormMutation, closeModal]);
|
||||||
title: t("success", {capfirst: true}),
|
|
||||||
message: t("successfully edited form", {capfirst: true}),
|
|
||||||
});
|
|
||||||
}, [editFormMutation]);
|
|
||||||
|
|
||||||
const onFilterChange = useCallback((
|
const onFilterChange = useCallback((
|
||||||
values: string[],
|
values: string[],
|
||||||
@@ -102,8 +93,18 @@ export function Forms() {
|
|||||||
});
|
});
|
||||||
}, [searchParams, setSearchParams])
|
}, [searchParams, setSearchParams])
|
||||||
|
|
||||||
|
|
||||||
if (!data || isPending)
|
if (!data || isPending)
|
||||||
return (<Loader color="blue"/>);
|
return (
|
||||||
|
<Group
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
h="80vh"
|
||||||
|
w="100%"
|
||||||
|
>
|
||||||
|
<Loader color="pink"/>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { ProductorModal } from "@/components/Productors/Modal";
|
|||||||
import { useCallback, useMemo } from "react";
|
import { useCallback, useMemo } from "react";
|
||||||
import type { Productor, ProductorInputs } from "@/services/resources/productors";
|
import type { Productor, ProductorInputs } from "@/services/resources/productors";
|
||||||
import ProductorsFilters from "@/components/Productors/Filter";
|
import ProductorsFilters from "@/components/Productors/Filter";
|
||||||
import { notifications } from "@mantine/notifications";
|
|
||||||
|
|
||||||
export default function Productors() {
|
export default function Productors() {
|
||||||
const [ searchParams, setSearchParams ] = useSearchParams();
|
const [ searchParams, setSearchParams ] = useSearchParams();
|
||||||
@@ -51,11 +50,7 @@ export default function Productors() {
|
|||||||
...productor
|
...productor
|
||||||
});
|
});
|
||||||
closeModal();
|
closeModal();
|
||||||
notifications.show({
|
}, [createProductorMutation, closeModal]);
|
||||||
title: t("success", {capfirst: true}),
|
|
||||||
message: t("successfully created productor", {capfirst: true}),
|
|
||||||
});
|
|
||||||
}, [createProductorMutation]);
|
|
||||||
|
|
||||||
const handleEditProductor = useCallback(async (productor: ProductorInputs, id?: number) => {
|
const handleEditProductor = useCallback(async (productor: ProductorInputs, id?: number) => {
|
||||||
if (!id)
|
if (!id)
|
||||||
@@ -65,11 +60,7 @@ export default function Productors() {
|
|||||||
productor: productor
|
productor: productor
|
||||||
});
|
});
|
||||||
closeModal();
|
closeModal();
|
||||||
notifications.show({
|
}, [editProductorMutation, closeModal]);
|
||||||
title: t("success", {capfirst: true}),
|
|
||||||
message: t("successfully edited productor", {capfirst: true}),
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onFilterChange = useCallback((values: string[], filter: string) => {
|
const onFilterChange = useCallback((values: string[], filter: string) => {
|
||||||
setSearchParams(prev => {
|
setSearchParams(prev => {
|
||||||
@@ -84,7 +75,16 @@ export default function Productors() {
|
|||||||
}, [searchParams, setSearchParams])
|
}, [searchParams, setSearchParams])
|
||||||
|
|
||||||
if (!productors || isPending)
|
if (!productors || isPending)
|
||||||
return <Loader/>
|
return (
|
||||||
|
<Group
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
h="80vh"
|
||||||
|
w="100%"
|
||||||
|
>
|
||||||
|
<Loader color="pink"/>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { ProductModal } from "@/components/Products/Modal";
|
|||||||
import { useCallback, useMemo } from "react";
|
import { useCallback, useMemo } from "react";
|
||||||
import { productCreateFromProductInputs, type Product, type ProductInputs } from "@/services/resources/products";
|
import { productCreateFromProductInputs, type Product, type ProductInputs } from "@/services/resources/products";
|
||||||
import ProductsFilters from "@/components/Products/Filter";
|
import ProductsFilters from "@/components/Products/Filter";
|
||||||
import { notifications } from "@mantine/notifications";
|
|
||||||
|
|
||||||
export default function Products() {
|
export default function Products() {
|
||||||
const [ searchParams, setSearchParams ] = useSearchParams();
|
const [ searchParams, setSearchParams ] = useSearchParams();
|
||||||
@@ -49,11 +48,7 @@ export default function Products() {
|
|||||||
const handleCreateProduct = useCallback(async (product: ProductInputs) => {
|
const handleCreateProduct = useCallback(async (product: ProductInputs) => {
|
||||||
await createProductMutation.mutateAsync(productCreateFromProductInputs(product));
|
await createProductMutation.mutateAsync(productCreateFromProductInputs(product));
|
||||||
closeModal();
|
closeModal();
|
||||||
notifications.show({
|
}, [createProductMutation, closeModal]);
|
||||||
title: t("success", {capfirst: true}),
|
|
||||||
message: t("successfully created product", {capfirst: true}),
|
|
||||||
});
|
|
||||||
}, [createProductMutation]);
|
|
||||||
|
|
||||||
const handleEditProduct = useCallback(async (product: ProductInputs, id?: number) => {
|
const handleEditProduct = useCallback(async (product: ProductInputs, id?: number) => {
|
||||||
if (!id)
|
if (!id)
|
||||||
@@ -63,11 +58,7 @@ export default function Products() {
|
|||||||
product: productCreateFromProductInputs(product)
|
product: productCreateFromProductInputs(product)
|
||||||
});
|
});
|
||||||
closeModal();
|
closeModal();
|
||||||
notifications.show({
|
}, [editProductMutation, closeModal]);
|
||||||
title: t("success", {capfirst: true}),
|
|
||||||
message: t("successfully edited product", {capfirst: true}),
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onFilterChange = useCallback((values: string[], filter: string) => {
|
const onFilterChange = useCallback((values: string[], filter: string) => {
|
||||||
setSearchParams(prev => {
|
setSearchParams(prev => {
|
||||||
@@ -82,7 +73,16 @@ export default function Products() {
|
|||||||
}, [searchParams, setSearchParams])
|
}, [searchParams, setSearchParams])
|
||||||
|
|
||||||
if (!products || isPending)
|
if (!products || isPending)
|
||||||
return <Loader/>
|
return (
|
||||||
|
<Group
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
h="80vh"
|
||||||
|
w="100%"
|
||||||
|
>
|
||||||
|
<Loader color="pink"/>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { useCallback, useMemo } from "react";
|
|||||||
import { shipmentCreateFromShipmentInputs, type Shipment, type ShipmentInputs } from "@/services/resources/shipments";
|
import { shipmentCreateFromShipmentInputs, type Shipment, type ShipmentInputs } from "@/services/resources/shipments";
|
||||||
import ShipmentModal from "@/components/Shipments/Modal";
|
import ShipmentModal from "@/components/Shipments/Modal";
|
||||||
import ShipmentsFilters from "@/components/Shipments/Filter";
|
import ShipmentsFilters from "@/components/Shipments/Filter";
|
||||||
import { notifications } from "@mantine/notifications";
|
|
||||||
|
|
||||||
export default function Shipments() {
|
export default function Shipments() {
|
||||||
const [ searchParams, setSearchParams ] = useSearchParams();
|
const [ searchParams, setSearchParams ] = useSearchParams();
|
||||||
@@ -38,17 +37,18 @@ export default function Shipments() {
|
|||||||
.filter((season, index, array) => array.indexOf(season) === index)
|
.filter((season, index, array) => array.indexOf(season) === index)
|
||||||
}, [allShipments])
|
}, [allShipments])
|
||||||
|
|
||||||
|
const forms = useMemo(() => {
|
||||||
|
return allShipments?.map((shipment: Shipment) => (shipment.form.name))
|
||||||
|
.filter((season, index, array) => array.indexOf(season) === index)
|
||||||
|
}, [allShipments])
|
||||||
|
|
||||||
const createShipmentMutation = createShipment();
|
const createShipmentMutation = createShipment();
|
||||||
const editShipmentMutation = editShipment();
|
const editShipmentMutation = editShipment();
|
||||||
|
|
||||||
const handleCreateShipment = useCallback(async (shipment: ShipmentInputs) => {
|
const handleCreateShipment = useCallback(async (shipment: ShipmentInputs) => {
|
||||||
await createShipmentMutation.mutateAsync(shipmentCreateFromShipmentInputs(shipment));
|
await createShipmentMutation.mutateAsync(shipmentCreateFromShipmentInputs(shipment));
|
||||||
closeModal();
|
closeModal();
|
||||||
notifications.show({
|
}, [createShipmentMutation, closeModal]);
|
||||||
title: t("success", {capfirst: true}),
|
|
||||||
message: t("successfully created shipment", {capfirst: true}),
|
|
||||||
});
|
|
||||||
}, [createShipmentMutation]);
|
|
||||||
|
|
||||||
const handleEditShipment = useCallback(async (shipment: ShipmentInputs, id?: number) => {
|
const handleEditShipment = useCallback(async (shipment: ShipmentInputs, id?: number) => {
|
||||||
if (!id)
|
if (!id)
|
||||||
@@ -58,11 +58,7 @@ export default function Shipments() {
|
|||||||
shipment: shipmentCreateFromShipmentInputs(shipment)
|
shipment: shipmentCreateFromShipmentInputs(shipment)
|
||||||
});
|
});
|
||||||
closeModal();
|
closeModal();
|
||||||
notifications.show({
|
}, [editShipmentMutation, closeModal]);
|
||||||
title: t("success", {capfirst: true}),
|
|
||||||
message: t("successfully edited shipment", {capfirst: true}),
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onFilterChange = useCallback((values: string[], filter: string) => {
|
const onFilterChange = useCallback((values: string[], filter: string) => {
|
||||||
setSearchParams(prev => {
|
setSearchParams(prev => {
|
||||||
@@ -77,7 +73,16 @@ export default function Shipments() {
|
|||||||
}, [searchParams, setSearchParams])
|
}, [searchParams, setSearchParams])
|
||||||
|
|
||||||
if (!shipments || isPending)
|
if (!shipments || isPending)
|
||||||
return <Loader/>
|
return (
|
||||||
|
<Group
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
h="80vh"
|
||||||
|
w="100%"
|
||||||
|
>
|
||||||
|
<Loader color="pink"/>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
@@ -106,6 +111,7 @@ export default function Shipments() {
|
|||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
<ShipmentsFilters
|
<ShipmentsFilters
|
||||||
|
forms={forms || []}
|
||||||
names={names || []}
|
names={names || []}
|
||||||
filters={searchParams}
|
filters={searchParams}
|
||||||
onFilterChange={onFilterChange}
|
onFilterChange={onFilterChange}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export default function Users() {
|
|||||||
const handleCreateUser = useCallback(async (user: UserInputs) => {
|
const handleCreateUser = useCallback(async (user: UserInputs) => {
|
||||||
await createUserMutation.mutateAsync(user);
|
await createUserMutation.mutateAsync(user);
|
||||||
closeModal();
|
closeModal();
|
||||||
}, [createUserMutation]);
|
}, [createUserMutation, closeModal]);
|
||||||
|
|
||||||
const handleEditUser = useCallback(async (user: UserInputs, id?: number) => {
|
const handleEditUser = useCallback(async (user: UserInputs, id?: number) => {
|
||||||
if (!id)
|
if (!id)
|
||||||
@@ -54,7 +54,7 @@ export default function Users() {
|
|||||||
user: user
|
user: user
|
||||||
});
|
});
|
||||||
closeModal();
|
closeModal();
|
||||||
}, []);
|
}, [editUserMutation, closeModal]);
|
||||||
|
|
||||||
const onFilterChange = useCallback((values: string[], filter: string) => {
|
const onFilterChange = useCallback((values: string[], filter: string) => {
|
||||||
setSearchParams(prev => {
|
setSearchParams(prev => {
|
||||||
@@ -69,7 +69,16 @@ export default function Users() {
|
|||||||
}, [searchParams, setSearchParams])
|
}, [searchParams, setSearchParams])
|
||||||
|
|
||||||
if (!users || isPending)
|
if (!users || isPending)
|
||||||
return <Loader/>
|
return (
|
||||||
|
<Group
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
h="80vh"
|
||||||
|
w="100%"
|
||||||
|
>
|
||||||
|
<Loader color="pink"/>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import Users from "@/pages/Users";
|
|||||||
import Shipments from "./pages/Shipments";
|
import Shipments from "./pages/Shipments";
|
||||||
import { Contract } from "./pages/Contract";
|
import { Contract } from "./pages/Contract";
|
||||||
import { NotFound } from "./pages/NotFound";
|
import { NotFound } from "./pages/NotFound";
|
||||||
// import { CreateForms } from "@/pages/Forms/CreateForm";
|
|
||||||
|
|
||||||
export const router = createBrowserRouter([
|
export const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user