Add contact form
This commit is contained in:
19
src/Client/src/components/Button.tsx
Normal file
19
src/Client/src/components/Button.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
type: "submit" | "button";
|
||||||
|
children: ReactNode;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Button({ type, children, onClick }: Props) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type={type}
|
||||||
|
onClick={onClick}
|
||||||
|
className="flex items-center justify-center border-0 ring-1 ring-inset ring-gray-300 bg-black px-3.5 py-2.5 text-sm font-semibold text-white shadow hover:bg-gray-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-600 disabled:bg-gray-800 disabled:cursor-progress"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
58
src/Client/src/components/ContactForm.tsx
Normal file
58
src/Client/src/components/ContactForm.tsx
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { FaRegPaperPlane } from "react-icons/fa6";
|
||||||
|
import Link from "./Link";
|
||||||
|
import TextInput from "./TextInput";
|
||||||
|
import TextAreaInput from "./TextAreaInput";
|
||||||
|
import Button from "./Button";
|
||||||
|
import Label from "./Label";
|
||||||
|
|
||||||
|
export default function ContactForm() {
|
||||||
|
return (
|
||||||
|
<div className="mx-auto max-w-xl py-4">
|
||||||
|
<form
|
||||||
|
onSubmit={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
console.log("Submitted");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="grid grid-cols-1 gap-x-8 gap-y-6 sm:grid-cols-2">
|
||||||
|
<div className="sm:col-span-2">
|
||||||
|
<Label htmlFor="name">Name</Label>
|
||||||
|
<div className="mt-2.5">
|
||||||
|
<TextInput id="name" type="text" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="sm:col-span-2">
|
||||||
|
<Label htmlFor="email">Email</Label>
|
||||||
|
<div className="mt-2.5">
|
||||||
|
<TextInput id="email" type="email" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="sm:col-span-2">
|
||||||
|
<Label htmlFor="message">Message</Label>
|
||||||
|
<div className="mt-2.5">
|
||||||
|
<TextAreaInput id="message" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<small>
|
||||||
|
This site is protected by reCAPTCHA and the Google{" "}
|
||||||
|
<Link href="https://policies.google.com/privacy" target="_blank">
|
||||||
|
Privacy Policy
|
||||||
|
</Link>{" "}
|
||||||
|
and{" "}
|
||||||
|
<Link href="https://policies.google.com/terms" target="_blank">
|
||||||
|
Terms of Service
|
||||||
|
</Link>{" "}
|
||||||
|
apply.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 flex items-center justify-center">
|
||||||
|
<Button type="submit">
|
||||||
|
<FaRegPaperPlane className="mr-2" /> Send
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
12
src/Client/src/components/Label.tsx
Normal file
12
src/Client/src/components/Label.tsx
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
interface Props {
|
||||||
|
htmlFor: string;
|
||||||
|
children: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Label({ htmlFor, children }: Props) {
|
||||||
|
return (
|
||||||
|
<label htmlFor={htmlFor} className="block font-semibold leading-6">
|
||||||
|
{children}
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
}
|
||||||
14
src/Client/src/components/TextAreaInput.tsx
Normal file
14
src/Client/src/components/TextAreaInput.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
interface Props {
|
||||||
|
id: string;
|
||||||
|
rows?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TextAreaInput({ id, rows = 4 }: Props) {
|
||||||
|
return (
|
||||||
|
<textarea
|
||||||
|
id={id}
|
||||||
|
rows={rows}
|
||||||
|
className="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600"
|
||||||
|
></textarea>
|
||||||
|
);
|
||||||
|
}
|
||||||
14
src/Client/src/components/TextInput.tsx
Normal file
14
src/Client/src/components/TextInput.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
interface Props {
|
||||||
|
id: string;
|
||||||
|
type: "text" | "email";
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TextInput({ id, type }: Props) {
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
id={id}
|
||||||
|
type={type}
|
||||||
|
className="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Title({ children, className }: Props) {
|
export default function Title({ children, className }: Props) {
|
||||||
const defaultStyles = "text-4xl";
|
const defaultStyles = "text-4xl py-4";
|
||||||
const styles = className ? `${defaultStyles} ${className}` : defaultStyles;
|
const styles = className ? `${defaultStyles} ${className}` : defaultStyles;
|
||||||
|
|
||||||
return <h1 className={styles}>{children}</h1>;
|
return <h1 className={styles}>{children}</h1>;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import ContactForm from "../components/ContactForm";
|
||||||
import Text from "../components/Text";
|
import Text from "../components/Text";
|
||||||
import Title from "../components/Title";
|
import Title from "../components/Title";
|
||||||
|
|
||||||
@@ -5,10 +6,11 @@ export default function ContactPage() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Title className="text-center">Contact</Title>
|
<Title className="text-center">Contact</Title>
|
||||||
<Text className="text-center py-8">
|
<Text className="text-center pb-8">
|
||||||
If you think I can help with your project or you'd just like to talk
|
If you think I can help with your project or you'd just like to talk
|
||||||
tech, send me a message!
|
tech, send me a message!
|
||||||
</Text>
|
</Text>
|
||||||
|
<ContactForm />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user