-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c4b48d7
commit 8eb06f1
Showing
12 changed files
with
355 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"use server"; | ||
|
||
import { apiConfig } from "@/lib/apiConfig"; | ||
import { apiHandler } from "@/lib/apiHandler"; | ||
import { CreateVariableDto } from "@/rules/validations"; | ||
import { SeverActionResponse, Variables } from "@/types"; | ||
import { getErrorMessage } from "@/utils/helpers"; | ||
import { Tags } from "@/utils/tags"; | ||
import { revalidateTag } from "next/cache"; | ||
|
||
export async function getVariables(): Promise< | ||
SeverActionResponse<Variables[]> | ||
> { | ||
try { | ||
const endpoint = apiConfig.variables.root(); | ||
const variables = await apiHandler<Variables[]>({ | ||
endpoint, | ||
method: "GET", | ||
next: { tags: [Tags.variables] }, | ||
}); | ||
return { results: variables }; | ||
} catch (error) { | ||
return { error: getErrorMessage(error) }; | ||
} | ||
} | ||
export async function createVariables(data: CreateVariableDto) { | ||
try { | ||
const endpoint = apiConfig.variables.root(); | ||
await apiHandler<Variables[]>({ | ||
endpoint, | ||
method: "POST", | ||
body: data, | ||
}); | ||
revalidateTag(Tags.variables); | ||
} catch (error) { | ||
return { error: getErrorMessage(error) }; | ||
} | ||
} | ||
export async function updateVariables(id: string, data: CreateVariableDto) { | ||
try { | ||
const endpoint = apiConfig.variables.get(id); | ||
await apiHandler<Variables[]>({ | ||
endpoint, | ||
method: "PATCH", | ||
body: data, | ||
}); | ||
revalidateTag(Tags.variables); | ||
} catch (error) { | ||
return { error: getErrorMessage(error) }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
src/app/(dashboard)/variables/_sections/AddVariableForm.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import { createVariables, updateVariables } from "@/actions/variables"; | ||
import TextField from "@/components/shared/input/TextField"; | ||
import { useReactHookForm } from "@/hooks/useReactHookForm"; | ||
import { useServerAction } from "@/hooks/useServerAction"; | ||
import { CreateVariableDto, createVariableSchema } from "@/rules/validations"; | ||
import { Variables } from "@/types"; | ||
import { getErrorMessage } from "@/utils/helpers"; | ||
import { | ||
Button, | ||
Modal, | ||
ModalBody, | ||
ModalContent, | ||
ModalFooter, | ||
ModalHeader, | ||
} from "@nextui-org/react"; | ||
import { useEffect } from "react"; | ||
import { toast } from "sonner"; | ||
|
||
interface Props { | ||
isOpen: boolean; | ||
onClose: () => void; | ||
variable: Variables | null; | ||
} | ||
export default function AddVariableForm(props: Props) { | ||
const { isOpen, onClose, variable } = props; | ||
|
||
const { control, handleSubmit, reset, setValue, clearErrors } = | ||
useReactHookForm<CreateVariableDto>(createVariableSchema); | ||
|
||
const [runCreateVariable, { loading }] = useServerAction< | ||
any, | ||
typeof createVariables | ||
>(createVariables); | ||
const [runUpdateVariable, { loading: updating }] = useServerAction< | ||
any, | ||
typeof updateVariables | ||
>(updateVariables); | ||
|
||
useEffect(() => { | ||
setValue("label", variable?.label ?? ""); | ||
setValue("value", variable?.value ?? ""); | ||
}, [variable]); | ||
|
||
const actionFunction = async (data: CreateVariableDto) => | ||
variable | ||
? await runUpdateVariable(variable.id, data) | ||
: await runCreateVariable(data); | ||
|
||
const onSubmit = async (data: CreateVariableDto) => { | ||
try { | ||
const toastMessage = variable | ||
? "Variable updated" | ||
: "New variable created"; | ||
|
||
const response = await actionFunction(data); | ||
if (response?.error) { | ||
toast.error(response.error); | ||
return; | ||
} | ||
toast.success(toastMessage); | ||
reset(); | ||
onClose(); | ||
} catch (error) { | ||
toast.error(getErrorMessage(error)); | ||
} | ||
}; | ||
|
||
return ( | ||
<Modal size={"md"} isOpen={isOpen} onClose={onClose} isDismissable={false}> | ||
<ModalContent> | ||
{(onClose) => ( | ||
<> | ||
<ModalHeader className='flex flex-col gap-1'>Variables</ModalHeader> | ||
<ModalBody> | ||
<TextField | ||
control={control} | ||
name='label' | ||
defaultValue={variable?.label} | ||
label='Label' | ||
variant='bordered' | ||
labelPlacement='outside' | ||
radius='sm' | ||
placeholder='Label' | ||
/> | ||
<TextField | ||
control={control} | ||
name='value' | ||
defaultValue={variable?.value} | ||
label='Value' | ||
variant='bordered' | ||
labelPlacement='outside' | ||
radius='sm' | ||
placeholder='Value' | ||
/> | ||
</ModalBody> | ||
<ModalFooter> | ||
<Button | ||
radius='sm' | ||
color='danger' | ||
variant='light' | ||
onPress={onClose} | ||
// isDisabled={loading || updating} | ||
> | ||
Cancel | ||
</Button> | ||
<Button | ||
onClick={handleSubmit(onSubmit)} | ||
radius='sm' | ||
color='primary' | ||
isLoading={loading || updating} | ||
> | ||
Proceed | ||
</Button> | ||
</ModalFooter> | ||
</> | ||
)} | ||
</ModalContent> | ||
</Modal> | ||
); | ||
} |
55 changes: 55 additions & 0 deletions
55
src/app/(dashboard)/variables/_sections/VariableSection.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
"use client"; | ||
import HStack from "@/components/shared/layout/HStack"; | ||
import { Variables } from "@/types"; | ||
import { pluralize } from "@/utils/helpers"; | ||
import { Button, useDisclosure } from "@nextui-org/react"; | ||
import VariablesTable from "./VariablesTable"; | ||
import { useState } from "react"; | ||
import AddVariableForm from "./AddVariableForm"; | ||
|
||
interface Props { | ||
variables: Variables[]; | ||
} | ||
export default function VariableSection({ variables }: Props) { | ||
const [selectedVariable, setSelectedVariable] = useState<Variables | null>( | ||
null, | ||
); | ||
const { onOpen, isOpen, onClose } = useDisclosure(); | ||
const totalVariables = variables?.length; | ||
return ( | ||
<div> | ||
<HStack className='items-center justify-between mb-3'> | ||
<h3 className='font-semibold text-xl'> | ||
{totalVariables} {pluralize("Variable", totalVariables)} | ||
</h3> | ||
<Button | ||
radius='sm' | ||
size='md' | ||
color='primary' | ||
disableRipple | ||
className='font-semibold' | ||
onClick={() => { | ||
setSelectedVariable(null); | ||
onOpen(); | ||
}} | ||
> | ||
Add Variable | ||
</Button> | ||
</HStack> | ||
<VariablesTable | ||
variables={variables} | ||
onEdit={(variable) => { | ||
setSelectedVariable(variable); | ||
onOpen(); | ||
}} | ||
/> | ||
<AddVariableForm | ||
isOpen={isOpen} | ||
onClose={() => { | ||
onClose(); | ||
}} | ||
variable={selectedVariable} | ||
/> | ||
</div> | ||
); | ||
} |
81 changes: 81 additions & 0 deletions
81
src/app/(dashboard)/variables/_sections/VariablesTable.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
"use client"; | ||
import EmptyContent from "@/components/shared/EmptyContent"; | ||
import HStack from "@/components/shared/layout/HStack"; | ||
import { Variables } from "@/types"; | ||
import { pluralize } from "@/utils/helpers"; | ||
import { | ||
Button, | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableColumn, | ||
TableHeader, | ||
TableRow, | ||
useDisclosure, | ||
} from "@nextui-org/react"; | ||
import { PencilIcon, Trash2Icon } from "lucide-react"; | ||
import React, { useState } from "react"; | ||
|
||
interface Props { | ||
variables: Variables[]; | ||
onEdit: (variable: Variables) => void; | ||
} | ||
export default function VariablesTable({ variables, onEdit }: Props) { | ||
const [selectedVariable, setSelectedVariable] = useState<Variables | null>( | ||
null, | ||
); | ||
const { onOpen, isOpen, onClose } = useDisclosure(); | ||
|
||
return ( | ||
<div className='border p-3 rounded-md'> | ||
<Table aria-label='list of variables' shadow='none' radius='none'> | ||
<TableHeader> | ||
<TableColumn className='w-1/2'>Name</TableColumn> | ||
<TableColumn>Value</TableColumn> | ||
<TableColumn>{null}</TableColumn> | ||
</TableHeader> | ||
<TableBody | ||
emptyContent={ | ||
<EmptyContent | ||
// img={illustration_empty_content} | ||
title='' | ||
description='No Variables added' | ||
/> | ||
} | ||
> | ||
{variables.map((variable) => ( | ||
<TableRow key={variable?.id}> | ||
<TableCell>{variable?.label}</TableCell> | ||
<TableCell>{variable?.value}</TableCell> | ||
<TableCell> | ||
<HStack className='items-center justify-end'> | ||
<Button | ||
radius='sm' | ||
size='sm' | ||
disableRipple | ||
color='danger' | ||
onClick={() => setSelectedVariable(variable)} | ||
isIconOnly | ||
disabled | ||
> | ||
<Trash2Icon className='text-white' size={15} /> | ||
</Button> | ||
<Button | ||
radius='sm' | ||
size='sm' | ||
disableRipple | ||
color='success' | ||
onClick={() => onEdit(variable)} | ||
isIconOnly | ||
> | ||
<PencilIcon className='text-white' size={20} /> | ||
</Button> | ||
</HStack> | ||
</TableCell> | ||
</TableRow> | ||
))} | ||
</TableBody> | ||
</Table> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from "react"; | ||
import VariablesTable from "./_sections/VariablesTable"; | ||
import { getVariables } from "@/actions/variables"; | ||
import WithServerError from "@/components/hoc/WithServerError"; | ||
import VariableSection from "./_sections/VariableSection"; | ||
|
||
export default async function Variables() { | ||
const { error, results } = await getVariables(); | ||
return ( | ||
<WithServerError error={error}> | ||
<div className='bg-white h-screen px-5 pt-5'> | ||
<VariableSection variables={results!} /> | ||
</div> | ||
</WithServerError> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { z } from "zod"; | ||
|
||
export const createVariableSchema = z.object({ | ||
label: z.string({ required_error: "variable name is required" }), | ||
value: z.string({ required_error: "variable value is required" }), | ||
}); | ||
|
||
export type CreateVariableDto = z.infer<typeof createVariableSchema>; |
Oops, something went wrong.