Refactor: consolidate page metadata and improve code organization - #56
Merged
Merged
Conversation
Bugs - Enter on 취소 in a delete confirmation no longer confirms the delete. - Removing an attachment only detaches it; dropped files are deleted once the save lands, and unsaved uploads are deleted when the editor is abandoned. One failed upload no longer discards the others. - Markdown keeps tables and fenced code intact, and leaves YouTube URLs that are already link targets alone. - Timestamps format in the school's time zone, not the server's UTC. - Notice summaries skip leading blank lines and strip markdown, so a description starting with a blank line still makes the card a link. - The notice editor guards against double submit. - Snapshotting a week into the standing timetable places slots by period. Logic - The schedule sync and calendar share one window keyed on the school year, so January and February can reach the months since March. - Open tabs reload their data when the KST day, 4pm rollover, or dinner cutoff passes. - Fetched timetable rows are stamped with their Monday and matched on it, so a stale row is never shown as this week; the timetable page labels the week it shows. - Auth failures are ConvexErrors; an expired session returns the admin to the PIN screen, and notice validation errors reach the editor. UI - Calendar grid has a fixed width, so long event titles no longer widen cells month to month. - Class label in notice titles comes from config; notice pages get og:url. - Admins can edit an empty standing timetable directly. - Calendar legend lists 학급 일정; colour picker labels are Korean. - Meals hide the type toggle when only one type exists and show 원산지. - ErrorState no longer prints raw errors; stale upload hint removed; file input resets so the same file can be picked again. - app.html: absolute splash paths, one status-bar style, closing body. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7d8MT7fdW13YS6oRm7q3p
Ran the app against a local Convex backend seeded with real school data and drove every page with Playwright at phone and desktop widths. Fixes - Universal loads pass SvelteKit's fetch to the Convex client, so hydration reuses the SSR responses instead of re-querying every source. - Drawer: Escape closes it wherever focus is, and focus returns to the control that opened it. The calendar's add field still cancels only the form on Escape. - Timetable cell editor keeps its content while the sheet slides out. - Markdown tables get styles; they rendered as run-together text. - Four-syllable subjects (추석연휴) no longer truncate on phones. - Copy button stays disabled when there is no 수행평가 to share. - Meal drawer's nutrient grid is two columns on phones. - CSP allows a local Convex backend's origin in development. - File drop zone no longer flickers when dragging over its children. Structure - Shared PageMeta, SectionHeader, RelativeTime and FileIcon components replace per-page head boilerplate and repeated markup. - Admin notice editor and row are components, shared by the current and past-month lists. - Date parts and short dates come from one helper; notice summaries use the backend's summarizeDescription (moved to convex/text.ts). - orFallback, blurActiveElement, holdComposingEnter and a `.field` input class replace repeated inline code. - Calendar paging uses a single month index; cell styling is a function. Comments across the frontend and backend are cut down to the why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7d8MT7fdW13YS6oRm7q3p
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7d8MT7fdW13YS6oRm7q3p
Measured frame by frame with scripted touch gestures on a phone viewport. - Opening no longer flashes the sheet at rest for a frame before it slides up: it starts off screen and is measured after layout. - Tap-to-open and dismiss are critically damped, as UIKit's are. Only a release that carried momentum overshoots (0.8 / 0.3, Apple's drawer). - Dismiss aims past the edge and cuts off there, so the critically damped tail doesn't leave the sheet creeping at the bottom of the screen. - Release velocity is the sheet's own over the last 100ms, not the finger's last event pair. A swipe the content scroller absorbed no longer bounces a sheet that never moved, and rubber-banded releases hand off the banded speed. - Upward momentum now counts in the dismiss decision: flicking up rescues a sheet dragged most of the way down. The threshold is half the height of the projected resting point. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7d8MT7fdW13YS6oRm7q3p
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Applied when meals are stored and again when they are served, so rows already in the database come out clean without a re-fetch. Only a y after a non-Latin character is dropped, so English words ending in y survive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7d8MT7fdW13YS6oRm7q3p
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7d8MT7fdW13YS6oRm7q3p
Audited against the skill's conformance checklist and fixed the failures. Installation and assets - Add apple-mobile-web-app-capable. Without it iOS ignored every startup image; the unprefixed tag alone doesn't enable them. - Generate startup images, their links and manifest icons from one device table and one mark (scripts/generate-app-assets.py). Adds the missing iPhone Air size and a light set: the old images were all dark, so light mode launched dark then flashed to the light page. Both sets now match the first rendered background. 22 sizes x 2 orientations x 2 appearances. - Default apple-touch-icon is the 180px opaque PNG (it was 57px); drop the legacy sizes. - Serve a web app manifest (name from SITE_NAME, standalone, 192/512 and maskable icons). - theme-color values match the real backgrounds; drop obsolete metas. Layout and overlays - The top safe-area inset moves from body padding to the sticky header, so the header clears the status bar once scrolled in a Home Screen app. - The sheet's last section clears the home indicator. - A fixed edge strip, the header colour with the dim applied, makes Safari darken its status bar with the page; the sticky header otherwise keeps the bar undimmed under a sheet. - Single-finger drags on the scrim no longer scroll the page behind it; pinch zoom still passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7d8MT7fdW13YS6oRm7q3p
This branch was successfully deployed
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This refactor consolidates page metadata handling into a reusable
PageMetacomponent and reorganizes imports/utilities across the application for better maintainability and consistency.Key Changes
New Components & Utilities
PageMeta.svelte: New component that centralizes Open Graph and meta tag generation for all pages, replacing inline metadata logicRelativeTime.svelte: New component for displaying relative timestamps that resolve after mount (SSR-safe)FileIcon.svelte: New component for rendering file type icons (images vs documents)AdminNoticeRow.svelte: Extracted notice row rendering logic from admin page for reusabilityNoticeEditor.svelte: Extracted notice form editor into a dedicated component withNoticeFormtype andemptyNoticeForm()helperlib/errors.ts: New utility for centralized error handling withadminErrorMessage()functionlib/dom.ts: New utility for DOM operations (blurActiveElement(),holdComposingEnter())lib/timetable.ts: New utility for timetable week matching logicpackages/backend/convex/text.ts: New backend utility for text processing (URL basename extraction, description summarization)Page Updates
All pages now use the new
PageMetacomponent instead of inline metadata:+page.svelte(home)calendar/+page.sveltetimetable/+page.sveltemeals/+page.sveltenotices/+page.sveltenotice/[id]/+page.svelteadmin/+page.svelteCode Organization Improvements
Backend Improvements
dates.ts: AddedscheduleWindow()function for pagination bounds calculationschema.ts: AddedweekStartfield to timetable documents for better week trackingauth.ts: Improved error handling withConvexErrorfor unauthorized accessnotices.ts: Enhanced error handling and validationUtility Refactoring
lib/date.ts: Consolidated date utilities; re-exported backend functions for client uselib/convex.ts: AddedorFallback()helper for graceful fallback handlinglib/format.ts: Improved file size formatting and addedparseInfoRows()utilitylib/transitions.ts: Simplified motion vocabulary documentationlib/eventChrome.ts: AddedCUSTOM_COLOR_LABELconstantConfiguration
svelte.config.js: Enhanced with environment loading for local Convex backend supportapp.html: Cleaned up splash screen configurationNotable Implementation Details
PageMetacomponent handles both website and article schema types with proper Open Graph tagsRelativeTimeusesonMountto ensure SSR/hydration consistencyNoticeEditorextracted with proper form state management and file upload integrationadminErrorMessage()for consistent user feedbackhttps://claude.ai/code/session_01C7d8MT7fdW13YS6oRm7q3p