Added EventGroupingHtmlRenderer initial concept

This commit is contained in:
Franco Speziali 2022-03-17 14:48:10 +01:00
parent 4ff914596b
commit b719a2c391
4 changed files with 188 additions and 0 deletions

View File

@ -0,0 +1,27 @@
import EventGrouping from "../EventGrouping";
import Renderer from "./Renderer";
export default class DayRenderer extends Renderer {
constructor(eventGrouping: EventGrouping) {
super(eventGrouping);
this.container.className += " scale-day";
}
protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
const html = document.createElement("span");
html.className = "event";
const dayInMonth = eventDate.getDate();
if (dayInMonth === 1) {
html.textContent = eventDate
.toLocaleDateString(undefined, { month: "long" })
.slice(0, 3);
html.className += " primary";
} else {
html.textContent = dayInMonth.toString();
}
return html;
}
}

View File

@ -0,0 +1,32 @@
import EventGrouping from "../EventGrouping";
import Renderer from "./Renderer";
export default class MonthRenderer extends Renderer {
constructor(eventGrouping: EventGrouping) {
super(eventGrouping);
this.container.className += " scale-month";
}
protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
const html = document.createElement("span");
html.className = "event";
// unlike getDate(), getMonth is 0 based
const month = eventDate.getMonth() + 1;
if (month === 1) {
html.textContent = eventDate.toLocaleDateString(undefined, {
year: "numeric",
});
html.className += " primary";
} else {
html.textContent = eventDate
.toLocaleDateString(undefined, {
month: "long",
})
.slice(0, 3);
}
return html;
}
}

View File

@ -0,0 +1,101 @@
import { generateRandomColor } from "../utilities";
import EventGrouping from "../EventGrouping";
import { Event } from "../types";
export default abstract class Renderer {
protected abstract renderDateAsIcon(
eventDate: Date,
groupIndex: number
): HTMLSpanElement;
protected container: HTMLDivElement;
protected eventGrouping: EventGrouping;
protected constructor(eventGrouping: EventGrouping) {
this.container = document.createElement("div");
this.container.className = "event-calendar";
this.eventGrouping = eventGrouping;
}
protected renderGroups(): HTMLDivElement[] {
return this.eventGrouping.groups.map((group, index) => {
const html = document.createElement("div");
html.className = "group";
if (group.length) {
const htmlHoverCard = this.renderHoverCard(group);
html.appendChild(htmlHoverCard);
}
let htmlGroupIcon: HTMLSpanElement;
// only need to render icon from first event in group
const event = group[0];
if (event) {
htmlGroupIcon = this.renderIcon(event);
html.className += " icon";
if (event.bgColor) {
html.style.backgroundColor = event.bgColor;
} else {
const randomColor = generateRandomColor();
html.style.backgroundColor = `rgb(${randomColor.r}, ${randomColor.g}, ${randomColor.b})`;
}
} else {
const eventDate = this.eventGrouping.getDateFromGroupIndex(index);
htmlGroupIcon = this.renderDateAsIcon(eventDate, index);
}
html.appendChild(htmlGroupIcon);
return html;
});
}
protected renderHoverCard(events: Event[]): HTMLDivElement {
const htmlHoverCard = document.createElement("div");
htmlHoverCard.className = "hover-card";
const cardDetails = events.map((event) => {
if (!event) {
return;
}
const htmlEvent = document.createElement("div");
const htmlDateText = document.createElement("p");
htmlDateText.textContent = event.date.toLocaleDateString();
const htmlEventTitle = document.createElement("p");
htmlEventTitle.textContent = event.title;
const htmlEventText = document.createElement("p");
htmlEventText.textContent = event.text;
htmlEvent.appendChild(htmlDateText);
htmlEvent.appendChild(htmlEventTitle);
htmlEvent.appendChild(htmlEventText);
return htmlEvent;
});
cardDetails.forEach((cardDetail) => htmlHoverCard.appendChild(cardDetail));
return htmlHoverCard;
}
protected renderIcon(event: Event | undefined): HTMLSpanElement {
const html = document.createElement("span");
html.className = "event";
if (event.icon) {
html.textContent = event.icon;
}
return html;
}
public render() {
const groups = this.renderGroups();
groups.forEach((group) => this.container.appendChild(group));
return this.container;
}
}

View File

@ -0,0 +1,28 @@
import { getWeek } from "date-fns";
import EventGrouping from "../EventGrouping";
import Renderer from "./Renderer";
export default class WeekRenderer extends Renderer {
constructor(eventGrouping: EventGrouping) {
super(eventGrouping);
this.container.className += " scale-week";
}
protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
const html = document.createElement("span");
html.className = "event";
const week = getWeek(eventDate);
if (week === 1) {
html.textContent = eventDate.toLocaleDateString(undefined, {
year: "numeric",
});
html.className += " primary";
} else {
html.textContent = week.toString();
}
return html;
}
}