diff --git a/app/layout.tsx b/app/layout.tsx index 5a2abfd..db8069a 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -44,6 +44,9 @@ export default function RootLayout({
  • Interactive
  • +
  • + Time +
  • Star Wars
  • diff --git a/app/time/dynamic/loading.tsx b/app/time/dynamic/loading.tsx new file mode 100644 index 0000000..dad7d5f --- /dev/null +++ b/app/time/dynamic/loading.tsx @@ -0,0 +1,35 @@ +export default function Loading() { + return ( +
    +

    + The current time is:{' '} + + (force-dynamic) + +

    +
    + + + + + Loading... +
    +
    + ); +} diff --git a/app/time/dynamic/page.tsx b/app/time/dynamic/page.tsx new file mode 100644 index 0000000..ec45ee6 --- /dev/null +++ b/app/time/dynamic/page.tsx @@ -0,0 +1,23 @@ +import { getTime } from '../get-time'; + +export const metadata = { + title: 'Dynamic Time', +}; + +export const dynamic = 'force-dynamic'; + +export default async function Page() { + const time = await getTime('America/Glace_Bay'); + + return ( +
    +

    + The current time is:{' '} + + (force-dynamic) + +

    +

    {time}

    +
    + ); +} diff --git a/app/time/get-time.tsx b/app/time/get-time.tsx new file mode 100644 index 0000000..0e5edc9 --- /dev/null +++ b/app/time/get-time.tsx @@ -0,0 +1,22 @@ +import sleep from '@/util/sleep'; +import { type Time } from './types'; +import { RequestInit } from 'next/dist/server/web/spec-extension/request'; + +export async function getTime( + timezone: string = 'America/New_York', + requestInit?: RequestInit, + shouldSleep: boolean = true +): Promise { + if (shouldSleep) { + await sleep(); + } + + const res = await fetch( + `https://worldtimeapi.org/api/timezone/${timezone}`, + requestInit + ); + + const json: Time = await res.json(); + + return `${new Date(json.datetime).toLocaleTimeString()} (${json.timezone})`; +} diff --git a/app/time/layout.tsx b/app/time/layout.tsx new file mode 100644 index 0000000..583fa54 --- /dev/null +++ b/app/time/layout.tsx @@ -0,0 +1,45 @@ +import Link from 'next/link'; +import { getTime } from './get-time'; + +const navigation = [ + { name: 'Static', href: '/time' }, + { name: 'Dynamic', href: '/time/dynamic' }, + { name: 'No-Store', href: '/time/no-store' }, + { name: 'Revalidate:0', href: '/time/revalidate-0' }, + { name: 'Revalidate:5', href: '/time/revalidate-5' }, + { name: 'Static + Route Revalidate', href: '/time/static-revalidate-route' }, +]; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const time = await getTime(); + return ( +
    +
    +

    + It's Time Time! +

    +
    + {time} +
    +
    + + {children} +
    + ); +} diff --git a/app/time/no-store/loading.tsx b/app/time/no-store/loading.tsx new file mode 100644 index 0000000..283884c --- /dev/null +++ b/app/time/no-store/loading.tsx @@ -0,0 +1,35 @@ +export default function Loading() { + return ( +
    +

    + The current time is:{' '} + + (cache: no-store) + +

    +
    + + + + + Loading... +
    +
    + ); +} diff --git a/app/time/no-store/page.tsx b/app/time/no-store/page.tsx new file mode 100644 index 0000000..0b40629 --- /dev/null +++ b/app/time/no-store/page.tsx @@ -0,0 +1,23 @@ +import { getTime } from '../get-time'; + +export const metadata = { + title: 'cache: no-store time', +}; + +export default async function Page() { + const time = await getTime('Asia/Bangkok', { + cache: 'no-store', + }); + + return ( +
    +

    + The current time is:{' '} + + (cache: no-store) + +

    +

    {time}

    +
    + ); +} diff --git a/app/time/page.tsx b/app/time/page.tsx new file mode 100644 index 0000000..2d1dca5 --- /dev/null +++ b/app/time/page.tsx @@ -0,0 +1,16 @@ +import { getTime } from './get-time'; + +export const metadata = { + title: 'Static Time', +}; + +export default async function Page() { + const time = await getTime('Africa/Lagos'); + + return ( +
    +

    The current time is:

    +

    {time}

    +
    + ); +} diff --git a/app/time/revalidate-0/loading.tsx b/app/time/revalidate-0/loading.tsx new file mode 100644 index 0000000..657bcf9 --- /dev/null +++ b/app/time/revalidate-0/loading.tsx @@ -0,0 +1,35 @@ +export default function Loading() { + return ( +
    +

    + The current time is:{' '} + + (revalidate: 0) + +

    +
    + + + + + Loading... +
    +
    + ); +} diff --git a/app/time/revalidate-0/page.tsx b/app/time/revalidate-0/page.tsx new file mode 100644 index 0000000..dad0815 --- /dev/null +++ b/app/time/revalidate-0/page.tsx @@ -0,0 +1,29 @@ +import { getTime } from '../get-time'; + +export const metadata = { + title: 'revalidate:0 time', +}; + +export default async function Page() { + const time = await getTime( + 'Europe/Moscow', + { + next: { + revalidate: 0, + }, + }, + false + ); + + return ( +
    +

    + The current time is:{' '} + + (revalidate: 0) + +

    +

    {time}

    +
    + ); +} diff --git a/app/time/revalidate-5/loading.tsx b/app/time/revalidate-5/loading.tsx new file mode 100644 index 0000000..0b405fd --- /dev/null +++ b/app/time/revalidate-5/loading.tsx @@ -0,0 +1,35 @@ +export default function Loading() { + return ( +
    +

    + The current time is:{' '} + + (revalidate: 5) + +

    +
    + + + + + Loading... +
    +
    + ); +} diff --git a/app/time/revalidate-5/page.tsx b/app/time/revalidate-5/page.tsx new file mode 100644 index 0000000..f3bec31 --- /dev/null +++ b/app/time/revalidate-5/page.tsx @@ -0,0 +1,29 @@ +import { getTime } from '../get-time'; + +export const metadata = { + title: 'revalidate:5 time', +}; + +export default async function Page() { + const time = await getTime( + 'Pacific/Pago_Pago', + { + next: { + revalidate: 5, + }, + }, + false + ); + + return ( +
    +

    + The current time is:{' '} + + (revalidate: 5) + +

    +

    {time}

    +
    + ); +} diff --git a/app/time/static-revalidate-route/loading.tsx b/app/time/static-revalidate-route/loading.tsx new file mode 100644 index 0000000..c902eec --- /dev/null +++ b/app/time/static-revalidate-route/loading.tsx @@ -0,0 +1,35 @@ +export default function Loading() { + return ( +
    +

    + The current time is:{' '} + + (Static + Revalidate Route) + +

    +
    + + + + + Loading... +
    +
    + ); +} diff --git a/app/time/static-revalidate-route/page.tsx b/app/time/static-revalidate-route/page.tsx new file mode 100644 index 0000000..2ab48c7 --- /dev/null +++ b/app/time/static-revalidate-route/page.tsx @@ -0,0 +1,23 @@ +import { getTime } from '../get-time'; + +export const metadata = { + title: 'Static + Revalidate Route Time', +}; + +export const revalidate = 0; + +export default async function Page() { + const time = await getTime('Europe/Prague'); + + return ( +
    +

    + The current time is:{' '} + + (Static + Revalidate Route) + +

    +

    {time}

    +
    + ); +} diff --git a/app/time/types.tsx b/app/time/types.tsx new file mode 100644 index 0000000..5ae5816 --- /dev/null +++ b/app/time/types.tsx @@ -0,0 +1,17 @@ +export type Time = { + abbreviation: string; + client_ip: string; + datetime: string; + day_of_week: number; + day_of_year: number; + dst: boolean; + dst_from: string; + dst_offset: number; + dst_until: string; + raw_offset: number; + timezone: string; + unixtime: number; + utc_datetime: string; + utc_offset: string; + week_number: number; +};