Skip to content

Commit

Permalink
Merge pull request #22 from informatyzacja/21-formularz-do-dodawania-…
Browse files Browse the repository at this point in the history
…organizacji

feat: add create organization page
  • Loading branch information
Rei-x authored Feb 13, 2023
2 parents a12bd1e + 65a7bb5 commit 83551f5
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 2 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
"plugins": ["@typescript-eslint"],
"extends": ["next/core-web-vitals", "plugin:@typescript-eslint/recommended"],
"rules": {
"@typescript-eslint/consistent-type-imports": "warn"
"@typescript-eslint/consistent-type-imports": "warn",
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksVoidReturn": false
}
]
}
}
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
postgres-data/
prisma/generated/zod/index.ts
1 change: 1 addition & 0 deletions nextjs-routes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ declare module "nextjs-routes" {
| StaticRoute<"/admin">
| DynamicRoute<"/admin/organizacje/[slug]", { "slug": string }>
| StaticRoute<"/admin/organizacje">
| StaticRoute<"/admin/organizacje/stworz">
| DynamicRoute<"/api/auth/[...nextauth]", { "nextauth": string[] }>
| DynamicRoute<"/api/trpc/[trpc]", { "trpc": string }>
| StaticRoute<"/">
Expand Down
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@chakra-ui/react": "^2.4.9",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@hookform/resolvers": "^2.9.11",
"@next-auth/prisma-adapter": "^1.0.5",
"@next/font": "^13.1.6",
"@prisma/client": "^4.9.0",
Expand All @@ -37,6 +38,7 @@
"nextjs-routes": "^1.0.8",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.43.1",
"react-icons": "^4.7.1",
"slugify": "^1.6.5",
"superjson": "1.9.1",
Expand Down
3 changes: 2 additions & 1 deletion src/features/admin/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HomePage } from "./views";
import { EditPage } from "./views/edit";
import { CreatePage } from "./views/create";

export { HomePage, EditPage };
export { HomePage, EditPage, CreatePage };
189 changes: 189 additions & 0 deletions src/features/admin/views/create.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import { AnimatePresenceSSR } from "@/components/AnimatePresenceSSR";
import { useForm } from "@/hooks/useForm";
import {
Button,
FormControl,
FormErrorMessage,
FormLabel,
Heading,
Input,
NumberDecrementStepper,
NumberIncrementStepper,
NumberInput,
NumberInputField,
NumberInputStepper,
Select,
Switch,
Textarea,
useToast,
VStack,
} from "@chakra-ui/react";
import { motion } from "framer-motion";
import React, { useState } from "react";
import { z } from "zod";
import { Layout } from "../components/Layout";

const departments = [
"W1",
"W2",
"W3",
"W4",
"W5",
"W6",
"W7",
"W8",
"W9",
"W10",
"W11",
"W12",
] as const;

const schema = z.object({
email: z.string().email(),
addManualy: z.boolean().default(false),
name: z.string().default(""),
residence: z.enum(departments).default("W1"),
foundationDate: z.date().default(new Date()),
description: z.string().default(""),
long_description: z.string().optional().default(""),
number_of_users: z.number().optional().default(0),
});

export const CreatePage = () => {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm({
schema,
});
const toast = useToast({
status: "success",
});
const [showAdditionalInfo, setShowAdditionalInfo] = useState(false);

return (
<Layout>
<Heading mb={4}>Stwórz organizacje</Heading>
<form
onSubmit={handleSubmit(() => {
toast({
title: "Organizacja została dodana",
});
})}
>
<VStack spacing={0} maxW={{ base: "100%", md: "600px" }} align="start">
<FormControl isRequired isInvalid={errors.email !== undefined} mb={4}>
<FormLabel>Email organizacji</FormLabel>
<Input
{...register("email")}
variant=""
placeholder="Email organizacji"
/>
<FormErrorMessage>
{errors.email?.message && "Niepoprawny email"}
</FormErrorMessage>
</FormControl>
<FormControl display="flex" alignItems="center" pb={4}>
<FormLabel htmlFor="additional-info" mb="0">
Czy chcesz sam(a) uzupełniać dane?
</FormLabel>
<Switch
{...register("addManualy")}
id="additional-info"
checked={showAdditionalInfo}
onChange={(e) => {
setShowAdditionalInfo(e.target.checked);
}}
/>
</FormControl>
<AnimatePresenceSSR mode="wait">
{showAdditionalInfo ? (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: "auto" }}
exit={{ opacity: 0, height: 0 }}
transition={{
type: "spring",
duration: 1,
}}
style={{
width: "100%",
}}
>
<VStack align="start" mt={2} mb={6} w="100%">
<FormControl isRequired>
<FormLabel>Nazwa organizacji</FormLabel>
<Input
{...register("name")}
variant=""
placeholder="Nazwa organizacji"
/>
<FormErrorMessage>
{errors.name?.message &&
"Nieprawidłowa nazwa organizacji"}
</FormErrorMessage>
</FormControl>
<FormControl isRequired>
<FormLabel>Wydział</FormLabel>
<Select {...register("residence")} variant="">
{departments.map((department) => (
<option key={department} value={department}>
{department}
</option>
))}
</Select>
<FormErrorMessage>
{errors.residence?.message && "Nieprawidłowy wydział"}
</FormErrorMessage>
</FormControl>
<FormControl isRequired>
<FormLabel>Krótki opis</FormLabel>
<Textarea
{...register("description")}
variant=""
placeholder="Opis"
/>
<FormErrorMessage>
{errors.description?.message && "Nieprawidłowy opis"}
</FormErrorMessage>
</FormControl>
<FormControl>
<FormLabel>Długi opis</FormLabel>
<Textarea
{...register("long_description")}
variant=""
placeholder="Opis"
/>
</FormControl>
<FormControl>
<FormLabel>Liczba członków</FormLabel>
<NumberInput variant="">
<NumberInputField />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<FormErrorMessage>
{errors.number_of_users?.message &&
"Nieprawidłowa ilość członków"}
</FormErrorMessage>
</FormControl>
</VStack>
</motion.div>
) : null}
</AnimatePresenceSSR>
<Button
mt={6}
type="submit"
colorScheme="blue"
isLoading={isSubmitting}
>
Dodaj
</Button>
</VStack>
</form>
</Layout>
);
};
13 changes: 13 additions & 0 deletions src/features/admin/views/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
Th,
Tbody,
Td,
Button,
HStack,
} from "@chakra-ui/react";
import React, { useState } from "react";
import { Layout } from "../components/Layout";
Expand Down Expand Up @@ -73,6 +75,17 @@ export const HomePage = () => {

return (
<Layout>
<HStack justify="flex-end">
<Button
variant="solid"
colorScheme="blue"
onClick={() => {
void router.push("/admin/organizacje/stworz");
}}
>
Stwórz nową
</Button>
</HStack>
<TableContainer>
<Table variant="simple" colorScheme="blackAlpha">
<TableCaption>Wszystkie organizacje</TableCaption>
Expand Down
21 changes: 21 additions & 0 deletions src/hooks/useForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { FieldValues, UseFormProps, UseFormReturn } from "react-hook-form";
import { useForm as rhUseForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import type { ZodType, z } from "zod";

export const useForm = <
// eslint-disable-next-line @typescript-eslint/no-explicit-any
T extends ZodType<any, any, any>,
TFieldValues extends FieldValues = z.infer<typeof schema>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
TContext = any
>(
props: UseFormProps<TFieldValues, TContext> & { schema: T }
): UseFormReturn<TFieldValues, TContext> => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { schema, resolver: _resolver, ...rest } = props;
return rhUseForm<TFieldValues, TContext>({
resolver: zodResolver(schema),
...rest,
});
};
3 changes: 3 additions & 0 deletions src/pages/admin/organizacje/stworz.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { CreatePage } from "@/features/admin";

export default CreatePage;

0 comments on commit 83551f5

Please sign in to comment.