Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"bootstrap": "^5.3.3",
"email-validator": "^2.0.4",
"i18next": "^23.10.1",
"need4deed-sdk": "",
"need4deed-sdk": "*",
"react": "^18.2.0",
"react-bootstrap": "^2.10.1",
"react-cookie-consent": "^9.0.0",
Expand Down
96 changes: 30 additions & 66 deletions src/components/Event/Event.tsx
Original file line number Diff line number Diff line change
@@ -1,84 +1,48 @@
import { EventN4D, Lang } from "need4deed-sdk";
import { EventN4D } from "need4deed-sdk";
import { useTranslation } from "react-i18next";

import { getImageUrl, getTimeFrameString } from "../../utils";
import PastEventCard from "./PastEventCard/PastEventCard";
import UpcomingEventCard from "./UpcomingEventCard/UpcomingEventCard";

interface Props {
eventData: { event?: EventN4D };
eventData: EventN4D[];
}

const fallbackPicUrl = "event.webp";

export default function Event({ eventData }: Props) {
const { event } = eventData || { event: undefined };
const {
i18n: { language },
t,
} = useTranslation();
const { t } = useTranslation();

if (!event) {
if (!eventData || eventData.length === 0) {
return <h4>{t("event.missing")}</h4>;
}

const upcomingEvents = eventData.filter((event) => event.active);
const pastEvents = eventData.filter((event) => !event.active);

return (
<div className="n4d-container event-container">
<h2>{event.title}</h2>
<h6>{event.subTitle}</h6>
<h6>
<strong>{event.hostName}</strong>
</h6>
{event.time && (
<h6>
<strong>{event.time}</strong>
</h6>
<div className="n4d-section">
{upcomingEvents.length > 0 && (
<section className="upcoming-events">
{upcomingEvents.map((event) => (
<UpcomingEventCard
key={event.id}
event={event}
fallbackPicUrl={fallbackPicUrl}
/>
))}
</section>
)}

{event.date && (
<h6>
{getTimeFrameString(language as Lang, event.date, event.dateEnd)}
</h6>
{pastEvents.length > 0 && (
<section className="past-events">
{pastEvents.map((event) => (
<PastEventCard
key={event.id}
event={event}
fallbackPicUrl={fallbackPicUrl}
/>
))}
</section>
)}

<img
src={getImageUrl("N4D-logo-purple-on-transparent-h.webp")}
height="16"
alt=""
/>
<h6 className="with-linebreaks">{event.address.replace(/\\n/g, "\n")}</h6>
<h6 className="with-linebreaks">{event.locationComment}</h6>
<p>
<a href={event.locationLink} target="_blank" rel="noreferrer">
{t("event.locationLink")}
</a>
</p>
<h6>
{t("event.rsvp")}:{" "}
<a href={event.linkRSVP} target="_blank" rel="noreferrer">
{t("event.registration")}
</a>
</h6>
<div className="pic-and-text">
<div
className="event-pic"
style={{
backgroundImage: `url(${getImageUrl(event.pic || fallbackPicUrl)})`,
}}
/>
<div>
<h6 className="with-linebreaks">
{event.description.replace(/\\n/g, "\n")}
</h6>
<h6 className="with-linebreaks m-0">{event.additionalTitle}</h6>
<ul>
{event.additionalInfo &&
event.additionalInfo.map((info) => (
<li key={info}>
<h6 className="with-linebreaks m-0">{info}</h6>
</li>
))}
</ul>
</div>
</div>
</div>
);
}
136 changes: 136 additions & 0 deletions src/components/Event/PastEventCard/PastEventCard.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
.pastEventCard {
margin-bottom: 4rem;
}


.eventContent {
display: flex;
gap: 2rem;
margin-block: 1rem;
width: 100%;
flex-wrap: wrap;
}

.eventContent h1 {
margin-block: 1rem 0;
}



.eventContent strong {
font-weight: 700;
}

.eventImage {
width: 328px;
height: 328px;
border-radius: 8px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
flex-shrink: 0;
}


.eventStatus {
align-items: center;
font-size: 14px;
padding: 0.375rem 1rem;
background: var(--color-white);
width: fit-content;
margin-bottom: 1rem;
}

.eventStatus p {
color: var(--color-midnight-bright);
margin: 0;
font-weight: 600;
}

.eventTitle {
font-size: 32px;
font-weight: 700;
color: var(--color-midnight);
}

.eventSubtitle {
font-size: 14px;
font-weight: 550;
color: var(--color-midnight);
}

.eventDate h6 {
color: var(--color-midnight);
font-size: 20px;
font-weight: 600;
margin: 2rem auto;
}


.eventDescription {
font-size: 20px;
font-weight: 400;
white-space: pre-line;
margin-top: 1rem;
color: var(--color-midnight);
}

.additionalTitle {
margin-top: 1rem;
font-weight: bold;
color: var(--color-midnight);
}


.additionalInfoList {
margin-top: 1rem;
padding-left: 20px;
}

.additionalInfoItem {
margin-bottom: 0.5rem;
color: var(--color-midnight);
}



@media (max-width: 1024px) {
.eventDetails {
width: 350px
}
}

/* Responsive styles */
@media (max-width: 576px) {
.eventContent {
grid-template-columns: unset;
gap: 1rem;
}



.eventImage {
height: 200px;
width: 200px;
}

.eventImage {
width: 328px;
height: 328px;
border-radius: 8px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
flex-shrink: 0;
}

.eventDescription {
font-size: 16px;
font-weight: 400;
white-space: pre-line;
margin-top: 1rem;
color: var(--color-midnight);
}


}
50 changes: 50 additions & 0 deletions src/components/Event/PastEventCard/PastEventCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { EventN4D } from "need4deed-sdk";
import { useTranslation } from "react-i18next";
import { formatDateRange, getImageUrl } from "../../../utils";
import styles from "./PastEventCard.module.css";

interface PastEventCardProps {
event: EventN4D;
fallbackPicUrl: string;
}

function PastEventCard({ event, fallbackPicUrl }: PastEventCardProps) {
const { t } = useTranslation();
const eventStatus = event.active
? t("homepage.events.headLine")
: t("event.past");

return (
<div className={`n4d-container ${styles.pastEventCard}`}>
<div className={styles.eventContent}>
<div
className={styles.eventImage}
style={{
backgroundImage:
`url(${getImageUrl(event.pic || fallbackPicUrl)})` as string,
}}
/>
<div className={styles.eventDetails}>
<div className={styles.eventStatus}>
<p>{eventStatus}</p>
</div>
<h2 className={styles.eventTitle}>{event.title}</h2>

{event.date && (
<div className={styles.eventDate}>
<h6>
{formatDateRange(
new Date(event.date),
event.dateEnd && new Date(event.dateEnd),
)}
</h6>
</div>
)}
<h6 className={styles.eventDescription}>{event.shortDescription}</h6>
</div>
</div>
</div>
);
}

export default PastEventCard;
Loading