Skip to content
Draft
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
35 changes: 35 additions & 0 deletions instructions/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Changelog

## [0.1.0] - 2024-01-25

### Added
- Created new EventDetailsCover component
- Displays event title, date/time, and location
- Optional cover image with hide/show functionality
- Responsive design following Figma specs
- TypeScript interfaces for type safety
- Tailwind CSS for styling

### New Files
- `/src/components/EventDetailsCover/`
- `EventDetailsCover.tsx` - Main component
- `types.ts` - TypeScript interfaces
- `index.ts` - Barrel exports
- `/src/utils/dateFormatter.ts` - Date formatting utility
- `/src/stories/EventDetailsCover.stories.tsx` - Storybook stories

### Features
- Cover image with optional hide/show functionality
- Formatted date/time display
- Location details with venue, address, city, state
- Icon integration for calendar and location
- Storybook documentation with two variants:
- Default (with cover image)
- Without cover image

### Technical Details
- Built with Next.js Image component for optimized images
- TypeScript for type safety
- Tailwind CSS for styling
- Storybook integration for component documentation
- Modular file structure following project conventions
108 changes: 108 additions & 0 deletions instructions/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
## Description:
Event details cover component will show the image, title, date and location of the event.

Mock the data in the component.

Ignore the right side of the desktop page, that is a separate component. For now add a div with the size of the right component to make it look like the design.

Add a prop to the component called hideCoverImage: boolean

If the hideCoverImage is true then dont show the image.

## Acceptance Criteria
The result should follow the figma design.

### Testing
Add the respective story using storybook for this issue


## Current File Structure

.
├── README.md
├── chromatic.config.json
├── components.json
├── eslint.config.mjs
├── instructions
│   └── instructions.md
├── next.config.js
├── next.config.ts
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
│   ├── Frame.svg
│   ├── HallosLetters.svg
│   ├── LogoHallos.svg
│   ├── Spain.svg
│   ├── calendar.svg
│   ├── file.svg
│   ├── globe.svg
│   ├── hallos.png
│   ├── images
│   │   ├── Facebook.png
│   │   ├── GoldRogerProfile2.png
│   │   ├── GroupBookTicketIcon.png
│   │   ├── Instagram.png
│   │   ├── Location.png
│   │   ├── Map.png
│   │   ├── Pinterest.png
│   │   ├── TikTok.png
│   │   ├── Twitter.png
│   │   ├── VISA.png
│   │   ├── dollar.png
│   │   ├── eth.png
│   │   ├── hallos.png
│   │   └── vueltos-un-colocho.png
│   ├── location.svg
│   ├── next.svg
│   ├── nightParty1.png
│   ├── nightParty2.png
│   ├── qr.svg
│   ├── tico-blockchain.jpg
│   ├── vercel.svg
│   └── window.svg
├── src
│   ├── app
│   │   ├── GroupBookTicketIcon.png
│   │   ├── events
│   │   ├── example
│   │   ├── favicon.ico
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   └── page.tsx
│   ├── components
│   │   ├── Input
│   │   ├── PaymentMethod.tsx
│   │   ├── common
│   │   ├── forms
│   │   ├── layout
│   │   └── ui
│   ├── constants
│   │   ├── countries.ts
│   │   └── formInputs.ts
│   ├── icons
│   │   ├── Calendar.tsx
│   │   ├── Facebook.tsx
│   │   ├── Filter.tsx
│   │   ├── GitHub.tsx
│   │   ├── Instagram.tsx
│   │   ├── Location.tsx
│   │   ├── Loupe.tsx
│   │   ├── PlusMinus.tsx
│   │   ├── Twitter.tsx
│   │   └── index.ts
│   ├── lib
│   │   └── utils.ts
│   ├── stories
│   │   ├── Colors.mdx
│   │   ├── Configure.mdx
│   │   └── assets
│   ├── types
│   │   └── faq.type.ts
│   └── utils
│   ├── events.ts
│   └── faqs.ts
├── tailwind.config.ts
├── tsconfig.json
└── yarn.lock
57 changes: 57 additions & 0 deletions src/components/EventDetailsCover/EventDetailsCover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Image from 'next/image';
import { EventDetailsCoverProps } from './types';
import { formatEventDate } from '@/utils/dateFormatter';
import { Calendar, Location } from '@/icons';

export const EventDetailsCover = ({
title,
startDate,
endDate,
location,
coverImage,
hideCoverImage = false
}: EventDetailsCoverProps) => {
return (
<div className="flex flex-col w-full">
{/* Cover Image */}
{!hideCoverImage && coverImage && (
<div className="relative w-full h-[240px] rounded-t-lg overflow-hidden">
<Image
src={coverImage}
alt={title}
fill
className="object-cover"
priority
/>
</div>
)}

{/* Event Details */}
<div className="bg-background p-6 rounded-b-lg">
<h1 className="text-2xl font-bold mb-4">{title}</h1>

{/* Date and Time */}
<div className="flex items-center gap-2 mb-3">
<Calendar className="w-5 h-5 text-muted-foreground" />
<span className="text-sm text-muted-foreground">
{formatEventDate(startDate, endDate)}
</span>
</div>

{/* Location */}
<div className="flex items-start gap-2">
<Location className="w-5 h-5 mt-1 text-muted-foreground" />
<div className="flex flex-col">
<span className="text-sm font-medium">{location.venue}</span>
<span className="text-sm text-muted-foreground">
{location.address}
</span>
<span className="text-sm text-muted-foreground">
{`${location.city}, ${location.state} ${location.zipCode}`}
</span>
</div>
</div>
</div>
</div>
);
};
2 changes: 2 additions & 0 deletions src/components/EventDetailsCover/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './EventDetailsCover';
export * from './types';
15 changes: 15 additions & 0 deletions src/components/EventDetailsCover/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export interface EventDetailsCoverProps {
title: string;
startDate: string;
endDate: string;
location: {
venue: string;
address: string;
city: string;
state: string;
zipCode: string;
country: string;
};
coverImage?: string;
hideCoverImage?: boolean;
}
37 changes: 37 additions & 0 deletions src/stories/EventDetailsCover.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Meta, StoryObj } from '@storybook/react';
import { EventDetailsCover } from '@/components/EventDetailsCover/EventDetailsCover';

const meta: Meta<typeof EventDetailsCover> = {
title: 'Components/EventDetailsCover',
component: EventDetailsCover,
parameters: {
layout: 'centered',
},
};

export default meta;
type Story = StoryObj<typeof EventDetailsCover>;

export const Default: Story = {
args: {
title: 'Everyone no Cover At Taj NYC #1 Urban Night Party',
startDate: '2024-01-25T23:00:00',
endDate: '2024-01-26T04:00:00',
location: {
venue: 'Taj II',
address: '48 West 21st Street',
city: 'New York',
state: 'NY',
zipCode: '10010',
country: 'United States'
},
coverImage: '/nightParty1.png'
},
};

export const WithoutCoverImage: Story = {
args: {
...Default.args,
hideCoverImage: true,
},
};
20 changes: 20 additions & 0 deletions src/utils/dateFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const formatEventDate = (startDate: string, endDate: string): string => {
const start = new Date(startDate);
const end = new Date(endDate);

const options: Intl.DateTimeFormatOptions = {
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
hour12: true
};

const startFormatted = start.toLocaleDateString('en-US', options);
const endFormatted = end.toLocaleDateString('en-US', {
...options,
month: undefined // Don't show month if it's the same day
});

return `${startFormatted} - ${endFormatted}`;
};