feat: implement dark mode and add custom color palette (theme)
This commit is contained in:
@@ -1,27 +1,12 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { getStorages } from "../utils/api/storages.ts";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Chip,
|
||||
CircularProgress,
|
||||
Divider,
|
||||
Input,
|
||||
Option,
|
||||
Select,
|
||||
Typography,
|
||||
} from "@mui/joy";
|
||||
import { Box, Button, Chip, CircularProgress, Divider, Input, Option, Select, Typography, } from "@mui/joy";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "@tanstack/react-form";
|
||||
import { getProductDetails, mutateProduct } from "../utils/api/products.ts";
|
||||
import { toInputDate } from "../utils/uxFncs";
|
||||
import type {
|
||||
AlertInterface,
|
||||
productDetailsInterface,
|
||||
ProductFormValues,
|
||||
Storage,
|
||||
} from "../misc/interfaces";
|
||||
import type { AlertInterface, productDetailsInterface, ProductFormValues, Storage, } from "../misc/interfaces";
|
||||
import type { ApiError } from "../utils/api/apiError";
|
||||
import Cookies from "js-cookie";
|
||||
import ElectricBoltIcon from "@mui/icons-material/ElectricBolt";
|
||||
@@ -140,7 +125,11 @@ export const ProductQuickView = () => {
|
||||
<div className="space-y-6">
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
<div className="space-y-1">
|
||||
<Typography level="h2" fontWeight="1000" className="text-slate-900">
|
||||
<Typography
|
||||
level="h2"
|
||||
fontWeight="1000"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
<ElectricBoltIcon color="primary" />
|
||||
{t("product-details-quick")}
|
||||
<ElectricBoltIcon color="primary" />
|
||||
@@ -157,7 +146,16 @@ export const ProductQuickView = () => {
|
||||
{productDetailsLoading && <CircularProgress size="sm" />}
|
||||
</div>
|
||||
{isSuccess && (
|
||||
<Box className="mt-6 rounded-3xl border border-white/70 bg-white/80 p-6 shadow-[0_24px_60px_rgba(12,38,78,0.12)] backdrop-blur">
|
||||
<Box
|
||||
className="mt-6 rounded-3xl p-6 backdrop-blur"
|
||||
sx={{
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
bgcolor: "background.surface",
|
||||
boxShadow:
|
||||
"0 24px 60px color-mix(in srgb, var(--joy-palette-primary-800) 12%, transparent)",
|
||||
}}
|
||||
>
|
||||
<form
|
||||
className="space-y-6"
|
||||
onSubmit={(e) => {
|
||||
@@ -168,7 +166,10 @@ export const ProductQuickView = () => {
|
||||
<div className="gap-5 lg:grid-cols-[1.2fr_1fr]">
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-1">
|
||||
<Typography level="title-md" className="text-slate-900">
|
||||
<Typography
|
||||
level="title-md"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
{t("product-name")}
|
||||
</Typography>
|
||||
<form.Field name="name">
|
||||
@@ -180,13 +181,20 @@ export const ProductQuickView = () => {
|
||||
onBlur={field.handleBlur}
|
||||
size="lg"
|
||||
variant="outlined"
|
||||
className="rounded-2xl bg-white/90 shadow-[0_10px_24px_rgba(15,23,42,0.08)]"
|
||||
className="rounded-2xl"
|
||||
sx={{
|
||||
bgcolor: "var(--joy-palette-background-surface)",
|
||||
boxShadow: "0 10px 24px var(--joy-palette-divider)",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</form.Field>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Typography level="title-md" className="text-slate-900">
|
||||
<Typography
|
||||
level="title-md"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
{t("description")}
|
||||
</Typography>
|
||||
<form.Field name="description">
|
||||
@@ -198,14 +206,21 @@ export const ProductQuickView = () => {
|
||||
onBlur={field.handleBlur}
|
||||
size="lg"
|
||||
variant="outlined"
|
||||
className="rounded-2xl bg-white/90 shadow-[0_10px_24px_rgba(15,23,42,0.08)]"
|
||||
className="rounded-2xl"
|
||||
sx={{
|
||||
bgcolor: "var(--joy-palette-background-surface)",
|
||||
boxShadow: "0 10px 24px var(--joy-palette-divider)",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</form.Field>
|
||||
</div>
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<div className="space-y-1">
|
||||
<Typography level="title-md" className="text-slate-900">
|
||||
<Typography
|
||||
level="title-md"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
{t("expiry-date")}
|
||||
</Typography>
|
||||
<form.Field name="expiry_date">
|
||||
@@ -217,13 +232,19 @@ export const ProductQuickView = () => {
|
||||
onBlur={field.handleBlur}
|
||||
size="lg"
|
||||
variant="outlined"
|
||||
className="rounded-2xl bg-white/90"
|
||||
className="rounded-2xl"
|
||||
sx={{
|
||||
bgcolor: "var(--joy-palette-background-surface)",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</form.Field>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Typography level="title-md" className="text-slate-900">
|
||||
<Typography
|
||||
level="title-md"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
{t("bottling-date")}
|
||||
</Typography>
|
||||
<form.Field name="bottling_date">
|
||||
@@ -235,7 +256,10 @@ export const ProductQuickView = () => {
|
||||
onBlur={field.handleBlur}
|
||||
size="lg"
|
||||
variant="outlined"
|
||||
className="rounded-2xl bg-white/90"
|
||||
className="rounded-2xl"
|
||||
sx={{
|
||||
bgcolor: "var(--joy-palette-background-surface)",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</form.Field>
|
||||
@@ -243,14 +267,28 @@ export const ProductQuickView = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="rounded-2xl border border-white/70 bg-linear-to-br from-[#f7fbff] via-[#f2f6fb] to-[#eef3f9] p-5 shadow-[0_16px_40px_rgba(12,38,78,0.08)]">
|
||||
<Typography level="title-lg" className="text-slate-900">
|
||||
<div
|
||||
className="rounded-2xl p-5"
|
||||
style={{
|
||||
border: "1px solid var(--joy-palette-divider)",
|
||||
background:
|
||||
"linear-gradient(to bottom right, var(--joy-palette-primary-50), var(--joy-palette-background-level1), var(--joy-palette-background-level2))",
|
||||
boxShadow: "0 16px 40px var(--joy-palette-divider)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
level="title-lg"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
{t("inventory")}
|
||||
</Typography>
|
||||
<Divider className="my-3" />
|
||||
<div className="grid gap-4">
|
||||
<div className="space-y-1">
|
||||
<Typography level="title-md" className="text-slate-900">
|
||||
<Typography
|
||||
level="title-md"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
{t("amount")}
|
||||
</Typography>
|
||||
<form.Field name="amount">
|
||||
@@ -270,13 +308,19 @@ export const ProductQuickView = () => {
|
||||
);
|
||||
}}
|
||||
onBlur={field.handleBlur}
|
||||
className="rounded-2xl bg-white/80"
|
||||
className="rounded-2xl"
|
||||
sx={{
|
||||
bgcolor: "var(--joy-palette-background-surface)",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</form.Field>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Typography level="title-md" className="text-slate-900">
|
||||
<Typography
|
||||
level="title-md"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
{t("price")}
|
||||
</Typography>
|
||||
<form.Field name="price">
|
||||
@@ -288,16 +332,25 @@ export const ProductQuickView = () => {
|
||||
onBlur={field.handleBlur}
|
||||
size="lg"
|
||||
variant="outlined"
|
||||
className="rounded-2xl bg-white/90"
|
||||
className="rounded-2xl"
|
||||
sx={{
|
||||
bgcolor: "var(--joy-palette-background-surface)",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</form.Field>
|
||||
<Typography level="body-sm" className="text-slate-500">
|
||||
<Typography
|
||||
level="body-sm"
|
||||
sx={{ color: "var(--joy-palette-text-tertiary)" }}
|
||||
>
|
||||
{Cookies.get("currency")}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Typography level="title-md" className="text-slate-900">
|
||||
<Typography
|
||||
level="title-md"
|
||||
sx={{ color: "var(--joy-palette-text-primary)" }}
|
||||
>
|
||||
{t("storage-place")}
|
||||
</Typography>
|
||||
<form.Field name="storage_location_uuid">
|
||||
@@ -309,7 +362,10 @@ export const ProductQuickView = () => {
|
||||
}
|
||||
size="lg"
|
||||
variant="outlined"
|
||||
className="rounded-2xl bg-white/90"
|
||||
className="rounded-2xl"
|
||||
sx={{
|
||||
bgcolor: "var(--joy-palette-background-surface)",
|
||||
}}
|
||||
>
|
||||
{storages?.map((storage) => (
|
||||
<Option key={storage.uuid} value={storage.uuid}>
|
||||
@@ -325,14 +381,23 @@ export const ProductQuickView = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<Typography level="body-sm" className="text-slate-500">
|
||||
<Typography
|
||||
level="body-sm"
|
||||
sx={{ color: "var(--joy-palette-text-tertiary)" }}
|
||||
>
|
||||
{t("product-details")}
|
||||
</Typography>
|
||||
<Button
|
||||
type="submit"
|
||||
loading={isPending}
|
||||
size="lg"
|
||||
className="rounded-2xl bg-[#0b6bcb] text-white shadow-[0_16px_36px_rgba(11,107,203,0.35)] transition hover:-translate-y-0.5 hover:bg-[#095aa7]"
|
||||
color="primary"
|
||||
variant="solid"
|
||||
className="rounded-2xl transition hover:-translate-y-0.5"
|
||||
sx={{
|
||||
boxShadow:
|
||||
"0 16px 36px color-mix(in srgb, var(--joy-palette-primary-solidBg) 35%, transparent)",
|
||||
}}
|
||||
>
|
||||
{t("save")}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user