-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: event page, sorted and formated accordion
- Loading branch information
alexandre-kakal-akarah
committed
Jun 19, 2024
1 parent
72c39fd
commit 0dc23f4
Showing
9 changed files
with
332 additions
and
5 deletions.
There are no files selected for viewing
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
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,82 @@ | ||
import React from "react"; | ||
import ParallaxImage from "@/components/clients/ParallaxImage"; | ||
import Rating from "@/components/Rating"; | ||
import { Icons } from "@/components/Icons"; | ||
|
||
type Params = { id: string }; | ||
|
||
const EventDetail = ({ params }: { params: Params }) => { | ||
// get journey by id | ||
return ( | ||
<main className="flex min-h-screen flex-col bg-gray"> | ||
<ParallaxImage /> | ||
<div className="relative flex-1 -translate-y-4 rounded-t-2xl px-5 pb-40 pt-14"> | ||
<div className="absolute left-4 top-0 flex gap-[6px]"> | ||
<div className="flex items-center rounded-b-md bg-white px-2 py-[6px]"> | ||
<Icons.dumbbel /> | ||
<p className="text-sm font-semibold text-gray">Facile</p> | ||
</div> | ||
<div className="flex items-center gap-1 rounded-b-md bg-green px-2 py-[6px]"> | ||
<Icons.bulb /> | ||
<p className="text-sm font-semibold text-gray">Intermédiaire</p> | ||
</div> | ||
</div> | ||
<h1 className="text-xl font-extrabold text-orange"> | ||
Sentier du biscuit sablé | ||
</h1> | ||
<div className="flex items-center gap-1 text-beige-600"> | ||
<Icons.mapPin fill="rgba(206, 192, 173, 60%)" /> | ||
<p className="text-sm font-medium">Normandie</p> | ||
</div> | ||
<p>TODO: Par Jean Blonblon, le 23/06/2024</p> | ||
|
||
<p className="text-sm"> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce | ||
accumsan ligula tellus, a luctus eros lobortis eu. Fusce rhoncus | ||
turpis in metus fermentum, nec hendrerit elit mattis. In ipsum diam, | ||
pellentesque ut porttitor eu, laoreet et dolor. Sed bibendum nec nulla | ||
eu fringilla. Aliquam erat volutpat. Nullam quis risus scelerisque, | ||
aliquet sapien ultricies, vulputate urna. Aenean sed dolor a nisl | ||
pellentesque venenatis at eget lectus. Vestibulum tempus at dui quis | ||
faucibus. | ||
</p> | ||
<div className="mt-[18px] flex items-center justify-between text-lg font-semibold text-orange"> | ||
<h2>Accessibilité</h2> | ||
<Icons.arrowLink /> | ||
</div> | ||
<div className="mt-4 flex gap-6"> | ||
<div className="flex aspect-[1/1] flex-1 items-center justify-center rounded-lg border-2 border-cadetblue bg-cadetblue-600"> | ||
<Icons.pmr /> | ||
</div> | ||
<div className="flex aspect-[1/1] flex-1 items-center justify-center rounded-lg border-2 border-cadetblue bg-cadetblue-600"> | ||
<Icons.partiallySighted /> | ||
</div> | ||
<div className="flex aspect-[1/1] flex-1 items-center justify-center rounded-lg border-2 border-cadetblue bg-cadetblue-600"> | ||
<Icons.partiallyDeaf /> | ||
</div> | ||
<div className="flex aspect-[1/1] flex-1 items-center justify-center rounded-lg border-2 border-cadetblue bg-cadetblue-600"> | ||
<Icons.cognitivelyImpaired /> | ||
</div> | ||
</div> | ||
<h2 className="mt-[18px] text-lg font-semibold text-orange"> | ||
Pré-requis | ||
</h2> | ||
<p> | ||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. | ||
Necessitatibus facilis velit dolores consectetur ea, molestias autem | ||
maiores dicta, laboriosam eaque, nesciunt esse accusamus libero | ||
aperiam. | ||
</p> | ||
|
||
<h2 className="mt-[18px] text-lg font-semibold text-orange"> | ||
Commentaires | ||
</h2> | ||
<div className="flex gap-1"> | ||
<Rating rating={3.5} ratingCount={4} /> | ||
</div> | ||
</div> | ||
</main> | ||
); | ||
}; | ||
|
||
export default EventDetail; |
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,22 @@ | ||
import React from "react"; | ||
import AddButton from "@/components/AddButton"; | ||
import JourneyForm from "@/components/form/journey/JourneyForm"; | ||
import TopBar from "@/components/TopBar"; | ||
import EventsFeed from "@/components/EventsFeed"; | ||
|
||
const Event = () => { | ||
return ( | ||
<> | ||
<TopBar /> | ||
<main> | ||
<section className="flex flex-col gap-7 px-5 pb-40"> | ||
<EventsFeed /> | ||
</section> | ||
<JourneyForm /> | ||
<AddButton action="journey" /> | ||
</main> | ||
</> | ||
); | ||
}; | ||
|
||
export default Event; |
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,86 @@ | ||
"use client"; | ||
import React, { useState } from "react"; | ||
import { | ||
Accordion, | ||
AccordionItem, | ||
AccordionTrigger, | ||
AccordionContent, | ||
} from "./ui/accordion"; | ||
import { Event } from "@prisma/client"; | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
|
||
interface EventAccordionProps { | ||
events: Event[]; | ||
} | ||
|
||
const EventAccordion: React.FC<EventAccordionProps> = ({ events }) => { | ||
const groupedEvents = events.reduce( | ||
(groups: Record<string, Event[]>, event) => { | ||
const date = new Date(event.startAt).toISOString().split("T")[0]; | ||
if (!groups[date]) { | ||
groups[date] = []; | ||
} | ||
groups[date].push(event); | ||
return groups; | ||
}, | ||
{}, | ||
); | ||
|
||
const sortedDates = Object.keys(groupedEvents).sort(); | ||
|
||
const formattedDates = sortedDates.map((date) => ({ | ||
original: date, | ||
formatted: new Date(date).toLocaleDateString("fr-FR", { | ||
weekday: "long", | ||
year: "numeric", | ||
month: "long", | ||
day: "numeric", | ||
}), | ||
})); | ||
|
||
const [openItem, setOpenItem] = useState<string>(formattedDates[0].formatted); | ||
|
||
const handleToggle = (date: string) => { | ||
setOpenItem((prev) => (prev === date ? "" : date)); | ||
}; | ||
|
||
return ( | ||
<Accordion | ||
type="single" | ||
value={openItem} | ||
onValueChange={handleToggle} | ||
className="w-full" | ||
> | ||
{formattedDates.map(({ original, formatted }) => ( | ||
<AccordionItem key={original} value={formatted}> | ||
<AccordionTrigger className="py-2 text-lg font-medium"> | ||
{formatted} | ||
</AccordionTrigger> | ||
<AccordionContent className="space-y-4"> | ||
{groupedEvents[original].map((event) => ( | ||
<div key={event.id} className=" rounded-lg border p-4 shadow"> | ||
<Link href={`/evenements/${event.id}`}> | ||
<Image | ||
src={`${event.image}200`} | ||
alt={event.title} | ||
className="mb-4 h-32 w-full rounded object-cover" | ||
width={200} | ||
height={200} | ||
/> | ||
<h3 className="text-xl font-bold">{event.title}</h3> | ||
<p className="">{event.description}</p> | ||
<p className=""> | ||
Participants: {event.numberPlayerMin} -{" "} | ||
{event.numberPlayerMax} | ||
</p> | ||
</Link> | ||
</div> | ||
))} | ||
</AccordionContent> | ||
</AccordionItem> | ||
))} | ||
</Accordion> | ||
); | ||
}; | ||
export default EventAccordion; |
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,16 @@ | ||
import EventAccordion from "./EventAccordion"; | ||
import { Suspense } from "react"; | ||
|
||
const EventsFeed = async () => { | ||
const res = await fetch(`${process.env.BASE_URL}/api/events`, { | ||
cache: "no-cache", | ||
}); | ||
const events = await res.json(); | ||
return ( | ||
<Suspense fallback={<div>Loading...</div>}> | ||
<EventAccordion events={events.data} /> | ||
</Suspense> | ||
); | ||
}; | ||
|
||
export default EventsFeed; |
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,58 @@ | ||
"use client"; | ||
|
||
import * as React from "react"; | ||
import * as AccordionPrimitive from "@radix-ui/react-accordion"; | ||
import { ChevronDown } from "lucide-react"; | ||
|
||
import { cn } from "@/lib/tailwindUtils"; | ||
|
||
const Accordion = AccordionPrimitive.Root; | ||
|
||
const AccordionItem = React.forwardRef< | ||
React.ElementRef<typeof AccordionPrimitive.Item>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item> | ||
>(({ className, ...props }, ref) => ( | ||
<AccordionPrimitive.Item | ||
ref={ref} | ||
className={cn("border-b", className)} | ||
{...props} | ||
/> | ||
)); | ||
AccordionItem.displayName = "AccordionItem"; | ||
|
||
const AccordionTrigger = React.forwardRef< | ||
React.ElementRef<typeof AccordionPrimitive.Trigger>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> | ||
>(({ className, children, ...props }, ref) => ( | ||
<AccordionPrimitive.Header className="flex"> | ||
<AccordionPrimitive.Trigger | ||
ref={ref} | ||
className={cn( | ||
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180", | ||
className, | ||
)} | ||
{...props} | ||
> | ||
{children} | ||
<ChevronDown className="size-4 shrink-0 transition-transform duration-200" /> | ||
</AccordionPrimitive.Trigger> | ||
</AccordionPrimitive.Header> | ||
)); | ||
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; | ||
|
||
const AccordionContent = React.forwardRef< | ||
React.ElementRef<typeof AccordionPrimitive.Content>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content> | ||
>(({ className, children, ...props }, ref) => ( | ||
<AccordionPrimitive.Content | ||
ref={ref} | ||
className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down" | ||
{...props} | ||
> | ||
<div className={cn("pb-4 pt-0", className)}>{children}</div> | ||
</AccordionPrimitive.Content> | ||
)); | ||
|
||
AccordionContent.displayName = AccordionPrimitive.Content.displayName; | ||
|
||
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; |