Skip to content

Commit

Permalink
🌟Training - Event booking component (#931)
Browse files Browse the repository at this point in the history
* Training - Even booking component

* Removed hardcoded text from the component

* Updating - responsiveness for multiple items

* Update schema.json

* UI - Adding right border

* Visual Edit - for event booking component

* removing hardcoded values

* Adding reference for the anchor link

* Update _schema.json

* UI - Fixing spacing issue between classes

* Replace moment with DAYJS

* Update - content change for label

* Removing events booking component from the Fullstack

* UI - adding responsiveness for small screens
  • Loading branch information
amankumarrr authored Jul 5, 2023
1 parent 31aff94 commit 15c6812
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .tina/__generated__/_graphql.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .tina/__generated__/_lookup.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .tina/__generated__/_schema.json

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions components/blocks-renderer.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import React from "react";
import { AboutUs } from "./blocks/aboutUs";

import { BuiltOnAzure } from "./blocks/builtOnAzure";
import { Carousel } from "./blocks/carousel";
import { ClientLogos } from "./blocks/clientLogos";
import { Content } from "./blocks/content";
import { ContentCard } from "./blocks/contentCard";
import { CustomImage } from "./blocks/customImage";
import { ServiceCards } from "./blocks/serviceCards";
import { UpcomingEvents } from "./blocks/upcomingEvents";
import { BuiltOnAzure } from "./blocks/builtOnAzure";
import { CustomImage } from "./blocks/customImage";
import { ClientLogos } from "./blocks/clientLogos";
import { VerticalImageLayout } from "./blocks/verticalImageLayout";
import { VerticalListItem } from "./blocks/verticalListItem";
import { EventBooking } from "./training/eventBooking";
import { TrainingInformation } from "./training/trainingInformation";
import { TrainingLearningOutcome } from "./training/trainingLearningOutcome";

Expand All @@ -27,6 +28,7 @@ const componentMap = {
ContentCard: ContentCard,
VerticalListItem: VerticalListItem,
TrainingInformation: TrainingInformation,
EventBooking: EventBooking,
TrainingLearningOutcome: TrainingLearningOutcome,
};

Expand Down
11 changes: 7 additions & 4 deletions components/blocks/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { Template } from "tinacms";

import { bookingButtonSchema } from "../bookingButton/bookingButton";
import { utilityButtonSchema } from "../button/utilityButton";
import { agreementFormBlockSchema } from "../terms-and-conditions/agreementForm";
import { eventBookingSchema } from "../training/eventBooking";
import { trainingInformationSchema } from "../training/trainingInformation";
import { trainingLearningOutcomeSchema } from "../training/trainingLearningOutcome";
import { aboutUsBlockSchema } from "./aboutUs";
Expand Down Expand Up @@ -28,8 +31,6 @@ import { upcomingEventsBlockSchema } from "./upcomingEvents";
import { verticalImageLayoutBlockSchema } from "./verticalImageLayout";
import { verticalListItemSchema } from "./verticalListItem";
import { videoEmbedBlockSchema } from "./videoEmbed";
import { utilityButtonSchema } from "../button/utilityButton";
import { bookingButtonSchema } from "../bookingButton/bookingButton";

export const pageBlocks: Template[] = [
aboutUsBlockSchema,
Expand Down Expand Up @@ -62,9 +63,13 @@ export const pageBlocks: Template[] = [
verticalImageLayoutBlockSchema,
verticalListItemSchema,
videoEmbedBlockSchema,
eventBookingSchema,
];

export * from "../bookingButton/bookingButton";
export * from "../button/utilityButton";
export * from "../terms-and-conditions/agreementForm";
export * from "../training/eventBooking";
export * from "../training/trainingInformation";
export * from "../training/trainingLearningOutcome";
export * from "./aboutUs";
Expand All @@ -87,8 +92,6 @@ export * from "./subNewsLetters";
export * from "./subscribe";
export * from "./tableLayout";
export * from "./upcomingEvents";
export * from "../button/utilityButton";
export * from "./verticalImageLayout";
export * from "./verticalListItem";
export * from "./videoEmbed";
export * from "../bookingButton/bookingButton";
234 changes: 234 additions & 0 deletions components/training/eventBooking.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
import classNames from "classnames";
import dayjs from "dayjs";
import { FC } from "react";
import { MdLocationOn } from "react-icons/md";
import type { Template } from "tinacms";
import { tinaField } from "tinacms/dist/react";
import { EventBookingType, EventModel } from "./eventBookingType";

const classes = {
mdColSpan4: "md:col-span-4",
mdColSpan6: "md:col-span-6",
mdColSpan12: "md:col-span-12",
lastMdColSpan4: "last:md:col-span-4",
lastMdColSpan8: "last:md:col-span-8",
lastMdColSpan12: "last:md:col-span-12",
};

export const EventBooking: FC<EventBookingType> = ({ data }) => {
return (
<>
{
<EventHeader
duration={data.duration}
price={data.price}
schema={data}
/>
}
<div className="mb-2 grid grid-cols-12">
{data.eventList?.map((event, index) => (
<EventCard
key={index}
event={event}
count={data.eventList.length}
index={index}
schema={data}
/>
))}
</div>
<div className="bg-gray-400 py-1 text-center text-white">
{EventModel.HOSTED_BY}{" "}
<span className="font-bold">{EventModel.SSW}</span>
</div>
</>
);
};

const EventCard = ({ event, count, index, schema }) => {
return (
<div
className={classNames(
"col-span-12 gap-2 border-b-8 border-white bg-gray-100 py-3 pl-5 text-lg last:border-b-0 last:border-r-0 md:border-b-0",
getColSpanClass(count, index),
addTopBorderForSecondRow(index),
addRightBorder(index)
)}
>
<div className="mb-2 grid grid-cols-12">
<div className="col-span-6 md:col-span-12">
<span
className="font-bold capitalize"
data-tina-field={tinaField(
schema.eventList[index],
eventBookingBlock.eventList.city
)}
>
{event.city}
</span>
<div
className=" py-0.5 text-xs uppercase text-gray-500"
data-tina-field={tinaField(
schema.eventList[index],
eventBookingBlock.eventList.date
)}
>
{" "}
{event.date && dayjs(event.date).format("Do (ddd) MMMM YYYY")}
</div>
<div className=" py-0.5 text-xs uppercase text-gray-500">
{EventModel.TIMINGS}
</div>
</div>
<div className="col-span-6 items-center pr-4 md:col-span-12 md:pr-0">
<div
className="py-1 text-end md:text-start"
data-tina-field={tinaField(
schema.eventList[index],
eventBookingBlock.eventList.bookingURL
)}
>
<a
href={event.bookingURL == null ? "" : event.bookingURL}
className="done inline-flex cursor-pointer"
target="_blank"
rel="noopener noreferrer"
>
{EventModel.BOOKING_BTN_TEXT}
</a>

<div className=" py-1 pr-0 text-xs ">
<a
className="flex items-center justify-end !no-underline md:justify-start"
href="#location"
>
<MdLocationOn className="m-icon" />
{EventModel.SSW}
<span className="ml-1 capitalize">{event.city}</span>
</a>
</div>
</div>
</div>
</div>
</div>
);
};

const getColSpanClass = (count, index) => {
if (count === 3) {
return classes.mdColSpan4;
} else if (count === 2) {
return classes.mdColSpan6;
} else if (count === 1) {
return classes.mdColSpan12;
} else {
// For counts greater than 3, calculate the column span class based on index and count > 3

if ((index + 1) % 3 === 0) {
// e.g number of items are 6 (3 items in a row each col-span-4)
return classes.mdColSpan4 + " " + classes.lastMdColSpan4;
} else if ((index + 1) % 3 === 1) {
// e.g number of items are 4 (1 item in a row (col-span-12))
return classes.mdColSpan4 + " " + classes.lastMdColSpan12;
} else {
// e.g number of items are 5 (2 items (col-span-4) && (col-span-8))
return classes.mdColSpan4 + " " + classes.lastMdColSpan8;
}
}
};

const addTopBorderForSecondRow = (index) => {
return index > 2 ? "border-white md:border-t-8" : "";
};

const addRightBorder = (index) => {
return (index + 1) % 3 != 0 ? "md:border-r-8" : "";
};

const EventHeader = ({ duration, price, schema }) => {
return (
<div className="mt-2 border-t-2 border-gray-400 bg-gray-100">
<div className="mb-2 grid grid-cols-12">
<div
data-tina-field={tinaField(schema, eventBookingBlock.duration)}
className="col-span-4 px-3 py-2 text-lg sm:col-span-2"
>
<div className=" text-xs uppercase text-gray-500">
{EventModel.DURATION}
</div>
{duration} {EventModel.DAY}
</div>
<div className="col-span-1 h-5/6 items-center self-center border-r-1 border-gray-300"></div>
<div
className="col-span-7 px-3 py-2 text-lg sm:col-span-9"
data-tina-field={tinaField(schema, eventBookingBlock.price)}
>
<div className="text-xs uppercase text-gray-500">
{EventModel.PRICE}
</div>
{EventModel.CURRENCY}
<span>{price}</span> {EventModel.INCLUDE_GST}
</div>
</div>
</div>
);
};

export const eventBookingBlock = {
eventBooking: "EventBooking",
duration: "duration",
price: "price",
eventList: {
value: "eventList",
city: "city",
date: "date",
bookingURL: "bookingURL",
},
};

export const eventBookingSchema: Template = {
name: eventBookingBlock.eventBooking,
label: "Events Booking",
fields: [
{
type: "number",
label: "Duration",
name: eventBookingBlock.duration,
},
{
type: "number",
label: "Price",
name: eventBookingBlock.price,
},
{
type: "object",
label: "Event",
name: eventBookingBlock.eventList.value,
ui: {
itemProps: (item) => {
return { label: item?.city };
},
},
list: true,
fields: [
{
type: "string",
label: "City",
name: eventBookingBlock.eventList.city,
},
{
type: "datetime",
label: "Date",
name: eventBookingBlock.eventList.date,
ui: {
timeFormat: "MM:DD:YY",
},
},
{
type: "string",
label: "Booking URL",
name: eventBookingBlock.eventList.bookingURL,
},
],
},
],
};
25 changes: 25 additions & 0 deletions components/training/eventBookingType.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export type EventBookingType = {
data: {
duration?: number | null;
price?: number | null;
eventList?: Event[];
};
};

export type Event = {
city: string | null;
date: string | null;
bookingURL: string;
};

export const EventModel = {
SSW: "SSW",
HOSTED_BY: "Hosted by",
CURRENCY: "$",
TIMINGS: "9AM - 5PM",
BOOKING_BTN_TEXT: "Book Now",
PRICE: "Price",
DURATION: "Duration",
INCLUDE_GST: "inc GST",
DAY: "Day",
};
11 changes: 8 additions & 3 deletions content/training/fullstack.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -201,23 +201,26 @@ trainingHeaderCarousel:
link:
linkText: Apply Now
url: >-
mailto:[email protected]?subject=SSW Internship Application&[email protected]; [email protected]
mailto:[email protected]?subject=SSW Internship
Application&[email protected]; [email protected]
- tagline: Learn how to build
secondaryTagline: Enterprise Applications
heroBackground: /images/polygonBackground.png
person: /images/people/ulysses.png
link:
linkText: Apply Now
url: >-
mailto:[email protected]?subject=SSW Internship Application&[email protected]; [email protected]
mailto:[email protected]?subject=SSW Internship
Application&[email protected]; [email protected]
- tagline: Become a
secondaryTagline: First Class Microsoft Developer
heroBackground: /images/polygonBackground.png
person: /images/ben-intern-2.png
link:
linkText: Apply Now
url: >-
mailto:[email protected]?subject=SSW Internship Application&[email protected]; [email protected]
mailto:[email protected]?subject=SSW Internship
Application&[email protected]; [email protected]
---


Expand All @@ -227,3 +230,5 @@ trainingHeaderCarousel:





2 changes: 1 addition & 1 deletion pages/training/[filename].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function TrainingPage(
});

const videoCardProps =
data.training.videos?.videoCards?.map<VideoCardProps>((m) => ({
data?.training.videos?.videoCards?.map<VideoCardProps>((m) => ({
title: m.title,
link: m.link,
})) || [];
Expand Down

0 comments on commit 15c6812

Please sign in to comment.