diff --git a/src/App.tsx b/src/App.tsx index 8c4804f..ff5fff1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,7 @@ import AuthContext from './context/AuthContext'; import connectToBlockchain from './config'; import Layout from '@/pages/layout'; import CandidatePage from './pages/AddCandidatePage'; +import CreateElection from './pages/CreateElection'; function App() { const auth = React.useContext(AuthContext); @@ -61,10 +62,11 @@ function App() { }> home} /> } /> - + + election} /> past election} /> + } /> upcoming election} /> - create election} /> active election} /> } /> diff --git a/src/components/shared/election/create-election.tsx b/src/components/shared/election/create-election.tsx new file mode 100644 index 0000000..82f4bba --- /dev/null +++ b/src/components/shared/election/create-election.tsx @@ -0,0 +1,115 @@ +import { cn } from '@/lib/utils'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import React from 'react'; +import { useForm } from 'react-hook-form'; +import * as z from 'zod'; +import { AddElectionSchema } from '@/schemas'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form'; +import { FormError } from '../Form-error'; +import AuthContext from '@/context/AuthContext'; +import { toast } from 'sonner'; + +export function CreateElectionForm() { + const [error, setError] = React.useState(''); + const [isPending, startTransition] = React.useTransition(); + const auth = React.useContext(AuthContext); + + const { state } = auth; + + const form = useForm>({ + resolver: zodResolver(AddElectionSchema), + defaultValues: { + purpose: '', + }, + }); + + const onSubmit = (values: z.infer) => { + setError(''); + startTransition(async () => { + try { + if (!state.is_admin) { + toast.error('Only admin can create an election!!'); + return; + } + + if (state.instance !== null) { + const totalElections = await state.instance.methods.noOfElections().call(); + for (let i = 1; i <= totalElections; i++) { + const electionData = await state.instance.methods + .getElection(i) + .call({ from: state.account }); + if ( + electionData.purpose && + electionData.purpose.toLowerCase() === values.purpose.toLowerCase() + ) { + toast.error('This election is already created'); + return; + } + } + + console.log('Creating election with purpose:', values.purpose); + await state.instance.methods.createElection(values.purpose).send({ + from: state.account, + gas: 1000000, + }); + + toast.message('Election created successfully', { + description: 'A new election has been created.', + }); + } + } catch (error) { + console.error(`Error: ${error}`); + toast.error('Error occurred while creating the election'); + } + }); + }; + + return ( +
+ +
+

Create an Election

+

+ Enter the purpose of the election below. +

+
+
+
+ ( + + Election Purpose + + + + + + )} + /> +
+ + +
+
+ + ); +} diff --git a/src/pages/CreateElection.tsx b/src/pages/CreateElection.tsx new file mode 100644 index 0000000..af393a5 --- /dev/null +++ b/src/pages/CreateElection.tsx @@ -0,0 +1,15 @@ +import { CreateElectionForm } from '@/components/shared/election/create-election'; + +const CreateElection = () => { + return ( + <> +
+
+ +
+
+ + ); +}; + +export default CreateElection; diff --git a/src/schemas/index.ts b/src/schemas/index.ts index 094c281..354ebe7 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -12,3 +12,7 @@ export const AddCandidateSchema = z.object({ .min(1, 'Election ID must be at least 1') .max(9999, 'Election ID cannot exceed 9999'), }); + +export const AddElectionSchema = z.object({ + purpose: z.string().nonempty('Name is required').min(1, 'Purpose is required').toLowerCase(), +});