-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
257 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import { ImageResponse } from "next/og"; | ||
// import CalendarGen from "@/components/Generators/Calendar"; | ||
import { Day } from "@/types/Calendar"; | ||
|
||
const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; | ||
|
||
export async function POST(request: Request) { | ||
const geist = await fetch( | ||
new URL("../../../../public/fonts/Geist.ttf", import.meta.url), | ||
).then((res) => res.arrayBuffer()); | ||
|
||
try { | ||
const calendar: any = await request.json(); | ||
|
||
if (!calendar) | ||
return new Response( | ||
JSON.stringify({ | ||
message: | ||
"Hmm, An error occured while grabbing your calendar data. Logout and login again.", | ||
fix: "Logout and retry. Its better be old expired cookies 🍪", | ||
}), | ||
{ | ||
status: 500, | ||
headers: { | ||
"content-type": "application/json", | ||
}, | ||
}, | ||
); | ||
|
||
const month = calendar.calendar.month; | ||
const days = calendar.calendar.days; | ||
|
||
const getFirstDayIndex = () => weekdays.indexOf(days[0].day); | ||
|
||
return new ImageResponse( | ||
( | ||
<div tw="bg-[#0a0d12] flex flex-col items-center justify-center h-screen w-screen"> | ||
<h1 tw="text-3xl font-semibold text-white my-8">{month}</h1> | ||
<div tw="max-w-[2000px] flex text-center font-bold bg-[#06090d]"> | ||
{weekdays.map((weekday) => ( | ||
<div | ||
key={weekday} | ||
tw="w-[285px] h-[56px] text-lg p-2 font-medium text-center text-white flex items-center justify-center" | ||
> | ||
{weekday} | ||
</div> | ||
))} | ||
</div> | ||
<div tw="bg-[#0a0d12] text-center flex flex-row flex-wrap max-w-[2000px] w-screen"> | ||
{Array.from({ length: getFirstDayIndex() }, (_, index) => ( | ||
<div tw="flex w-[285px] h-[390px]" key={`empty-${index}`} /> | ||
))} | ||
{days | ||
.filter((a: any) => a.dayOrder.length <= 1) | ||
.map((day: Day, index: number) => ( | ||
<DayCell key={index} day={day} /> | ||
))} | ||
</div> | ||
</div> | ||
), | ||
{ | ||
width: 2100, | ||
height: 2200, | ||
fonts: [ | ||
{ | ||
name: "Geist", | ||
data: geist, | ||
style: "normal", | ||
}, | ||
], | ||
headers: { | ||
"Accept-Encoding": "gzip, deflate, br, zstd", | ||
"cache-control": "private, maxage=86400", | ||
}, | ||
}, | ||
); | ||
} catch (err: any) { | ||
console.warn(err); | ||
return new Response( | ||
JSON.stringify({ | ||
error: err.stack, | ||
}), | ||
{ | ||
status: 500, | ||
statusText: "Server Error", | ||
}, | ||
); | ||
} | ||
} | ||
export const runtime = "edge"; | ||
|
||
function DayCell({ day }: { day: Day }) { | ||
const isErrorDay = day.dayOrder === "-"; | ||
|
||
return ( | ||
<div | ||
aria-label={day.date} | ||
title={`${day.date} - Day Order: ${day.dayOrder}`} | ||
tw={ | ||
`${isErrorDay ? "bg-[#1D0C0C]" : ""} flex max-w-[285px] h-[370px] w-full flex-col justify-between border border-[#1E232B] p-4 items-end` | ||
} | ||
> | ||
<DateDisplay | ||
date={day.date} | ||
day={day.day} | ||
isToday={false} | ||
isErrorDay={isErrorDay} | ||
/> | ||
<HolidayDisplay holiday={day.holiday || ""} isErrorDay={isErrorDay} /> | ||
<DayOrderDisplay dayOrder={day.dayOrder} isToday={false} /> | ||
</div> | ||
); | ||
} | ||
|
||
interface DateDisplayProps { | ||
date: string; | ||
day: string; | ||
isToday: boolean; | ||
isErrorDay: boolean; | ||
} | ||
|
||
const DateDisplay: React.FC<DateDisplayProps> = ({ | ||
date, | ||
day, | ||
isToday, | ||
isErrorDay, | ||
}) => ( | ||
<div tw={`flex ${isErrorDay && !isToday ? "text-[#F75B5B]" : "text-white opacity-70"}`}> | ||
<h2 tw="rounded-full flex text-right text-3xl font-bold">{date}</h2> | ||
</div> | ||
); | ||
|
||
interface HolidayDisplayProps { | ||
holiday: string | null; | ||
isErrorDay: boolean; | ||
} | ||
|
||
const HolidayDisplay: React.FC<HolidayDisplayProps> = ({ | ||
holiday, | ||
isErrorDay, | ||
}) => { | ||
if (!holiday) return null; | ||
return ( | ||
<p | ||
style={{ whiteSpace: "break-spaces" }} | ||
tw={`text-right pr-1 -mb-0.5 -mx-2 text-base ${isErrorDay ? "text-[#F75B5B]" : "rounded-md border-l-2 border-r-0 border-[#7CB3EB] bg-[#1B1D2B] px-1 py-0.5 pl-2 text-[#7CB3EB] opacity-70"}`} | ||
> | ||
{holiday.replaceAll(",", ", ")} | ||
</p> | ||
); | ||
}; | ||
|
||
interface DayOrderDisplayProps { | ||
dayOrder: string; | ||
isToday: boolean; | ||
} | ||
|
||
const DayOrderDisplay: React.FC<DayOrderDisplayProps> = ({ | ||
dayOrder, | ||
isToday, | ||
}) => { | ||
if (dayOrder === "-") return null; | ||
return ( | ||
<h2 tw="w-full pl-1 -mb-0.5 text-xl text-white opacity-70 font-medium text-left"> | ||
Day Order{" "} | ||
<span tw={`ml-2 font-bold`}> | ||
{dayOrder} | ||
</span> | ||
</h2> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
"use client"; | ||
import Link from "@/components/Link"; | ||
import Loading from "@/components/States/Loading"; | ||
import { useCalendar } from "@/provider/CalendarProvider"; | ||
import Image from "next/image"; | ||
import React, { useEffect, useState } from "react"; | ||
import { FaArrowLeft } from "react-icons/fa"; | ||
|
||
export default function Calendar() { | ||
const { calendar, isLoading, error } = useCalendar(); | ||
|
||
const [data, setData] = useState(""); | ||
|
||
useEffect(() => { | ||
if (calendar && calendar[0]) { | ||
fetch(`/calendar/download/api`, { | ||
method: "POST", | ||
body: JSON.stringify({ | ||
calendar: calendar?.[new Date().getMonth() % 5] | ||
}), | ||
headers: { | ||
"Content-Type": "application/json", | ||
} | ||
}) | ||
.then((d) => d.blob()) | ||
.then((res: Blob | MediaSource) => { | ||
const imageUrl = URL.createObjectURL(res); | ||
setData(imageUrl); | ||
}); | ||
} | ||
}, [calendar]); | ||
return ( | ||
<main className="flex h-screen w-screen flex-col items-center justify-center gap-12 bg-light-background-normal dark:bg-dark-background-normal"> | ||
{data ? ( | ||
<> | ||
<Link | ||
href="/academia" | ||
style={{ padding: 12, borderRadius: 32 }} | ||
className="absolute left-6 top-6 z-10 bg-light-error-background text-light-error-color dark:bg-dark-error-background dark:text-dark-error-color" | ||
> | ||
<FaArrowLeft /> | ||
</Link> | ||
<Image | ||
className="scale-70 rounded-3xl" | ||
alt="calendar" | ||
src={data} | ||
width={800} | ||
height={400} | ||
/> | ||
<a | ||
href={data} | ||
download={`calendar.png`} | ||
className="w-fit transform rounded-xl bg-light-background-dark px-5 py-1 font-medium text-light-color transition-all duration-300 hover:scale-105 hover:opacity-80 dark:bg-dark-background-light dark:text-dark-color" | ||
> | ||
Download | ||
</a> | ||
</> | ||
) : ( | ||
<Loading /> | ||
)} | ||
</main> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters