Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 7 additions & 15 deletions apps/web/app/auth/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import { useState, FormEvent } from "react";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";

function validateEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}

import { authSchema } from "@/lib/validation";
export default function AuthPage() {
const [email, setEmail] = useState("");
const [error, setError] = useState("");
Expand All @@ -19,13 +14,9 @@ export default function AuthPage() {
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();

if (!email) {
setError("Email is required");
return;
}

if (!validateEmail(email)) {
setError("Enter a valid email");
const result = authSchema.safeParse({ email });
if (!result.success) {
setError(result.error.issues[0].message);
return;
}

Expand Down Expand Up @@ -105,10 +96,10 @@ export default function AuthPage() {
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full bg-white border-2 border-black rounded-full px-4 py-2 mb-4 outline-none"
className="w-full bg-white border-2 border-black rounded-full px-4 py-2 mb-4 outline-none"
/>

{error && <p className="text-xs text-red-500 mb-3">{error}</p>}
{error && <p className="text-xs text-red-500 mb-3 mt-1">{error}</p>}

<Button
type="submit"
Expand All @@ -123,6 +114,7 @@ export default function AuthPage() {
font-medium
flex items-center justify-center gap-2
mb-4
mt-3
border-2 border-black
shadow-[0_4px_0_#000]
active:translate-y-[2px]
Expand Down
70 changes: 26 additions & 44 deletions apps/web/app/create-event/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,9 @@ import { Navbar } from "@/components/layout/navbar";
import { Footer } from "@/components/layout/footer";
import { Button } from "@/components/ui/button";
import { toast } from "sonner";
import { createEventSchema, CreateEventInput } from "@/lib/validation";
import { useIsMounted } from "@/hooks/useIsMounted";
import { z } from "zod";

const createEventSchema = z.object({
title: z.string().trim().min(1, "Event title is required"),
startDate: z.string().min(1, "Start date is required"),
startTime: z.string().min(1, "Start time is required"),
endDate: z.string().optional(),
endTime: z.string().optional(),
location: z.string().trim().min(1, "Location is required"),
description: z.string().optional(),
capacity: z
.string()
.optional()
.refine((value) => !value || Number.parseInt(value, 10) > 0, {
message: "Capacity must be greater than 0",
}),
price: z
.string()
.trim()
.min(1, "Price is required (put 0 for free)")
.refine((value) => Number.parseFloat(value) >= 0, {
message: "Price cannot be negative",
}),
visibility: z.enum(["Public", "Private"]),
});

type CreateEventInput = z.infer<typeof createEventSchema>;


export default function CreateEventPage() {
const router = useRouter();
Expand Down Expand Up @@ -221,6 +196,12 @@ export default function CreateEventPage() {
</div>
</div>

{(errors.startDate || errors.startTime) && (
<span className="text-red-500 text-xs font-bold mt-1 ml-10">
{errors.startDate || errors.startTime}
</span>
)}

<div className="flex items-center mt-[18px]">
<div className="w-[10px] h-[10px] rounded-[10px] border border-dark-deep/50 bg-transparent shrink-0 relative z-10 ml-3" />
<span className="text-[15px] font-semibold w-12 text-black ml-3 leading-[24px]">
Expand Down Expand Up @@ -442,27 +423,29 @@ export default function CreateEventPage() {
{errors.price && <span className="text-red-500 text-sm font-bold absolute bottom-2 left-6">{errors.price}</span>}
</div>

<div className="flex justify-end gap-4 mt-6 mr-4">
<div className="flex justify-end gap-4 mt-6 mr-4">
<Button
type="button"
variant="secondary"
className="w-[212px] h-[50px] rounded-[32px]"
onClick={() => setFormData({
title: "",
startDate: "",
startTime: "",
endDate: "",
endTime: "",
location: "",
description: "",
capacity: "",
price: "",
visibility: "Public",
})}
onClick={() => {
setFormData({
title: "",
startDate: "",
startTime: "",
endDate: "",
endTime: "",
location: "",
description: "",
capacity: "",
price: "",
visibility: "Public",
});
setErrors({});
}}
>
Clear Event
</Button>

<Button
type="submit"
variant="primary"
Expand All @@ -480,11 +463,10 @@ export default function CreateEventPage() {
)}
</Button>
</div>
</div>
</div>
</div>
</form>

<Footer />
</main>
);
}
}
4 changes: 2 additions & 2 deletions apps/web/app/home/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"use client";
"use client";

import { useState } from "react";
import { motion } from "framer-motion";
Expand Down Expand Up @@ -585,7 +585,7 @@ function MyEventsContent({ activeTab }: { activeTab: MyEventsTab }) {
{/* CTA Section */}
<div className="flex flex-col items-center gap-4">
<p className="text-xl font-medium leading-5.5 text-center text-ink-deep/36">
You haven't created any events yet
You haven&apos;t created any events yet
</p>
<Link href="/create-event">
<Button variant="dark" className="rounded-full">
Expand Down
35 changes: 35 additions & 0 deletions apps/web/lib/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { z } from "zod";

export const authSchema = z.object({
email: z
.string()
.min(1, "Email is required")
.email("Enter a valid email"),
});

export const createEventSchema = z.object({
title: z.string().trim().min(1, "Event title is required"),
startDate: z.string().min(1, "Start date is required"),
startTime: z.string().min(1, "Start time is required"),
endDate: z.string().optional(),
endTime: z.string().optional(),
location: z.string().trim().min(1, "Location is required"),
description: z.string().optional(),
capacity: z
.string()
.optional()
.refine((value) => !value || Number.parseInt(value, 10) > 0, {
message: "Capacity must be greater than 0",
}),
price: z
.string()
.trim()
.min(1, "Price is required (put 0 for free)")
.refine((value) => Number.parseFloat(value) >= 0, {
message: "Price cannot be negative",
}),
visibility: z.enum(["Public", "Private"]),
});

export type AuthFormData = z.infer<typeof authSchema>;
export type CreateEventInput = z.infer<typeof createEventSchema>;
Loading
Loading