@@ -0,0 +1,44 @@ | |||
import { Metadata } from "next"; | |||
import { getServerI18n, I18nProvider } from "@/i18n"; | |||
import Typography from "@mui/material/Typography"; | |||
import { Button, Link, Stack } from "@mui/material"; | |||
import { Add } from "@mui/icons-material"; | |||
import { Suspense } from "react"; | |||
import { preloadQcItem } from "@/app/api/settings/qcItem"; | |||
import QcItemSearch from "@/components/QcItemSearch"; | |||
export const metadata: Metadata = { | |||
title: "Qc Item", | |||
}; | |||
const qcItem: React.FC = async () => { | |||
const { t } = await getServerI18n("qcItem") | |||
preloadQcItem() | |||
return <> | |||
<Stack | |||
direction="row" | |||
justifyContent="space-between" | |||
flexWrap="wrap" | |||
rowGap={2} | |||
> | |||
<Typography variant="h4" marginInlineEnd={2}> | |||
{t("Qc Item")} | |||
</Typography> | |||
<Button | |||
variant="contained" | |||
startIcon={<Add />} | |||
LinkComponent={Link} | |||
href="qcItem/create" | |||
> | |||
{t("Create Qc Item")} | |||
</Button> | |||
</Stack> | |||
<Suspense fallback={<QcItemSearch.Loading />}> | |||
<QcItemSearch /> | |||
</Suspense> | |||
</>; | |||
}; | |||
export default qcItem; |
@@ -0,0 +1,32 @@ | |||
"use server" | |||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { revalidateTag } from "next/cache"; | |||
export interface SaveQcItemInputs { | |||
id?: number; | |||
code: string; | |||
name: string; | |||
description?: string; | |||
} | |||
export interface SaveQcItemResponse { | |||
id?: number; | |||
code: string; | |||
name: string; | |||
description?: string; | |||
errors: Record<keyof SaveQcItemInputs, string> | |||
} | |||
export const saveQcItem = async (data: SaveQcItemInputs) => { | |||
const response = await serverFetchJson<SaveQcItemResponse>(`${BASE_API_URL}/qcItems/save`, { | |||
method: "POST", | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}) | |||
revalidateTag(`qcItems`) | |||
return response | |||
} |
@@ -0,0 +1,32 @@ | |||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { cache } from "react"; | |||
import "server-only"; | |||
import { SaveQcItemInputs } from "./actions"; | |||
import next from "next"; | |||
export interface QcItemResult { | |||
id: number; | |||
code: string; | |||
name: string; | |||
description: string; | |||
} | |||
export const preloadQcItem = () => { | |||
fetchQcItems(); | |||
}; | |||
export const fetchQcItems = cache(async () => { | |||
return serverFetchJson<QcItemResult[]>(`${BASE_API_URL}/qcItems`, { | |||
next: { tags: ["qcItems"] } | |||
}); | |||
}); | |||
export const fetchQcItemDetail = cache(async (qcItemId: string) => { | |||
return serverFetchJson<SaveQcItemInputs>( | |||
`${BASE_API_URL}/qcItems/qcItemDetail/${qcItemId}`, | |||
{ | |||
next: { tags: [`qcItemDetail_${qcItemId}`] } | |||
} | |||
) | |||
}) |
@@ -12,6 +12,8 @@ const pathToLabelMap: { [path: string]: string } = { | |||
"/projects/create": "Create Project", | |||
"/tasks": "Task Template", | |||
"/tasks/create": "Create Task Template", | |||
"/settings/qcItem": "Qc Item", | |||
}; | |||
const Breadcrumb = () => { | |||
@@ -224,12 +224,12 @@ const NavigationContent: React.FC = () => { | |||
{ | |||
icon: <RequestQuote />, | |||
label: "QC Check Item", | |||
path: "/settings/user", | |||
path: "/settings/qcItem", | |||
}, | |||
{ | |||
icon: <RequestQuote />, | |||
label: "QC Category", | |||
path: "/settings/user", | |||
path: "/settings/qcCategory", | |||
}, | |||
{ | |||
icon: <RequestQuote />, | |||
@@ -0,0 +1,57 @@ | |||
import { SaveQcItemInputs } from "@/app/api/settings/qcItem/actions" | |||
import { Box, Card, CardContent, Grid, Stack, TextField, Typography } from "@mui/material" | |||
import { useFormContext } from "react-hook-form" | |||
import { useTranslation } from "react-i18next" | |||
const QcItemDetails = () => { | |||
const { t } = useTranslation() | |||
const { | |||
register | |||
} = useFormContext<SaveQcItemInputs>() | |||
return ( | |||
<Card sx={{ display: "block" }}> | |||
<CardContent component={Stack} spacing={4}> | |||
<Box> | |||
<Typography variant={"overline"} display={"block"} marginBlockEnd={1}> | |||
{t("Qc Item Details")} | |||
</Typography> | |||
<Grid container spacing={2} columns={{ xs: 6, sm: 12 }}> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("Code")} | |||
fullWidth | |||
{...register("code", { | |||
required: "Code required!", | |||
maxLength: 30 | |||
})} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("Name")} | |||
fullWidth | |||
{...register("name", { | |||
required: "Name required!", | |||
maxLength: 30 | |||
})} | |||
/> | |||
</Grid> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("Description")} | |||
fullWidth | |||
{...register("description", { | |||
maxLength: 100 | |||
})} | |||
/> | |||
</Grid> | |||
</Grid> | |||
</Box> | |||
</CardContent> | |||
</Card> | |||
) | |||
} | |||
export default QcItemDetails |
@@ -0,0 +1,70 @@ | |||
"use client" | |||
import { saveQcItem, SaveQcItemInputs } from "@/app/api/settings/qcItem/actions"; | |||
import { Stack } from "@mui/material"; | |||
import { useCallback } from "react"; | |||
import { FormProvider, SubmitHandler, useForm } from "react-hook-form"; | |||
import { errorDialogWithContent, submitDialog } from "../Swal/CustomAlerts"; | |||
import { useTranslation } from "react-i18next"; | |||
import { useRouter } from "next/navigation"; | |||
interface Props { | |||
defaultInputs?: SaveQcItemInputs; | |||
} | |||
const QcItemSave: React.FC<Props> = ({ | |||
defaultInputs, | |||
}) => { | |||
const { t } = useTranslation("qcItem") | |||
const router = useRouter() | |||
const formProps = useForm<SaveQcItemInputs>({ | |||
defaultValues: { | |||
...defaultInputs | |||
} | |||
}) | |||
const handleSubmit = useCallback(async (data: SaveQcItemInputs) => { | |||
const response = await saveQcItem(data) | |||
const errors = response.errors | |||
if (errors) { | |||
let errorContents = "" | |||
for (const [key, value] of Object.entries(errors)) { | |||
formProps.setError(key as keyof SaveQcItemInputs, { type: "custom", message: value }) | |||
errorContents = errorContents + t(value) + "<br>" | |||
} | |||
errorDialogWithContent(t("Submit Error"), errorContents, t) | |||
} else { | |||
router.push("/settings/qcItem") | |||
} | |||
}, | |||
[] | |||
) | |||
const onSubmit = useCallback<SubmitHandler<SaveQcItemInputs>>( | |||
async (data) => { | |||
await submitDialog(() => handleSubmit(data), t) | |||
}, [] | |||
) | |||
return ( | |||
<> | |||
<FormProvider {...formProps}> | |||
<Stack | |||
spacing={2} | |||
component={"form"} | |||
onSubmit={formProps.handleSubmit(onSubmit)} | |||
> | |||
</Stack> | |||
</FormProvider> | |||
</> | |||
) | |||
}; | |||
export default QcItemSave; |
@@ -0,0 +1,40 @@ | |||
import Card from "@mui/material/Card"; | |||
import CardContent from "@mui/material/CardContent"; | |||
import Skeleton from "@mui/material/Skeleton"; | |||
import Stack from "@mui/material/Stack"; | |||
import React from "react"; | |||
// Can make this nicer | |||
export const QcItemSaveLoading: React.FC = () => { | |||
return ( | |||
<> | |||
<Card> | |||
<CardContent> | |||
<Stack spacing={2}> | |||
<Skeleton variant="rounded" height={60} /> | |||
<Skeleton variant="rounded" height={60} /> | |||
<Skeleton variant="rounded" height={60} /> | |||
<Skeleton | |||
variant="rounded" | |||
height={50} | |||
width={100} | |||
sx={{ alignSelf: "flex-end" }} | |||
/> | |||
</Stack> | |||
</CardContent> | |||
</Card> | |||
<Card> | |||
<CardContent> | |||
<Stack spacing={2}> | |||
<Skeleton variant="rounded" height={40} /> | |||
<Skeleton variant="rounded" height={40} /> | |||
<Skeleton variant="rounded" height={40} /> | |||
<Skeleton variant="rounded" height={40} /> | |||
</Stack> | |||
</CardContent> | |||
</Card> | |||
</> | |||
); | |||
}; | |||
export default QcItemSaveLoading; |
@@ -0,0 +1,26 @@ | |||
import React from "react" | |||
import QcItemSaveLoading from "./QcItemSaveLoading" | |||
import QcItemSave from "./QcItemSave"; | |||
import { fetchQcItemDetail } from "@/app/api/settings/qcItem"; | |||
interface SubComponents { | |||
Loading: typeof QcItemSaveLoading; | |||
} | |||
type SaveQcItemProps = { | |||
id?: string | |||
} | |||
type Props = SaveQcItemProps | |||
const QcItemSaveWrapper: React.FC<Props> & SubComponents = async ( | |||
props | |||
) => { | |||
const qcItem = props.id ? await fetchQcItemDetail(props.id) : undefined; | |||
return <QcItemSave defaultInputs={qcItem} />; | |||
}; | |||
QcItemSaveWrapper.Loading = QcItemSaveLoading; | |||
export default QcItemSaveWrapper; |
@@ -0,0 +1 @@ | |||
export { default } from "./QcItemSaveWrapper"; |
@@ -0,0 +1,97 @@ | |||
"use client"; | |||
import { Html5QrcodeResult, Html5QrcodeScanner, QrcodeErrorCallback, QrcodeSuccessCallback } from "html5-qrcode"; | |||
import React, { useCallback, useEffect, useMemo, useState } from "react"; | |||
import SearchBox, { Criterion } from "../SearchBox"; | |||
import { useTranslation } from "react-i18next"; | |||
import SearchResults, { Column } from "../SearchResults"; | |||
import EditNote from "@mui/icons-material/EditNote"; | |||
import { QcItemResult } from "@/app/api/settings/qcItem"; | |||
import { useRouter } from "next/navigation"; | |||
import QrCodeScanner from "../QrCodeScanner"; | |||
import { Button } from "@mui/material"; | |||
interface Props { | |||
qcItems: QcItemResult[]; | |||
} | |||
type SearchQuery = Partial<Omit<QcItemResult, "id">>; | |||
type SearchParamNames = keyof SearchQuery; | |||
const qcItemSearch: React.FC<Props> = ({ qcItems }) => { | |||
const { t } = useTranslation("qcItems"); | |||
const router = useRouter(); | |||
// If qcItem searching is done on the server-side, then no need for this. | |||
const [filteredQcItems, setFilteredQcItems] = useState(qcItems); | |||
const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | |||
() => [ | |||
{ label: t("Code"), paramName: "code", type: "text" }, | |||
{ label: t("Name"), paramName: "name", type: "text" }, | |||
], | |||
[t] | |||
); | |||
const onReset = useCallback( | |||
() => { | |||
setFilteredQcItems(qcItems); | |||
}, [qcItems] | |||
); | |||
const onQcItemClick = useCallback( | |||
(qcItem: QcItemResult) => { | |||
router.push(`/edit/${qcItem.id}`); | |||
}, | |||
[router] | |||
); | |||
const columns = useMemo<Column<QcItemResult>[]>( | |||
() => [ | |||
{ | |||
name: "id", | |||
label: t("Details"), | |||
onClick: onQcItemClick, | |||
buttonIcon: <EditNote />, | |||
}, | |||
{ name: "code", label: t("Code") }, | |||
{ name: "name", label: t("Name") }, | |||
], | |||
[t, onQcItemClick] | |||
); | |||
const [isOpenScanner, setOpenScanner] = useState(false) | |||
const onOpenScanner = useCallback(() => { | |||
setOpenScanner(true) | |||
}, []) | |||
const onCloseScanner = useCallback(() => { | |||
setOpenScanner(false) | |||
}, []) | |||
const handleScanSuccess = useCallback((result: string) => { | |||
console.log(result) | |||
}, []) | |||
return ( | |||
<> | |||
<QrCodeScanner isOpen={isOpenScanner} onClose={onCloseScanner} onScanSuccess={handleScanSuccess} /> | |||
<Button onClick={onOpenScanner}>abc</Button> | |||
{/* <SearchBox | |||
criteria={searchCriteria} | |||
onSearch={(query) => { | |||
setFilteredQcItems( | |||
qcItems.filter( | |||
(qi) => | |||
qi.code.toLowerCase().includes(query.code.toLowerCase()) && | |||
qi.name.toLowerCase().includes(query.name.toLowerCase()) | |||
) | |||
); | |||
}} | |||
onReset={onReset} | |||
/> | |||
<SearchResults<QcItemResult> items={filteredQcItems} columns={columns} /> */} | |||
</> | |||
) | |||
}; | |||
export default qcItemSearch; |
@@ -0,0 +1,40 @@ | |||
import Card from "@mui/material/Card"; | |||
import CardContent from "@mui/material/CardContent"; | |||
import Skeleton from "@mui/material/Skeleton"; | |||
import Stack from "@mui/material/Stack"; | |||
import React from "react"; | |||
// Can make this nicer | |||
export const QcCategorySearchLoading: React.FC = () => { | |||
return ( | |||
<> | |||
<Card> | |||
<CardContent> | |||
<Stack spacing={2}> | |||
<Skeleton variant="rounded" height={60} /> | |||
<Skeleton variant="rounded" height={60} /> | |||
<Skeleton variant="rounded" height={60} /> | |||
<Skeleton | |||
variant="rounded" | |||
height={50} | |||
width={100} | |||
sx={{ alignSelf: "flex-end" }} | |||
/> | |||
</Stack> | |||
</CardContent> | |||
</Card> | |||
<Card> | |||
<CardContent> | |||
<Stack spacing={2}> | |||
<Skeleton variant="rounded" height={40} /> | |||
<Skeleton variant="rounded" height={40} /> | |||
<Skeleton variant="rounded" height={40} /> | |||
<Skeleton variant="rounded" height={40} /> | |||
</Stack> | |||
</CardContent> | |||
</Card> | |||
</> | |||
); | |||
}; | |||
export default QcCategorySearchLoading; |
@@ -0,0 +1,23 @@ | |||
import React from "react" | |||
import QcItemSearchLoading from "./QcItemSearchLoading" | |||
import QcItemSearch from "./QcItemSearch"; | |||
import { fetchQcItems } from "@/app/api/settings/qcItem"; | |||
interface SubComponents { | |||
Loading: typeof QcItemSearchLoading; | |||
} | |||
const QcItemSearchWrapper: React.FC & SubComponents = async () => { | |||
const [ | |||
qcItems | |||
] = await Promise.all([ | |||
fetchQcItems() | |||
]); | |||
return <QcItemSearch qcItems={qcItems} />; | |||
}; | |||
QcItemSearchWrapper.Loading = QcItemSearchLoading; | |||
export default QcItemSearchWrapper; |
@@ -0,0 +1 @@ | |||
export { default } from "./QcItemSearchWrapper"; |
@@ -1,8 +1,8 @@ | |||
import { Button, Card, CardContent, Modal, ModalProps, SxProps } from "@mui/material"; | |||
import { Html5QrcodeResult, Html5QrcodeScanner, QrcodeErrorCallback, QrcodeSuccessCallback } from "html5-qrcode"; | |||
import { Button, Card, CardContent, Grid, Modal, ModalProps, Stack, SxProps, Typography } from "@mui/material"; | |||
import { Html5Qrcode, Html5QrcodeCameraScanConfig, Html5QrcodeFullConfig, Html5QrcodeResult, Html5QrcodeScanner, QrcodeErrorCallback, QrcodeSuccessCallback } from "html5-qrcode"; | |||
import { Html5QrcodeError } from "html5-qrcode/esm/core"; | |||
import { Html5QrcodeScannerConfig } from "html5-qrcode/esm/html5-qrcode-scanner"; | |||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; | |||
import React, { RefObject, useCallback, useEffect, useMemo, useRef, useState } from "react"; | |||
const scannerSx: React.CSSProperties = { | |||
position: "absolute", | |||
@@ -16,82 +16,115 @@ const scannerSx: React.CSSProperties = { | |||
type QrCodeScannerProps = { | |||
onScanSuccess: (result: string) => void, | |||
onScanError?: (error: string) => void | |||
} | |||
const scannerConfig: Html5QrcodeScannerConfig = { | |||
fps: 10, | |||
qrbox: { width: 400, height: 400 }, | |||
aspectRatio: 2.5, | |||
onScanError?: (error: string) => void, | |||
isOpen: boolean | |||
} | |||
const QrCodeScanner: React.FC<QrCodeScannerProps> = ({ | |||
onScanSuccess, | |||
onScanError | |||
onScanError, | |||
isOpen | |||
}) => { | |||
const [isScanned, setIsScanned] = useState<boolean>(false) | |||
const [scanner, setScanner] = useState<Html5QrcodeScanner | null>(null) | |||
const [scanner, setScanner] = useState<Html5Qrcode | null>(null) | |||
const scannerConfig: Html5QrcodeFullConfig = { | |||
verbose: false | |||
} | |||
const cameraConfig: Html5QrcodeCameraScanConfig = { | |||
fps: 10, | |||
qrbox: { width: 400, height: 400 }, | |||
// aspectRatio: cardRef.current ? (cardRef.current.offsetWidth / cardRef.current.offsetHeight) : 1.78, | |||
aspectRatio: 2.5 | |||
}; | |||
// MediaTrackConstraintSet | |||
const mediaTrackConstraintSet = { | |||
facingMode: "environment" | |||
} | |||
useEffect(() => { | |||
setScanner(new Html5QrcodeScanner( | |||
setScanner(new Html5Qrcode( | |||
"qr-reader", | |||
scannerConfig, | |||
false | |||
scannerConfig | |||
)) | |||
}, []) | |||
const handleStartScan = useCallback(() => { | |||
setIsScanned(false) | |||
scanner?.resume(); | |||
if (scanner) { | |||
setIsScanned(false) | |||
scanner.resume(); | |||
} | |||
}, [scanner]) | |||
const handleScanSuccess = useCallback<QrcodeSuccessCallback>((decodedText, result) => { | |||
if (scanner) { | |||
console.log(`Decoded text: ${decodedText}`); | |||
// Handle the decoded text as needed | |||
setIsScanned(true) | |||
scanner.pause(); | |||
onScanSuccess(decodedText) | |||
} | |||
}, [scanner, onScanSuccess]) | |||
const handleScanError = useCallback<QrcodeErrorCallback>((errorMessage, error) => { | |||
console.log(`Error: ${errorMessage}`); | |||
if (onScanError) { | |||
onScanError(errorMessage) | |||
} | |||
}, [scanner, onScanError]) | |||
const handleScanClose = useCallback(async () => { | |||
if (scanner) { | |||
console.log("Cleaning up scanner..."); | |||
await scanner.stop() | |||
await scanner.clear() | |||
} | |||
}, [scanner]) | |||
useEffect(() => { | |||
if (scanner) { | |||
console.log("Scanner Instance:", scanner); | |||
const success: QrcodeSuccessCallback = (decodedText, result) => { | |||
console.log(`Decoded text: ${decodedText}`); | |||
// Handle the decoded text as needed | |||
setIsScanned(true) | |||
scanner.pause(); | |||
onScanSuccess(decodedText) | |||
}; | |||
const error: QrcodeErrorCallback = (errorMessage, error) => { | |||
console.log(`Error: ${errorMessage}`); | |||
scanner.start( | |||
mediaTrackConstraintSet, | |||
cameraConfig, | |||
handleScanSuccess, | |||
handleScanError | |||
) | |||
if (onScanError) { | |||
onScanError(errorMessage) | |||
} | |||
}; | |||
try { | |||
scanner.render(success, error); | |||
console.log("Scanner render called"); | |||
} catch (err) { | |||
console.error("Failed to render scanner:", err); | |||
} | |||
return () => { | |||
console.log("Cleaning up scanner..."); | |||
scanner.clear().catch((error) => { | |||
console.error("Failed to clear html5QrcodeScanner. ", error); | |||
}); | |||
handleScanClose() | |||
}; | |||
} | |||
}, [scanner]); | |||
return ( | |||
<> | |||
<div id="qr-reader" hidden={isScanned} /> | |||
<Button | |||
size="small" | |||
onClick={handleStartScan} | |||
variant="contained" | |||
> | |||
{isScanned ? "Re-Scan" : "Stop-Scanning"} | |||
</Button> | |||
<Stack spacing={2}> | |||
<Typography variant="overline" display="block" marginBlockEnd={1} paddingLeft={2}> | |||
{"Title"} | |||
</Typography> | |||
<Grid container columns={{ xs: 6, sm: 12 }}> | |||
<Grid item xs={12} justifyContent={"center"}> | |||
<div style={{textAlign: "center", margin: "auto", justifyContent: "center"}} id="qr-reader" hidden={isScanned} /> | |||
</Grid> | |||
</Grid> | |||
<Stack direction="row" justifyContent={"flex-end"} spacing={2} sx={{ margin: 2 }}> | |||
<Button | |||
size="small" | |||
onClick={handleStartScan} | |||
variant="contained" | |||
sx={{ margin: 2 }} | |||
> | |||
{isScanned ? "Re-Scan" : "Stop-Scanning"} | |||
</Button> | |||
</Stack> | |||
</Stack> | |||
</> | |||
) | |||
} | |||
@@ -1,6 +1,6 @@ | |||
import { Button, CardContent, Card, Modal, SxProps, ModalProps } from "@mui/material"; | |||
import { Button, CardContent, Card, Modal, SxProps, ModalProps, Box, CardActions } from "@mui/material"; | |||
import QrCodeScanner from "./QrCodeScanner"; | |||
import { useCallback } from "react"; | |||
import { useCallback, useRef } from "react"; | |||
const modalSx: SxProps = { | |||
position: "absolute", | |||
@@ -39,7 +39,14 @@ const QrCodeScannerModal: React.FC<QrCodeScannerModalProps> = ({ | |||
<Modal open={isOpen} onClose={onModalClose}> | |||
<Card sx={modalSx}> | |||
<CardContent> | |||
<QrCodeScanner onScanSuccess={onScanSuccess} onScanError={onScanError}/> | |||
<Box | |||
sx={{ | |||
marginInline: -3, | |||
marginBlock: 4, | |||
}} | |||
> | |||
<QrCodeScanner onScanSuccess={onScanSuccess} onScanError={onScanError} isOpen={isOpen}/> | |||
</Box> | |||
</CardContent> | |||
</Card> | |||
</Modal> | |||
@@ -1,7 +1,14 @@ | |||
import Swal from "sweetalert2"; | |||
import Swal, { SweetAlertOptions } from "sweetalert2"; | |||
import "./sweetalert2.css"; | |||
import { TFunction } from "i18next"; | |||
export const msg = (text) => { | |||
export type SweetAlertTitle = string | HTMLElement | JQuery | undefined | |||
export type SweetAlertHtml = string | HTMLElement | JQuery | undefined | |||
export type SweetAlertConfirmButtonText = string | undefined | |||
type Transaction = TFunction<["translation", ...string[]], undefined> | |||
export const msg = (title: SweetAlertTitle) => { | |||
Swal.mixin({ | |||
toast: true, | |||
position: "bottom-end", | |||
@@ -13,68 +20,68 @@ export const msg = (text) => { | |||
toast.onmouseleave = Swal.resumeTimer; | |||
}, | |||
}).fire({ | |||
icon: "Success", | |||
title: text, | |||
icon: "success", | |||
title: title, | |||
}); | |||
}; | |||
export const popup = (text) => { | |||
Swal.fire(text); | |||
export const popup = (options: SweetAlertOptions) => { | |||
Swal.fire(options); | |||
}; | |||
export const successDialog = (text, t) => { | |||
export const successDialog = (title: SweetAlertTitle, t: Transaction) => { | |||
return Swal.fire({ | |||
icon: "success", | |||
title: text, | |||
title: title, | |||
confirmButtonText: t("Confirm"), | |||
showConfirmButton: true, | |||
}); | |||
}; | |||
export const successDialogWithContent = (title, text, t) => { | |||
export const successDialogWithContent = (title: SweetAlertTitle, html: SweetAlertHtml, t: Transaction) => { | |||
return Swal.fire({ | |||
icon: "success", | |||
title: title, | |||
html: text, | |||
html: html, | |||
confirmButtonText: t("Confirm"), | |||
showConfirmButton: true, | |||
}); | |||
}; | |||
export const errorDialog = (text, t) => { | |||
export const errorDialog = (title: SweetAlertTitle, t: Transaction) => { | |||
return Swal.fire({ | |||
icon: "error", | |||
title: text, | |||
title: title, | |||
confirmButtonText: t("Confirm"), | |||
showConfirmButton: true, | |||
}); | |||
}; | |||
export const errorDialogWithContent = (title, text, t) => { | |||
export const errorDialogWithContent = (title: SweetAlertTitle, html: SweetAlertHtml, t: Transaction) => { | |||
return Swal.fire({ | |||
icon: "error", | |||
title: title, | |||
html: text, | |||
html: html, | |||
confirmButtonText: t("Confirm"), | |||
showConfirmButton: true, | |||
}); | |||
}; | |||
export const warningDialog = (text, t) => { | |||
export const warningDialog = (title: SweetAlertTitle, t: Transaction) => { | |||
return Swal.fire({ | |||
icon: "warning", | |||
title: text, | |||
title: title, | |||
confirmButtonText: t("Confirm"), | |||
showConfirmButton: true, | |||
}); | |||
}; | |||
export const submitDialog = async ( | |||
confirmAction, | |||
t, | |||
confirmAction: () => void, | |||
t: Transaction, | |||
{ ...props } = { | |||
title: t("Do you want to submit?"), | |||
confirmButtonText: t("Submit"), | |||
title: t("Do you want to submit?") as SweetAlertTitle, | |||
confirmButtonText: t("Submit") as SweetAlertConfirmButtonText, | |||
} | |||
) => { | |||
// console.log(props) | |||
@@ -97,12 +104,12 @@ export const submitDialog = async ( | |||
}; | |||
export const submitDialogWithWarning = async ( | |||
confirmAction, | |||
t, | |||
confirmAction: () => void, | |||
t: Transaction, | |||
{ ...props } = { | |||
title: t("Do you want to submit?"), | |||
text: t("Warning!"), | |||
confirmButtonText: t("Submit"), | |||
title: t("Do you want to submit?") as SweetAlertTitle, | |||
html: t("Warning!") as SweetAlertHtml, | |||
confirmButtonText: t("Submit") as SweetAlertConfirmButtonText, | |||
} | |||
) => { | |||
// console.log(props) | |||
@@ -110,7 +117,7 @@ export const submitDialogWithWarning = async ( | |||
const result = await Swal.fire({ | |||
icon: "warning", | |||
title: props?.title, | |||
html: props?.text, | |||
html: props?.html, | |||
cancelButtonText: t("Cancel"), | |||
confirmButtonText: props?.confirmButtonText, | |||
showCancelButton: true, | |||
@@ -125,7 +132,7 @@ export const submitDialogWithWarning = async ( | |||
} | |||
}; | |||
export const deleteDialog = async (confirmAction, t) => { | |||
export const deleteDialog = async (confirmAction: () => void, t: Transaction) => { | |||
// const { t } = useTranslation("common") | |||
const result = await Swal.fire({ | |||
icon: "question", |