Skip to content

Commit e3927c6

Browse files
committed
feat: update contact form styles and add new parm Children to theme components to add blocks
1 parent a407ad0 commit e3927c6

6 files changed

Lines changed: 87 additions & 33 deletions

File tree

src/assets/styles/globals.css

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,63 @@
33
@tailwind utilities;
44
@plugin '@tailwincss/forms';
55

6+
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
7+
8+
[data-theme='dark'] {
9+
.heading-color {
10+
@apply text-slate-300;
11+
}
12+
13+
.card {
14+
@apply bg-white/5;
15+
}
16+
.form-input {
17+
@apply text-white bg-white/5 border-slate-200/5;
18+
}
19+
20+
.form-label {
21+
@apply text-white;
22+
}
23+
24+
.form-submit,
25+
.button {
26+
@apply bg-white hover:bg-white/70 text-zinc-900;
27+
}
28+
29+
.form-message-error {
30+
@apply text-red-400;
31+
}
32+
}
33+
34+
.heading-color {
35+
@apply text-slate-600;
36+
}
37+
38+
.form-input {
39+
@apply border-slate-200 rounded-md;
40+
}
41+
42+
.form-label {
43+
@apply text-sm font-semibold text-zinc-800;
44+
}
45+
46+
.form-submit,
47+
.button {
48+
@apply font-semibold text-sm flex gap-3 items-center justify-center bg-zinc-900 text-white rounded-md px-4 py-3 hover:bg-zinc-800 transition-colors;
49+
}
50+
51+
.form-message-error {
52+
@apply text-red-500 text-xs font-semibold;
53+
}
54+
655
.scrollbar-hide::-webkit-scrollbar {
756
display: none;
857
}
958

59+
.card {
60+
@apply rounded-xl bg-slate-50;
61+
}
62+
1063
.scrollbar-hide {
1164
-ms-overflow-style: none;
1265
scrollbar-width: none;

src/blocks/ContactFormBlock/index.tsx

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { CircleNotch, XCircle } from '@phosphor-icons/react';
2-
import { AnyFormApi, FormApi, useForm } from '@tanstack/react-form';
1+
import { CircleNotch, PaperPlaneTilt, XCircle } from '@phosphor-icons/react';
2+
import { useForm } from '@tanstack/react-form';
33
import { useSendEmail } from '@services/email/hooks/useSendEmail';
44
import z from 'zod';
5-
import { toast, Toaster } from 'sonner';
5+
import { toast } from 'sonner';
66
import { CheckCircle } from '@phosphor-icons/react/dist/ssr';
77

88
const contactFormSchema = z.object({
@@ -52,8 +52,8 @@ function ContactFormBlock() {
5252
}
5353

5454
return (
55-
<div>
56-
<h2 className="text-2xl font-semibold text-gray-700">Contact us</h2>
55+
<div className="card p-6">
56+
<h2 className="heading-color text-2xl font-semibold">Contact us</h2>
5757
<form
5858
className="flex gap-6 flex-col mt-6"
5959
onSubmit={(e) => {
@@ -62,7 +62,7 @@ function ContactFormBlock() {
6262
}}
6363
>
6464
<div className="flex gap-2 flex-col">
65-
<label className="text-sm font-semibold text-zinc-800" htmlFor="name">
65+
<label className="form-label" htmlFor="name">
6666
Name
6767
</label>
6868
<form.Field
@@ -74,11 +74,11 @@ function ContactFormBlock() {
7474
id={fieldName.name}
7575
name={fieldName.name}
7676
value={fieldName.state.value}
77-
className="form-input border-gray-200 rounded-md"
77+
className="form-input"
7878
onChange={(e) => fieldName.handleChange(e.target.value)}
7979
/>
8080
{!fieldName.state.meta.isValid && (
81-
<span className="text-red-500 text-xs font-semibold">
81+
<span className="form-message-error text-xs font-semibold">
8282
{fieldName.state.meta.errors[0]?.message ?? ''}
8383
</span>
8484
)}
@@ -88,10 +88,7 @@ function ContactFormBlock() {
8888
</div>
8989

9090
<div className="flex gap-2 flex-col">
91-
<label
92-
className="text-sm font-semibold text-zinc-800"
93-
htmlFor="email"
94-
>
91+
<label className="form-label" htmlFor="email">
9592
Email
9693
</label>
9794
<form.Field
@@ -103,11 +100,11 @@ function ContactFormBlock() {
103100
id={fieldEmail.name}
104101
name={fieldEmail.name}
105102
value={fieldEmail.state.value}
106-
className="form-input border-gray-200 rounded-md"
103+
className="form-input"
107104
onChange={(e) => fieldEmail.handleChange(e.target.value)}
108105
/>
109106
{!fieldEmail.state.meta.isValid && (
110-
<span className="text-red-500 text-xs font-semibold">
107+
<span className="form-message-error">
111108
{fieldEmail.state.meta.errors[0]?.message ?? ''}
112109
</span>
113110
)}
@@ -117,10 +114,7 @@ function ContactFormBlock() {
117114
</div>
118115

119116
<div className="flex gap-2 flex-col">
120-
<label
121-
className="text-sm font-semibold text-zinc-800"
122-
htmlFor="email"
123-
>
117+
<label className="form-label" htmlFor="email">
124118
Message
125119
</label>
126120
<form.Field
@@ -131,11 +125,11 @@ function ContactFormBlock() {
131125
id={fieldMessage.name}
132126
name={fieldMessage.name}
133127
value={fieldMessage.state.value}
134-
className="form-input border-gray-200 rounded-md"
128+
className="form-input"
135129
onChange={(e) => fieldMessage.handleChange(e.target.value)}
136130
/>
137131
{!fieldMessage.state.meta.isValid && (
138-
<span className="text-red-500 text-xs font-semibold">
132+
<span className="form-message-error">
139133
{fieldMessage.state.meta.errors[0]?.message ?? ''}
140134
</span>
141135
)}
@@ -144,17 +138,13 @@ function ContactFormBlock() {
144138
/>
145139
</div>
146140

147-
<button
148-
className="flex gap-4 items-center justify-center bg-zinc-900 text-white rounded-md px-4 py-2 hover:bg-zinc-800 transition-colors"
149-
type="submit"
150-
>
151-
Send message
141+
<button className="form-submit" type="submit">
142+
Send message <PaperPlaneTilt weight="duotone" />
152143
{status === 'pending' && (
153144
<CircleNotch size={18} weight="regular" className="animate-spin" />
154145
)}
155146
</button>
156147
</form>
157-
<Toaster />
158148
</div>
159149
);
160150
}

src/pages/_app.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ import '@assets/styles/globals.css';
22
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
33

44
import type { AppProps } from 'next/app';
5+
import { Toaster } from 'sonner';
56

67
const queryClient = new QueryClient();
78
export default function App({ Component, pageProps }: AppProps) {
89
return (
910
<QueryClientProvider client={queryClient}>
1011
<Component {...pageProps} />
12+
<Toaster />
1113
</QueryClientProvider>
1214
);
1315
}

src/pages/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Head from 'next/head';
33
import { Alpha } from '@themes/alpha';
44
import { DATA } from '@lib/data';
55
import { GA4 } from '@utils/ga4';
6+
import { ContactFormBlock } from '@blocks/ContactFormBlock';
67

78
export default function Home() {
89
const { user } = DATA;
@@ -22,7 +23,11 @@ export default function Home() {
2223
<meta property="og:description" content={user.bio} />
2324
<meta property="og:type" content="website" />
2425
</Head>
25-
<Alpha data={DATA} />
26+
<Alpha data={DATA}>
27+
<div className="container max-w-lg px-4 flex flex-col gap-6 animate-slide-up">
28+
<ContactFormBlock />
29+
</div>
30+
</Alpha>
2631
{GA4ID && <GA4 ga4Id={GA4ID} />}
2732
</>
2833
);

src/themes/alpha/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import { Header } from './components/Header';
33
import { Montserrat } from 'next/font/google';
44
import { ListingWrapper } from './components/ListingWrapper';
55
import { ContactFormBlock } from '@blocks/ContactFormBlock';
6+
import React, { Children } from 'react';
67

78
const themeFont = Montserrat({ subsets: ['latin'] });
89
interface AlphaProps {
910
data: DataProps;
11+
children?: React.ReactNode;
1012
}
1113

12-
function Alpha({ data }: AlphaProps) {
14+
function Alpha({ data, children }: AlphaProps) {
1315
const { user, categories, links } = data;
1416
return (
1517
<main className={`${themeFont.className} antialiased`}>
@@ -20,9 +22,7 @@ function Alpha({ data }: AlphaProps) {
2022
image={user.image}
2123
/>
2224
<ListingWrapper categories={categories} links={links} />
23-
<div className="container max-w-lg px-4 flex flex-col gap-6 animate-slide-up">
24-
<ContactFormBlock />
25-
</div>
25+
{children}
2626
</main>
2727
);
2828
}

src/themes/dracula/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ import DataProps from '@interfaces/data';
22
import { Header } from './components/Header';
33
import { Montserrat } from 'next/font/google';
44
import { ListingWrapper } from './components/ListingWrapper';
5+
import React from 'react';
56

67
const themeFont = Montserrat({ subsets: ['latin'] });
78
interface DraculaProps {
89
data: DataProps;
10+
children?: React.ReactNode;
911
}
1012

11-
function Dracula({ data }: DraculaProps) {
13+
function Dracula({ data, children }: DraculaProps) {
1214
const { user, categories, links } = data;
1315
return (
1416
<main
15-
className={`${themeFont.className} min-h-screen bg-dracula-background antialiased`}
17+
data-theme="dark"
18+
className={`${themeFont.className} min-h-screen bg-dracula-background antialiased pb-10`}
1619
>
1720
<Header
1821
fullname={user.fullname}
@@ -21,6 +24,7 @@ function Dracula({ data }: DraculaProps) {
2124
image={user.image}
2225
/>
2326
<ListingWrapper categories={categories} links={links} />
27+
{children}
2428
</main>
2529
);
2630
}

0 commit comments

Comments
 (0)