-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix: use layout as a parent element * feat: define a height limit for tables * feat(frontend): create author form
- Loading branch information
1 parent
3854115
commit 8959a44
Showing
16 changed files
with
424 additions
and
92 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,84 @@ | ||
import React, { useState } from "react"; | ||
import { AuthorCreate } from "types/author"; | ||
import Input from "./Form/Input"; | ||
import { SubmitHandler, useForm } from "react-hook-form"; | ||
import { yupResolver } from "@hookform/resolvers/yup" | ||
import AuthorSchema from "./Schemas/AuthorSchema"; | ||
import Form, { FormMessage } from "./Form/Form"; | ||
import ManagementService from "services/managementService"; | ||
|
||
const managementService = new ManagementService() | ||
|
||
|
||
const AuthorForm: React.FC = () => { | ||
const messageInitialState = { value: "", isError: false } | ||
const [isLoading, setIsLoading] = useState(false) | ||
const [message, setMessage] = useState<FormMessage>(messageInitialState) | ||
const { | ||
register, | ||
handleSubmit, | ||
reset, | ||
|
||
formState: { errors }, | ||
} = useForm({ resolver: yupResolver(AuthorSchema) }) | ||
|
||
|
||
|
||
const onSubmit: SubmitHandler<AuthorCreate> = async (data: AuthorCreate) => { | ||
setIsLoading(true) | ||
const author = await managementService.createAuthor(data) | ||
console.log(author, author === undefined) | ||
setMessage({ | ||
value: author ? "Author created with success" : "It wansn't possible to create the author, try again", | ||
isError: author === undefined | ||
}) | ||
setIsLoading(false) | ||
// onReset() | ||
} | ||
|
||
const onReset = () => { | ||
setMessage(messageInitialState) | ||
reset(undefined) | ||
} | ||
|
||
return ( | ||
<Form | ||
onSubmit={handleSubmit(onSubmit)} | ||
onReset={onReset} | ||
title="Author Creation" | ||
description="Enter the author details" | ||
message={message} | ||
isLoading={isLoading}> | ||
<> | ||
<Input | ||
label="Author name" | ||
name="name" | ||
register={register} | ||
errorMessage={errors.name?.message} | ||
/> | ||
|
||
<Input | ||
label="Email address" | ||
name="email" | ||
register={register} | ||
errorMessage={errors.email?.message} | ||
/> | ||
|
||
<Input | ||
label="Nationality" | ||
name="nationality" | ||
register={register} | ||
errorMessage={errors.nationality?.message} | ||
/> | ||
|
||
<Input | ||
label="Birth date" | ||
name="birthDate" | ||
register={register} | ||
errorMessage={errors.birthDate?.message} | ||
/></> | ||
</Form> | ||
) | ||
} | ||
|
||
export default AuthorForm |
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,48 @@ | ||
import React, { ReactNode } from "react"; | ||
import FormControlButtons from "./FormSubmitButtons"; | ||
|
||
export interface FormMessage { | ||
value: string; | ||
isError: boolean; | ||
} | ||
interface FormProps { | ||
title: string; | ||
description: string; | ||
isLoading: boolean; | ||
onSubmit: () => Promise<void>; | ||
onReset: () => void; | ||
message: FormMessage; | ||
children: ReactNode; | ||
} | ||
|
||
const Form: React.FC<FormProps> = ({ title, description, onSubmit, onReset, message, isLoading, children }) => { | ||
return ( | ||
<form onSubmit={onSubmit}> | ||
{message.value && | ||
<div | ||
className={"border px-4 py-3 my-3 rounded relative " + | ||
(message.isError ? "bg-red-100 border-red-400 text-red-700" : "bg-teal-100 border-teal-500 text-teal-900") | ||
} | ||
role="alert" | ||
> | ||
<strong className="font-bold">{message.isError ? "Ops!" : "Yes!"} </strong> | ||
<span className="block sm:inline">{message.value}</span> | ||
</div> | ||
} | ||
<div className="space-y-12"> | ||
<div className="border-b border-gray-900/10 pb-12"> | ||
<h2 className="text-base font-semibold leading-7 text-gray-900">{title}</h2> | ||
<p className="mt-1 text-sm leading-6 text-gray-600">{description}</p> | ||
<hr /> | ||
<div className="mt-5 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6"> | ||
{children} | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<FormControlButtons isLoading={isLoading} reset={onReset} /> | ||
</form > | ||
) | ||
} | ||
|
||
export default Form |
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,34 @@ | ||
|
||
interface FormControlButtonsProps { | ||
reset: () => void; | ||
isLoading: boolean; | ||
} | ||
const FormControlButtons: React.FC<FormControlButtonsProps> = ({ isLoading, reset }) => { | ||
|
||
return ( | ||
<div className="mt-6 flex items-center justify-end gap-x-6"> | ||
<button | ||
type="button" | ||
disabled={isLoading} | ||
className={`text-sm font-semibold leading-6 ${isLoading ? "text-gray-200" : "text-gray-900"}`} | ||
onClick={reset} | ||
> | ||
Reset | ||
</button> | ||
<button | ||
type="submit" | ||
disabled={isLoading} | ||
className={`bg-indigo-600 rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm` + | ||
( | ||
isLoading ? " bg-gray-200" : " hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" | ||
) | ||
} | ||
> | ||
{isLoading ? "Loading" : "Save"} | ||
</button> | ||
</div > | ||
) | ||
} | ||
|
||
|
||
export default FormControlButtons |
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,31 @@ | ||
import { InputHTMLAttributes } from "react"; | ||
import { UseFormRegister } from "react-hook-form"; | ||
|
||
interface InputProps extends InputHTMLAttributes<HTMLInputElement> { | ||
label: string; | ||
name: string; | ||
register: UseFormRegister<any>; | ||
errorMessage?: string | ||
} | ||
|
||
const Input: React.FC<InputProps> = ({ label, name, register, errorMessage, ...otherOptions }) => { | ||
|
||
return ( | ||
<div className="sm:col-span-3"> | ||
<label htmlFor={name} className="block text-sm font-medium leading-6 text-gray-900"> | ||
{label} | ||
</label> | ||
<div className="mt-2"> | ||
<input | ||
{...otherOptions} | ||
{...register(name)} | ||
id={name} | ||
className="block w-full rounded-md border-0 py-1.5 px-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" | ||
/> | ||
<p className="text-red-500 text-xs italic">{errorMessage}</p> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
export default Input |
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 |
---|---|---|
@@ -1,14 +1,14 @@ | ||
import { Navbar } from "./Navbar/Navbar"; | ||
import { Outlet } from "react-router-dom"; | ||
import { Navbar } from "./Navbar"; | ||
|
||
interface LayoutProps { | ||
element: React.ReactNode; | ||
} | ||
|
||
const Layout: React.FC<LayoutProps> = ({ element }) => ( | ||
const Layout: React.FC = () => ( | ||
<> | ||
<Navbar /> | ||
{element} | ||
<div className="sm:rounded-lg w-1/2 mx-auto mt-4"> | ||
<Outlet /> | ||
</div> | ||
</> | ||
); | ||
|
||
export default Layout; | ||
export default Layout | ||
|
File renamed without changes.
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,13 @@ | ||
import * as yup from "yup" | ||
|
||
const AuthorSchema = yup | ||
.object({ | ||
name: yup.string().required().min(1).max(300), | ||
email: yup.string().email().min(1).max(320), | ||
nationality: yup.string().min(1).max(100), | ||
birthDate: yup.string().matches(/^(?:(?:19|20)\d{2})-(?:(?:0[1-9]|1[0-2]))-(?:(?:0[1-9]|[12]\d|3[01]))$/, { message: "Follow the format AAAA-MM-DD" }), | ||
}) | ||
.required() | ||
|
||
|
||
export default AuthorSchema |
Oops, something went wrong.