diff --git a/apps/web/scripts/generateCalendarAbacus.tsx b/apps/web/scripts/generateCalendarAbacus.tsx index 1f72db55..5f8c187e 100644 --- a/apps/web/scripts/generateCalendarAbacus.tsx +++ b/apps/web/scripts/generateCalendarAbacus.tsx @@ -16,20 +16,20 @@ const value = parseInt(process.argv[2], 10) const columns = parseInt(process.argv[3], 10) if (isNaN(value) || isNaN(columns)) { - console.error('Usage: npx tsx scripts/generateCalendarAbacus.tsx ') - process.exit(1) + console.error('Usage: npx tsx scripts/generateCalendarAbacus.tsx ') + process.exit(1) } // Use exact same pattern as generateDayIcon - inline customStyles const abacusMarkup = renderToStaticMarkup( - , + ) process.stdout.write(abacusMarkup) diff --git a/apps/web/src/app/api/create/calendar/generate/route.ts b/apps/web/src/app/api/create/calendar/generate/route.ts index 2cf8419c..8ab23330 100644 --- a/apps/web/src/app/api/create/calendar/generate/route.ts +++ b/apps/web/src/app/api/create/calendar/generate/route.ts @@ -33,30 +33,24 @@ export async function POST(request: NextRequest) { // Generate SVGs using script (avoids Next.js react-dom/server restriction) const daysInMonth = getDaysInMonth(year, month) const maxDay = format === 'daily' ? daysInMonth : 31 // For monthly, pre-generate all - const customStyles = abacusConfig?.customStyles || {} + const scriptPath = join(process.cwd(), 'scripts', 'generateCalendarAbacus.tsx') - // Call script to generate all SVGs - const scriptPath = join(process.cwd(), 'scripts', 'generateCalendarSVGs.tsx') - const customStylesJson = JSON.stringify(customStyles) - const svgsJson = execSync(`npx tsx "${scriptPath}" ${maxDay} ${year} '${customStylesJson}'`, { + // Generate day SVGs (1 to maxDay) + for (let day = 1; day <= maxDay; day++) { + const svg = execSync(`npx tsx "${scriptPath}" ${day} 2`, { + encoding: 'utf-8', + cwd: process.cwd(), + }) + writeFileSync(join(tempDir, `day-${day}.svg`), svg) + } + + // Generate year SVG + const yearColumns = Math.max(1, Math.ceil(Math.log10(year + 1))) + const yearSvg = execSync(`npx tsx "${scriptPath}" ${year} ${yearColumns}`, { encoding: 'utf-8', cwd: process.cwd(), }) - - interface CalendarSVGs { - days: Record - year: string - } - - const svgs: CalendarSVGs = JSON.parse(svgsJson) - - // Write day SVGs to temp directory - for (const [key, svg] of Object.entries(svgs.days)) { - writeFileSync(join(tempDir, `${key}.svg`), svg) - } - - // Write year SVG - writeFileSync(join(tempDir, 'year.svg'), svgs.year) + writeFileSync(join(tempDir, 'year.svg'), yearSvg) // Generate Typst document const typstContent = diff --git a/apps/web/src/app/create/calendar/page.tsx b/apps/web/src/app/create/calendar/page.tsx index 6bd2980c..574c0933 100644 --- a/apps/web/src/app/create/calendar/page.tsx +++ b/apps/web/src/app/create/calendar/page.tsx @@ -3,6 +3,7 @@ import { useState } from 'react' import { css } from '../../../../styled-system/css' import { useAbacusConfig } from '@soroban/abacus-react' +import { PageWithNav } from '@/components/PageWithNav' import { CalendarConfigPanel } from './components/CalendarConfigPanel' import { CalendarPreview } from './components/CalendarPreview' @@ -54,75 +55,77 @@ export default function CalendarCreatorPage() { } return ( -
+
- {/* Header */} -
-

- Create Abacus Calendar -

-

- Generate printable calendars with abacus date numbers -

-
- - {/* Main Content */}
- {/* Configuration Panel */} - + {/* Header */} +
+

+ Create Abacus Calendar +

+

+ Generate printable calendars with abacus date numbers +

+
- {/* Preview */} - + {/* Main Content */} +
+ {/* Configuration Panel */} + + + {/* Preview */} + +
-
+ ) } diff --git a/apps/web/src/app/create/page.tsx b/apps/web/src/app/create/page.tsx index c277e21a..25c941e1 100644 --- a/apps/web/src/app/create/page.tsx +++ b/apps/web/src/app/create/page.tsx @@ -102,7 +102,7 @@ export default function CreateHubPage() {
@@ -499,6 +499,203 @@ export default function CreateHubPage() {
+ + {/* Calendar Creator */} + +
+ {/* Icon with gradient background */} +
+ 📅 +
+ + {/* Title */} +

+ Abacus Calendar +

+ + {/* Description */} +

+ Generate printable calendars where every date is shown as an abacus. Perfect for + teaching number representation. +

+ + {/* Features */} +
    +
  • + + ✓ + + Monthly or daily formats +
  • +
  • + + ✓ + + Multiple paper sizes +
  • +
  • + + ✓ + + Uses your abacus styling +
  • +
+ + {/* CTA Button */} +
+
+ Create Calendar + → +
+
+
+ diff --git a/apps/web/src/components/MyAbacus.tsx b/apps/web/src/components/MyAbacus.tsx index ddc8493e..6f658f3e 100644 --- a/apps/web/src/components/MyAbacus.tsx +++ b/apps/web/src/components/MyAbacus.tsx @@ -166,7 +166,8 @@ export function MyAbacus() { isHeroMode ? { // Hero mode: position accounts for scroll to flow with page (subtract scroll to move up with content) - top: `calc(50vh - ${scrollY}px)`, + // Positioned lower (60vh instead of 50vh) to avoid covering subtitle + top: `calc(60vh - ${scrollY}px)`, } : undefined }