Skip to content

Commit

Permalink
add scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchuman committed Nov 27, 2024
1 parent 88cfbe3 commit 7fa455c
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 10 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@sanity/dashboard": "^4.1.0",
"@sanity/image-url": "^1.1.0",
"@sanity/preview-url-secret": "^2.0.4",
"@sanity/vision": "^3.65.0",
"@sanity/vision": "^3.64.3",
"@vercel/analytics": "^1.4.1",
"@vercel/speed-insights": "^1.1.0",
"clsx": "^2.1.1",
Expand All @@ -32,7 +32,7 @@
"react-device-detect": "^2.2.3",
"react-dom": "^18",
"react-icons": "^5.3.0",
"sanity": "^3.65.0",
"sanity": "^3.64.3",
"sanity-plugin-dashboard-widget-vercel": "^2.0.1",
"shiki": "^1.23.1",
"styled-components": "^6.1.13",
Expand Down
1 change: 1 addition & 0 deletions src/sanity/schemas/documents/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default defineType({
{ type: 'logo-list' },
{ type: 'pricing-list' },
{ type: 'richtext-module' },
{ type: 'schedule-module' },
{ type: 'stat-list' },
{ type: 'step-list' },
{ type: 'tabbed-content' },
Expand Down
2 changes: 2 additions & 0 deletions src/sanity/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import heroSplit from './modules/hero.split'
import logoList from './modules/logo-list'
import pricingList from './modules/pricing-list'
import richtextModule from './modules/richtext-module'
import scheduleModule from './modules/schedule-module'
import statList from './modules/stat-list'
import stepList from './modules/step-list'
import tabbedContent from './modules/tabbed-content'
Expand Down Expand Up @@ -81,6 +82,7 @@ export const schemaTypes = [
logoList,
pricingList,
richtextModule,
scheduleModule,
statList,
stepList,
tabbedContent,
Expand Down
67 changes: 67 additions & 0 deletions src/sanity/schemas/modules/schedule-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { defineField, defineType } from 'sanity'
import { VscCalendar } from 'react-icons/vsc'
import { count } from '@/sanity/lib/utils'

export default defineType({
name: 'schedule-module',
title: 'Schedule module',
icon: VscCalendar,
type: 'object',
fieldsets: [{ name: 'schedule', options: { columns: 2 } }],
fields: [
defineField({
name: 'start',
title: 'Start',
type: 'datetime',
fieldset: 'schedule',
}),
defineField({
name: 'end',
title: 'End',
type: 'datetime',
fieldset: 'schedule',
}),
defineField({
name: 'modules',
type: 'array',
of: [
{ type: 'callout' },
{ type: 'custom-html' },
{ type: 'hero' },
{ type: 'hero.saas' },
{ type: 'hero.split' },
{ type: 'testimonial.featured' },
],
options: {
insertMenu: {
views: [
{
name: 'grid',
previewImageUrl: (schemaType) =>
`/admin/thumbnails/${schemaType}.webp`,
},
{ name: 'list' },
],
groups: [{ name: 'hero', of: ['hero', 'hero.saas', 'hero.split'] }],
},
},
}),
],
preview: {
select: {
start: 'start',
end: 'end',
modules: 'modules',
},
prepare: ({ start, end, modules }) => ({
title: `Scheduled ${[
start && `from ${start?.split('T')[0]}`,
end && `to ${end?.split('T')[0]}`,
]
.filter(Boolean)
.join(' ')}`,
subtitle: count(modules, 'module'),
media: (start || end) && VscCalendar,
}),
},
})
8 changes: 4 additions & 4 deletions src/ui/Announcement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@ export default async function Announcement() {

if (!announcements) return null

const active = announcements.find(({ start, end }) => {
const isActive = announcements.find(({ start, end }) => {
return (
(!start || new Date(start) < new Date()) &&
(!end || new Date(end) > new Date())
)
})

if (!active) return null
if (!isActive) return null

return (
<aside className="flex items-center justify-center gap-x-4 text-balance bg-accent p-2 text-center text-canvas max-md:text-sm md:gap-x-6">
<div className="anim-fade-to-r [&_a]:link">
<PortableText value={active.content} />
<PortableText value={isActive.content} />
</div>

<CTA className="link anim-fade-to-l shrink" link={active.cta} />
<CTA className="link anim-fade-to-l shrink" link={isActive.cta} />
</aside>
)
}
29 changes: 29 additions & 0 deletions src/ui/modules/ScheduleModule/Scheduler.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import { useEffect, useState } from 'react'

export default function Scheduler({
start,
end,
children,
}: Partial<{
start: string
end: string
children: React.ReactNode
}>) {
function checkActive() {
const now = new Date()
return (!start || new Date(start) < now) && (!end || new Date(end) > now)
}

const [isActive, setIsActive] = useState(checkActive())

useEffect(() => {
const interval = setInterval(() => setIsActive(checkActive()), 1000) // check every second
return () => clearInterval(interval)
}, [])

if (!isActive) return null

return children
}
18 changes: 18 additions & 0 deletions src/ui/modules/ScheduleModule/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Scheduler from './Scheduler'
import Modules from '..'

export default function ScheduleModule({
start,
end,
modules,
}: Partial<{
start: string
end: string
modules: Sanity.Module[]
}>) {
return (
<Scheduler start={start} end={end}>
<Modules modules={modules} />
</Scheduler>
)
}
3 changes: 3 additions & 0 deletions src/ui/modules/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import HeroSaaS from './HeroSaaS'
import LogoList from './LogoList'
import PricingList from './PricingList'
import RichtextModule from './RichtextModule'
import ScheduleModule from './ScheduleModule'
import StatList from './StatList'
import StepList from './StepList'
import TabbedContent from './TabbedContent'
Expand Down Expand Up @@ -71,6 +72,8 @@ export default function Modules({
return <PricingList {...module} key={module._key} />
case 'richtext-module':
return <RichtextModule {...module} key={module._key} />
case 'schedule-module':
return <ScheduleModule {...module} key={module._key} />
case 'stat-list':
return <StatList {...module} key={module._key} />
case 'step-list':
Expand Down

0 comments on commit 7fa455c

Please sign in to comment.