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
85 changes: 36 additions & 49 deletions apps/web/src/app/(app)/events/[id]/edit/edit-event-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { useRouter } from "next/navigation";
import { useCallback, useRef, useState, useTransition } from "react";
import { type EventDetail, updateEvent } from "~/actions/events";
import { getPresignedUploadUrl } from "~/actions/upload";
import { PageShell } from "~/components/layout/page-shell";
import { Button } from "~/components/ui/button";
import { Calendar } from "~/components/ui/calendar";
import { Input } from "~/components/ui/input";
import { Popover, PopoverContent, PopoverTrigger } from "~/components/ui/popover";
Expand Down Expand Up @@ -163,33 +165,21 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
};

return (
<div className="px-[40px] py-[20px] max-w-[1100px] mx-auto">
<PageShell width="wide">
{/* Top buttons */}
<div className="flex items-center justify-between mb-[30px] pr-[100px]">
<div className="flex items-center gap-[10px]">
<button
type="button"
onClick={() => router.back()}
className="px-[16px] py-[8px] border border-forum-medium-gray rounded-[6px] text-[11px] font-bold font-dm-sans text-forum-dark-gray tracking-wider hover:border-forum-dark-gray transition-colors"
>
CANCEL
</button>
<button
type="button"
className="flex items-center gap-[5px] px-[16px] py-[8px] border border-forum-medium-gray rounded-[20px] text-[11px] font-bold font-dm-sans text-forum-dark-gray tracking-wider hover:border-forum-dark-gray transition-colors"
>
<Eye size={13} />
PREVIEW
</button>
<div className="mb-8 flex flex-wrap items-center justify-between gap-3 pr-[100px]">
<div className="flex items-center gap-2.5">
<Button variant="outline" size="sm" onClick={() => router.back()}>
Cancel
</Button>
<Button variant="outline" size="sm">
<Eye />
Preview
</Button>
</div>
<button
type="button"
onClick={handleSubmit}
disabled={isPending}
className="px-[24px] py-[10px] bg-forum-cerulean text-white text-[12px] font-bold font-dm-sans rounded-[6px] tracking-wider hover:opacity-90 disabled:opacity-50 transition-all"
>
{isPending ? "SAVING..." : "SAVE CHANGES"}
</button>
<Button variant="cerulean" size="cta" onClick={handleSubmit} disabled={isPending}>
{isPending ? "Saving…" : "Save changes"}
</Button>
</div>

<div className="flex gap-[40px]">
Expand Down Expand Up @@ -293,12 +283,12 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
placeholder="Super Interesting Event Title"
className={cn(
"flex-1 text-[32px] font-serif font-bold text-black placeholder:text-forum-placeholder/40 outline-none",
errors.title && "placeholder:text-red-300",
errors.title && "placeholder:text-forum-coral/60",
)}
/>
<Pencil size={16} className="text-forum-cerulean flex-shrink-0 ml-2" />
</div>
{errors.title && <p className="text-[11px] text-red-400 mt-1">{errors.title}</p>}
{errors.title && <p className="text-[11px] text-forum-coral mt-1">{errors.title}</p>}
</div>

{/* Event Description */}
Expand All @@ -316,11 +306,11 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
rows={8}
className={cn(
"border border-forum-medium-gray rounded-[8px] text-[14px] font-dm-sans placeholder:text-forum-placeholder resize-none focus:border-forum-cerulean",
errors.description && "border-red-400",
errors.description && "border-forum-coral",
)}
/>
{errors.description && (
<p className="text-[11px] text-red-400 mt-1">{errors.description}</p>
<p className="text-[11px] text-forum-coral mt-1">{errors.description}</p>
)}
</div>

Expand All @@ -338,7 +328,7 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
className={cn(
"flex items-center gap-2 h-[40px] px-[14px] border border-forum-medium-gray rounded-[8px] text-[13px] font-dm-sans",
date ? "text-black" : "text-forum-placeholder",
errors.date && "border-red-400",
errors.date && "border-forum-coral",
)}
>
<CalendarIcon size={14} />
Expand All @@ -356,7 +346,7 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
/>
</PopoverContent>
</Popover>
{errors.date && <p className="text-[11px] text-red-400 mt-1">{errors.date}</p>}
{errors.date && <p className="text-[11px] text-forum-coral mt-1">{errors.date}</p>}
</div>
<div>
<span className="text-[13px] font-bold text-forum-coral block mb-[6px]">
Expand Down Expand Up @@ -405,7 +395,7 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
placeholder="Search by keyword or address"
className={cn(
"w-full h-[40px] pl-[34px] pr-[14px] border border-forum-medium-gray rounded-[8px] text-[13px] font-dm-sans outline-none focus:border-forum-cerulean",
errors.location && "border-red-400",
errors.location && "border-forum-coral",
)}
/>
</div>
Expand All @@ -426,7 +416,7 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
"w-full text-left px-3 py-2 rounded-md text-sm transition-colors",
locationId === loc.id
? "bg-forum-turquoise/20 text-black"
: "text-forum-dark-gray hover:bg-gray-50",
: "text-forum-dark-gray hover:bg-forum-turquoise/10",
)}
>
{loc.name}
Expand All @@ -435,7 +425,9 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
</div>
</PopoverContent>
</Popover>
{errors.location && <p className="text-[11px] text-red-400 mt-1">{errors.location}</p>}
{errors.location && (
<p className="text-[11px] text-forum-coral mt-1">{errors.location}</p>
)}
</div>

{/* Visibility */}
Expand Down Expand Up @@ -529,25 +521,20 @@ export function EditEventForm({ event, locations }: EditEventFormProps) {
</div>

{/* Bottom actions */}
<div className="flex items-center justify-between pt-[20px] border-t border-forum-medium-gray mb-[40px]">
<button
type="button"
<div className="mb-10 flex flex-wrap items-center justify-between gap-3 border-t border-forum-medium-gray pt-5">
<Button
variant="quiet"
size="sm"
onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
className="flex items-center gap-[4px] text-[11px] font-bold font-dm-sans text-forum-dark-gray tracking-wider"
>
<ArrowUp size={12} /> BACK TO TOP
</button>
<button
type="button"
onClick={handleSubmit}
disabled={isPending}
className="px-[24px] py-[10px] bg-forum-cerulean text-white text-[12px] font-bold font-dm-sans rounded-[6px] tracking-wider hover:opacity-90 disabled:opacity-50 transition-all"
>
{isPending ? "SAVING..." : "SAVE CHANGES"}
</button>
<ArrowUp /> Back to top
</Button>
<Button variant="cerulean" size="cta" onClick={handleSubmit} disabled={isPending}>
{isPending ? "Saving…" : "Save changes"}
</Button>
</div>
</div>
</div>
</div>
</PageShell>
);
}
148 changes: 69 additions & 79 deletions apps/web/src/app/(app)/events/[id]/event-detail-client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import {
toggleRsvp,
toggleSave,
} from "~/actions/events";
import { Panel } from "~/components/common/panel";
import { getCategoryColor } from "~/components/events/event-card";
import { EventCoverArt } from "~/components/events/event-cover-art";
import { PageHeading, PageShell, SectionHeading } from "~/components/layout/page-shell";
import { AvatarStack } from "~/components/social/avatar-stack";
import { Button } from "~/components/ui/button";
import {
Expand Down Expand Up @@ -126,53 +128,47 @@ export function EventDetailClient({ event, similarEvents }: EventDetailClientPro
};

return (
<div className="max-w-5xl mx-auto px-[40px] py-[20px]">
<PageShell>
{/* Back link */}
<button
type="button"
onClick={() => router.back()}
className="flex items-center gap-[6px] text-[14px] font-dm-sans text-forum-light-gray hover:text-forum-dark-gray transition-colors mb-[24px] group"
>
<ChevronLeft size={16} className="group-hover:-translate-x-0.5 transition-transform" />
<Button variant="quiet" size="sm" onClick={() => router.back()} className="mb-6">
<ChevronLeft />
Back
</button>
</Button>

{/* Main content */}
<div className="flex gap-[40px]">
<div className="flex flex-wrap gap-10">
{/* Left: Flyer */}
<div className="flex-shrink-0 w-[340px]">
<div className="rounded-[20px] overflow-hidden shadow-xl h-[440px]">
<div className="w-[340px] shrink-0">
<div className="h-[440px] overflow-hidden rounded-xl shadow-lg">
{event.flyerUrl ? (
<img src={event.flyerUrl} alt={event.title} className="w-full h-full object-cover" />
<img src={event.flyerUrl} alt="" className="size-full object-cover" />
) : (
<EventCoverArt title={event.title} tags={event.tags} className="w-full h-full" />
<EventCoverArt title={event.title} tags={event.tags} className="size-full" />
)}
</div>
</div>

{/* Right: Event info */}
<div className="flex-1 flex flex-col min-w-0">
<div className="flex min-w-0 flex-1 flex-col">
{/* Action buttons */}
<div className="flex items-center justify-between mb-[16px]">
<div className="flex items-center gap-[8px]">
<div className="mb-4 flex flex-wrap items-center justify-between gap-2">
<div className="flex items-center gap-2">
{event.isOwner && (
<>
<Link href={`/events/${event.id}/edit`}>
<button
type="button"
className="flex items-center gap-[6px] px-[12px] py-[6px] rounded-[10px] border border-forum-medium-gray text-[12px] font-bold font-dm-sans text-forum-light-gray hover:border-forum-dark-gray transition-colors"
>
<Edit3 size={12} /> Edit
</button>
</Link>
<Button asChild variant="outline" size="sm">
<Link href={`/events/${event.id}/edit`}>
<Edit3 /> Edit
</Link>
</Button>
<Dialog open={deleteOpen} onOpenChange={setDeleteOpen}>
<DialogTrigger asChild>
<button
type="button"
className="flex items-center gap-[6px] px-[12px] py-[6px] rounded-[10px] border border-forum-coral/30 text-[12px] font-bold font-dm-sans text-forum-coral hover:bg-forum-coral/5 transition-colors"
<Button
variant="outline"
size="sm"
className="border-forum-coral/30 text-forum-coral hover:bg-forum-coral/5"
>
<Trash2 size={12} /> Delete
</button>
<Trash2 /> Delete
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
Expand All @@ -186,51 +182,43 @@ export function EventDetailClient({ event, similarEvents }: EventDetailClientPro
<Button variant="outline" onClick={() => setDeleteOpen(false)}>
Cancel
</Button>
<Button variant="destructive" onClick={handleDelete} disabled={isPending}>
{isPending ? "Deleting..." : "Delete Event"}
<Button variant="coral" onClick={handleDelete} disabled={isPending}>
{isPending ? "Deleting" : "Delete Event"}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</>
)}
</div>
<div className="flex items-center gap-[8px]">
<a
href={buildGCalUrl(event)}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-[6px] px-[12px] py-[6px] rounded-[10px] border border-forum-medium-gray text-[12px] font-bold font-dm-sans text-forum-light-gray hover:border-forum-dark-gray transition-colors"
>
<Calendar size={13} /> Calendar
</a>
<button
type="button"
onClick={handleShare}
className="flex items-center gap-[6px] px-[12px] py-[6px] rounded-[10px] border border-forum-medium-gray text-[12px] font-bold font-dm-sans text-forum-light-gray hover:border-forum-dark-gray transition-colors"
>
<Share2 size={13} /> Share
</button>
<button
type="button"
<div className="flex items-center gap-2">
<Button asChild variant="outline" size="sm">
<a href={buildGCalUrl(event)} target="_blank" rel="noopener noreferrer">
<Calendar /> Calendar
</a>
</Button>
<Button variant="outline" size="sm" onClick={handleShare}>
<Share2 /> Share
</Button>
<Button
variant="outline"
size="sm"
aria-pressed={isSaved}
onClick={handleSave}
className={cn(
"flex items-center gap-[6px] px-[12px] py-[6px] rounded-[10px] border text-[12px] font-bold font-dm-sans transition-colors",
isSaved
? "text-forum-cerulean border-forum-cerulean bg-forum-turquoise/10"
: "text-forum-light-gray border-forum-medium-gray hover:border-forum-dark-gray",
isSaved && "border-forum-cerulean bg-forum-turquoise/10 text-forum-cerulean",
)}
>
{isSaved ? <BookmarkCheck size={13} /> : <Bookmark size={13} />}
{isSaved ? <BookmarkCheck /> : <Bookmark />}
{isSaved ? "Saved" : "Save"}
</button>
</Button>
</div>
</div>

{/* Title */}
<h1 className="font-serif text-[36px] font-bold text-black leading-tight mb-[8px]">
<PageHeading className="text-[28px] font-bold leading-tight sm:text-[32px] lg:text-[36px]">
{event.title}
</h1>
</PageHeading>

{/* Org */}
{event.orgName && (
Expand Down Expand Up @@ -296,19 +284,16 @@ export function EventDetailClient({ event, similarEvents }: EventDetailClientPro
</p>

{/* RSVP button */}
<button
type="button"
onClick={handleRsvp}
<Button
variant={isRsvped ? "solid" : "coral"}
size="cta"
aria-pressed={isRsvped}
disabled={isPending}
className={cn(
"w-full max-w-[300px] py-[12px] rounded-[10px] font-bold font-dm-sans text-[15px] transition-all",
isRsvped
? "bg-forum-dark-gray text-white"
: "bg-forum-coral text-white hover:opacity-90",
)}
onClick={handleRsvp}
className="w-full max-w-[300px]"
>
{isRsvped ? "CANCEL RSVP" : "RSVP NOW"}
</button>
{isRsvped ? "Cancel RSVP" : "RSVP now"}
</Button>

{/* Attendees */}
<div className="flex items-center gap-[12px] mt-[16px]">
Expand Down Expand Up @@ -339,22 +324,27 @@ export function EventDetailClient({ event, similarEvents }: EventDetailClientPro

{/* Similar Events */}
{similarEvents.length > 0 && (
<div className="mt-[48px] pt-[24px] border-t border-forum-medium-gray">
<h2 className="font-serif text-[25px] text-black mb-[20px]">Similar Events</h2>
<div className="grid grid-cols-2 md:grid-cols-4 gap-[16px]">
<section className="mt-12 border-t border-forum-medium-gray pt-6">
<SectionHeading>Similar Events</SectionHeading>
<div className="grid grid-cols-2 gap-4 md:grid-cols-4">
{similarEvents.map((se) => (
<Link key={se.id} href={`/events/${se.id}`} className="group">
<div className="rounded-[14px] overflow-hidden bg-forum-coral-bg hover:shadow-md transition-shadow h-[120px] p-[16px] flex flex-col justify-between">
<p className="font-serif text-[16px] text-black leading-tight line-clamp-2">
<Panel
asChild
key={se.id}
size="sm"
className="h-[120px] bg-forum-coral-bg transition-colors hover:border-forum-cerulean"
>
<Link href={`/events/${se.id}`} className="flex flex-col justify-between">
<p className="font-serif text-[16px] leading-tight text-black line-clamp-2">
{se.title}
</p>
<p className="text-[12px] font-dm-sans text-forum-light-gray">{se.datetime}</p>
</div>
</Link>
<p className="font-dm-sans text-[12px] text-forum-light-gray">{se.datetime}</p>
</Link>
</Panel>
))}
</div>
</div>
</section>
)}
</div>
</PageShell>
);
}
Loading