Skip to content

Commit c465593

Browse files
feat: add white section starter-kit (#471)
* feat: add desktop for white starter-kit * feat: add mobile layout * fix calendar events * reuse CalendarItem in teambuidling --------- Co-authored-by: michelleyeoh <74385095+michelleyeoh@users.noreply.github.com> Co-authored-by: michelleyeoh <michellew.yeoh@gmail.com>
1 parent 3f42b98 commit c465593

9 files changed

Lines changed: 404 additions & 91 deletions

File tree

app/(pages)/(hackers)/_components/Schedule/CalendarItem.tsx

Lines changed: 52 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ interface CalendarItemProps {
1212
event: Event & { originalType?: string };
1313
attendeeCount?: number;
1414
inPersonalSchedule?: boolean;
15+
hideAddButton?: boolean;
16+
disableAddButton?: boolean;
1517
onAddToSchedule?: () => void;
1618
onRemoveFromSchedule?: () => void;
1719
isRecommended?: boolean;
@@ -27,6 +29,8 @@ export function CalendarItem({
2729
event,
2830
attendeeCount,
2931
inPersonalSchedule = false,
32+
hideAddButton = false,
33+
disableAddButton = false,
3034
tags,
3135
host,
3236
onAddToSchedule,
@@ -40,6 +44,9 @@ export function CalendarItem({
4044
? normalizedType
4145
: 'GENERAL';
4246
const eventStyle = SCHEDULE_EVENT_STYLES[displayType];
47+
const actionIconPath = inPersonalSchedule
48+
? '/icons/check.svg'
49+
: '/icons/plus.svg';
4350

4451
// Handle different time display scenarios
4552
const timeDisplay = formatScheduleTimeRange(
@@ -49,27 +56,14 @@ export function CalendarItem({
4956

5057
return (
5158
<div
52-
className={`w-full py-[24px] flex-shrink-0 rounded-[16px] px-[20px] 2xs:px-[38px] 2xs:py-[24px] lg:px-[40px] lg:py-[32px] mb-[8px] flex ${
53-
displayType === 'ACTIVITIES' ? 'flex-row' : 'flex-col justify-center'
54-
}`}
59+
className="w-full py-[24px] flex-shrink-0 rounded-[16px] px-[20px] 2xs:px-[38px] 2xs:py-[24px] lg:px-[40px] lg:py-[32px] mb-[8px] flex flex-col justify-center"
5560
style={{
5661
backgroundColor: eventStyle.bgColor,
5762
color: eventStyle.textColor,
5863
}}
5964
>
60-
<div
61-
className={`flex items-start justify-between sm:items-center gap-[40px] md:gap-[60px] relative ${
62-
displayType === 'ACTIVITIES'
63-
? 'w-full flex-col sm:flex-row'
64-
: 'flex-col'
65-
}`}
66-
>
67-
<div
68-
className={`flex flex-col sm:flex-row justify-between items-start gap-4 sm:gap-6 ${
69-
// top
70-
displayType !== 'ACTIVITIES' ? 'w-full' : ''
71-
}`}
72-
>
65+
<div className="flex items-start justify-between sm:items-center gap-[40px] relative flex-col">
66+
<div className="flex flex-col sm:flex-row justify-between items-start gap-4 sm:gap-6 w-full">
7367
<div className="w-full sm:w-auto">
7468
<h2 className="font-metropolis text-[18px] md:text-[20px] font-semibold tracking-[0.72px] mb-1 text-balance">
7569
{name}
@@ -123,13 +117,8 @@ export function CalendarItem({
123117
)}
124118
</div>
125119
{displayType !== 'GENERAL' && displayType !== 'MEALS' && (
126-
<div
127-
className={`flex flex-row justify-between items-center gap-2 sm:gap-6 w-full ${
128-
//bottom
129-
displayType !== 'ACTIVITIES' ? '' : 'sm:w-auto'
130-
}`}
131-
>
132-
{displayType === 'WORKSHOPS' && (
120+
<div className="flex flex-row justify-between items-center gap-2 sm:gap-6 w-full">
121+
{(displayType === 'WORKSHOPS' || displayType === 'ACTIVITIES') && (
133122
<div
134123
className={`flex gap-2 items-center w-full sm:w-auto ${
135124
attendeeCount && attendeeCount > 0
@@ -150,47 +139,46 @@ export function CalendarItem({
150139
</div>
151140
)}
152141

153-
<div className="flex flex-col gap-2 items-end sm:w-auto ml-auto">
154-
<Button
155-
onClick={
156-
inPersonalSchedule ? onRemoveFromSchedule : onAddToSchedule
157-
}
158-
className="w-auto h-auto px-9 py-4 rounded-3xl cursor-pointer relative shrink-0 hover:brightness-[97%] hover:saturate-[140%]"
159-
style={{
160-
backgroundColor:
161-
eventStyle.addButtonColor || 'rgba(0, 0, 0, 0)',
162-
color: eventStyle.textColor,
163-
}}
164-
variant="ghost"
165-
>
166-
<p className="font-semibold relative text-[14px] z-10 inline-flex items-center gap-2">
167-
<span
168-
aria-hidden
169-
className="inline-block w-4 h-4"
170-
style={{
171-
backgroundColor: 'currentColor',
172-
WebkitMaskImage: `url(${
173-
inPersonalSchedule
174-
? '/icons/check.svg'
175-
: '/icons/plus.svg'
176-
})`,
177-
WebkitMaskRepeat: 'no-repeat',
178-
WebkitMaskPosition: 'center',
179-
WebkitMaskSize: 'contain',
180-
maskImage: `url(${
181-
inPersonalSchedule
182-
? '/icons/check.svg'
183-
: '/icons/plus.svg'
184-
})`,
185-
maskRepeat: 'no-repeat',
186-
maskPosition: 'center',
187-
maskSize: 'contain',
188-
}}
189-
/>
190-
{inPersonalSchedule ? 'Added' : 'Add'}
191-
</p>
192-
</Button>
193-
</div>
142+
{!hideAddButton && (
143+
<div className="flex flex-col gap-2 items-end sm:w-auto ml-auto">
144+
<Button
145+
onClick={
146+
inPersonalSchedule ? onRemoveFromSchedule : onAddToSchedule
147+
}
148+
disabled={disableAddButton}
149+
className={`w-auto h-auto px-9 py-4 rounded-3xl relative shrink-0 ${
150+
disableAddButton
151+
? 'cursor-not-allowed opacity-60'
152+
: 'cursor-pointer hover:brightness-[97%] hover:saturate-[140%]'
153+
}`}
154+
style={{
155+
backgroundColor:
156+
eventStyle.addButtonColor || 'rgba(0, 0, 0, 0)',
157+
color: eventStyle.textColor,
158+
}}
159+
variant="ghost"
160+
>
161+
<p className="font-semibold relative text-[14px] z-10 inline-flex items-center gap-2">
162+
<span
163+
aria-hidden
164+
className="inline-block w-4 h-4"
165+
style={{
166+
backgroundColor: 'currentColor',
167+
WebkitMaskImage: `url(${actionIconPath})`,
168+
WebkitMaskRepeat: 'no-repeat',
169+
WebkitMaskPosition: 'center',
170+
WebkitMaskSize: 'contain',
171+
maskImage: `url(${actionIconPath})`,
172+
maskRepeat: 'no-repeat',
173+
maskPosition: 'center',
174+
maskSize: 'contain',
175+
}}
176+
/>
177+
{inPersonalSchedule ? 'Added' : 'Add'}
178+
</p>
179+
</Button>
180+
</div>
181+
)}
194182
</div>
195183
)}
196184
</div>
Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,98 @@
11
import Image from 'next/image';
22
import { ArrowRight } from 'lucide-react';
3+
import type { StaticImageData } from 'next/image';
4+
import type { ReactNode } from 'react';
35
import mentorGraphic from '@public/hackers/starter-kit/ideate/TalkMentor.svg';
46
import IdeateSection from './IdeateSection';
57

6-
export default function IdeateMentorCallout() {
7-
const mentorDiscordLink = 'https://discord.gg/wc6QQEc';
8+
interface MentorCalloutCardProps {
9+
imageSrc: StaticImageData;
10+
imageAlt: string;
11+
eyebrow: string;
12+
description: ReactNode;
13+
note?: ReactNode;
14+
noteBgClassName?: string;
15+
ctaHref: string;
16+
ctaLabel: string;
17+
}
18+
19+
export function MentorCalloutCard({
20+
imageSrc,
21+
imageAlt,
22+
eyebrow,
23+
description,
24+
note,
25+
noteBgClassName,
26+
ctaHref,
27+
ctaLabel,
28+
}: MentorCalloutCardProps) {
829
return (
930
<IdeateSection eyebrow=" " title="">
1031
<div className="grid items-start gap-8 md:grid-cols-[minmax(320px,0.95fr)_minmax(0,1fr)] md:gap-10 lg:gap-14">
11-
<div className="relative order-1 mx-auto flex aspect-[1.72] w-full max-w-[44rem] items-center justify-center overflow-hidden rounded-[28px] bg-[#E4FFFE] md:order-1 md:mx-0">
32+
<div className="relative order-1 mx-auto flex w-full max-w-[44rem] items-center justify-center overflow-hidden rounded-[28px] md:order-1 md:mx-0">
1233
<Image
13-
src={mentorGraphic}
14-
alt="HackDavis mentor illustration"
15-
className="relative h-full w-full object-contain"
34+
src={imageSrc}
35+
alt={imageAlt}
36+
className="w-full h-auto object-contain"
1637
/>
1738
</div>
1839
<div className="order-2 flex flex-col gap-6 md:order-2">
1940
<p className="text-[1rem] font-dm-mono uppercase text-[#00000066]">
20-
Still Feel Stuck?
41+
{eyebrow}
2142
</p>
2243
<p className="max-w-[38rem] text-[#656565] text-[1rem]">
23-
No worries, we have a panel of industry mentors who are ready to
24-
lend you help at any part of your development process.
44+
{description}
2545
</p>
26-
<div className="hidden rounded-[20px] bg-[#E9FBBA] px-6 py-5 text-[#000000a6] md:block md:px-8 md:py-6">
27-
<p className="text-[1rem]">
28-
<span className="italic">Note:</span> If you have any questions
29-
regarding hackathon events, please contact a{' '}
30-
<a
31-
href="https://discord.gg/Ba5xAtf8"
32-
target="_blank"
33-
rel="noopener noreferrer"
34-
className="underline underline-offset-4"
35-
>
36-
director
37-
</a>
38-
.
39-
</p>
40-
</div>
46+
{note ? (
47+
<div
48+
className={`hidden rounded-[20px] px-6 py-5 text-[#000000a6] md:block md:px-8 md:py-6 ${
49+
noteBgClassName || 'bg-[#E9FBBA]'
50+
}`}
51+
>
52+
<p className="text-[1rem]">{note}</p>
53+
</div>
54+
) : null}
4155
<div className="pt-1">
4256
<a
43-
href={mentorDiscordLink}
57+
href={ctaHref}
4458
target="_blank"
4559
rel="noopener noreferrer"
4660
className="inline-flex items-center gap-3 font-dm-mono text-[1.125rem] uppercase text-[#3F3F3F] underline underline-offset-4 transition hover:opacity-75"
4761
>
4862
<ArrowRight className="h-5 w-5" />
49-
Contact a mentor
63+
{ctaLabel}
5064
</a>
5165
</div>
5266
</div>
5367
</div>
5468
</IdeateSection>
5569
);
5670
}
71+
72+
export default function IdeateMentorCallout() {
73+
return (
74+
<MentorCalloutCard
75+
imageSrc={mentorGraphic}
76+
imageAlt="HackDavis mentor illustration"
77+
eyebrow="Still Feel Stuck?"
78+
description="No worries, we have a panel of industry mentors who are ready to lend you help at any part of your development process."
79+
note={
80+
<>
81+
<span className="italic">Note:</span> If you have any questions
82+
regarding hackathon events, please contact a{' '}
83+
<a
84+
href="https://discord.gg/Ba5xAtf8"
85+
target="_blank"
86+
rel="noopener noreferrer"
87+
className="underline underline-offset-4"
88+
>
89+
director
90+
</a>
91+
.
92+
</>
93+
}
94+
ctaHref="https://discord.gg/wc6QQEc"
95+
ctaLabel="Contact a mentor"
96+
/>
97+
);
98+
}

0 commit comments

Comments
 (0)