earthjasonlin
|
ae1a23143e
|
feat(ui): optimize landing page and showcase for mobile (hamburger nav, 2-col grid, compact lightbox)
|
2026-07-18 09:41:42 +08:00 |
|
earthjasonlin
|
64dfa71bd0
|
chore(ui): update favicon icon
|
2026-07-18 09:22:29 +08:00 |
|
earthjasonlin
|
6624985014
|
chore: remove stray favicon.ico from project root
|
2026-07-18 09:21:13 +08:00 |
|
earthjasonlin
|
e7396de1a4
|
feat(ui): add favicon.ico route and link tag in base template
|
2026-07-18 09:21:07 +08:00 |
|
earthjasonlin
|
b0e69fc123
|
fix(cache): move Cache-Control middleware before mounts using @app.middleware decorator
|
2026-07-18 09:16:45 +08:00 |
|
earthjasonlin
|
8771d105bb
|
chore(deps): add boto3 to requirements.txt
|
2026-07-18 09:13:01 +08:00 |
|
earthjasonlin
|
1c53209acf
|
fix(templates): replace all TemplateResponse with _render to bypass Jinja2 unhashable dict cache bug
|
2026-07-18 09:03:55 +08:00 |
|
earthjasonlin
|
b80a1859a0
|
fix(templates): fix unhashable dict in Jinja2 cache by converting available_languages global to function
|
2026-07-18 08:57:42 +08:00 |
|
earthjasonlin
|
f27c263dd4
|
fix(storage): reduce presigned URL expiry from 7 days to 1 day
|
2026-07-18 08:25:13 +08:00 |
|
earthjasonlin
|
d30fd59ade
|
fix(storage): use presigned URLs for private S3 buckets (7-day expiry)
|
2026-07-18 08:24:40 +08:00 |
|
earthjasonlin
|
2dc68ff408
|
feat(cache): add 30-day browser cache for uploaded images (middleware + S3 CacheControl)
|
2026-07-18 08:23:13 +08:00 |
|
earthjasonlin
|
54d778971d
|
fix(storage): allow S3 without public_url, auto-construct path-style URL from endpoint
|
2026-07-18 08:17:35 +08:00 |
|
earthjasonlin
|
4787fdbf22
|
refactor(config): consolidate into single config.json, storage backend selectable
|
2026-07-18 08:05:39 +08:00 |
|
earthjasonlin
|
3a931fe752
|
feat(storage): add S3 image storage support with file-based config and migration script
|
2026-07-18 08:03:18 +08:00 |
|
earthjasonlin
|
ddeec36a01
|
fix(dashboard): exclude pending postcards from sent stat count
|
2026-07-15 19:40:42 +08:00 |
|
earthjasonlin
|
6636af9990
|
fix(dashboard): hide time for pending postcards in recent activity
|
2026-07-15 19:38:52 +08:00 |
|
earthjasonlin
|
ad85b85e1e
|
fix(dashboard+list): pending status sort first, stats count, badge/recipient/time display
|
2026-07-15 19:36:31 +08:00 |
|
earthjasonlin
|
abec829117
|
fix(i18n): repair broken pc_form.country_from key in postcard form template
|
2026-07-15 19:29:27 +08:00 |
|
earthjasonlin
|
0a8f8c4904
|
fix(i18n): rename country labels to '寄出国/到达国' to avoid ambiguity
|
2026-07-15 19:27:26 +08:00 |
|
earthjasonlin
|
2fe3ea5249
|
fix(postcard): reorder country fields to from→to on both create forms
|
2026-07-15 19:24:02 +08:00 |
|
earthjasonlin
|
05168fb1ca
|
fix(postcard): remove auto option from status dropdown, auto-select silently by date
|
2026-07-15 19:16:41 +08:00 |
|
earthjasonlin
|
5ec21f0e3f
|
feat(postcard): allow manual status override in new-sent form (auto/pending/sent/delivered)
|
2026-07-15 19:10:12 +08:00 |
|
earthjasonlin
|
de29f5445e
|
feat(postcard): split create into sent/received, add pending status and mark-sent flow
|
2026-07-15 19:04:54 +08:00 |
|
earthjasonlin
|
d79aaea4ae
|
fix(web): correct country_to form parameter name mismatch in create and edit routes
|
2026-07-10 23:07:56 +08:00 |
|
earthjasonlin
|
3323523e8e
|
fix(dashboard): put time in its own column on the right side
|
2026-07-07 14:00:07 +08:00 |
|
earthjasonlin
|
afee0b2d92
|
fix(dashboard): country on first line, person + time on second line
|
2026-07-07 13:58:56 +08:00 |
|
earthjasonlin
|
722895a0c8
|
fix(dashboard): wrap recent-meta in container so country and person display on separate lines
|
2026-07-07 13:58:06 +08:00 |
|
earthjasonlin
|
985010d63c
|
fix(dashboard): show country and person on separate lines in recent activity
|
2026-07-07 13:56:07 +08:00 |
|
earthjasonlin
|
599a95ee12
|
fix(ui): fix field name corruption (country_to_from -> country_from) and ensure all flag displays show country code
|
2026-07-07 13:54:00 +08:00 |
|
earthjasonlin
|
fed060ea84
|
fix(ui): hide scroll loading indicator when no more content to load
|
2026-07-07 13:45:25 +08:00 |
|
earthjasonlin
|
ad6f2b2ff2
|
refactor(model): rename Postcard.country -> country_to for clear semantics - country_from: origin country (where postcard was sent from) - country_to: destination country (where postcard was sent to) - Profile.country remains as user's home country - Updated all routes, schemas, templates, and API endpoints
|
2026-07-07 13:43:39 +08:00 |
|
earthjasonlin
|
806c9ba8a0
|
fix(ui): show country code alongside flag emoji in from→to display
|
2026-07-07 13:34:06 +08:00 |
|
earthjasonlin
|
1292c6591b
|
fix(profiles): allow existing profiles to edit country field in rename form
|
2026-07-07 13:28:24 +08:00 |
|
earthjasonlin
|
5de27f1937
|
feat(showcase): display send_time/receive_time on personal showcase cards
|
2026-07-07 13:24:58 +08:00 |
|
earthjasonlin
|
b5716ff340
|
fix(dashboard): sort recent activity by updated_at so delivered/received cards also appear
|
2026-07-07 13:23:39 +08:00 |
|
earthjasonlin
|
a071b3dde4
|
feat(postcard): profile country, country_from, per-user card number uniqueness, public page overhaul - Profile: add country field for default origin country - Postcard: add country_from field, auto-fill from profile.country on create - card_number uniqueness: change from global to per-user (profile_id + card_number) - Public pages: remove card_number display, only show cards with image_front - Public pages: show country as from→to format - Index page: no time display, add register button, fix lightbox with prev/next - Infinite scroll: add /api/public/cards endpoints and IntersectionObserver - Internal pages: update postcards list/detail for country_from display - i18n: add profiles.country_ph, pc_form.country_from, pc_detail.route
|
2026-07-07 12:32:24 +08:00 |
|
earthjasonlin
|
bd664d23be
|
feat(ui): add landing page with random public postcards for unauthenticated visitors
|
2026-07-07 12:05:44 +08:00 |
|
earthjasonlin
|
ba56fc6e6b
|
feat(admin): merge invites + copyright into system admin page with SystemConfig table
|
2026-07-07 11:35:57 +08:00 |
|
earthjasonlin
|
8a4500f723
|
chore: remove scripts and export_i18n.py from git, add to .gitignore
|
2026-07-07 11:35:00 +08:00 |
|
earthjasonlin
|
ce377157a0
|
chore: add server.log to .gitignore
|
2026-07-07 11:31:47 +08:00 |
|
earthjasonlin
|
137304090a
|
chore: stage changes before history rewrite
|
2026-07-07 11:28:18 +08:00 |
|
earthjasonlin
|
a619b919be
|
feat(showcase): add temporary language switcher for visitors with cookie persistence
|
2026-07-07 09:57:20 +08:00 |
|
earthjasonlin
|
02269417a9
|
feat(ui): replace language dropdown with globe icon and expandable menu
|
2026-07-07 09:54:57 +08:00 |
|
earthjasonlin
|
591ad3e178
|
refactor(i18n): move translations to JSON files under app/locales, dynamic language switch
|
2026-07-07 09:46:50 +08:00 |
|
earthjasonlin
|
fb98974382
|
fix(api-docs): replace all hardcoded Chinese with i18n translation keys for English support
|
2026-07-07 09:33:01 +08:00 |
|
earthjasonlin
|
5dc705bf37
|
fix(api-docs): remove inline-block override on settings link button for proper text centering
|
2026-07-07 09:28:58 +08:00 |
|
earthjasonlin
|
6a49fedfbb
|
feat(api): add public RESTful API with API key auth and documentation page
|
2026-07-07 09:22:11 +08:00 |
|
earthjasonlin
|
14c226d082
|
fix(postcards): remove card number format restriction and forced uppercase
|
2026-07-06 23:14:12 +08:00 |
|
earthjasonlin
|
87785494d6
|
feat(i18n): add English localization with per-user language preference
|
2026-07-06 22:41:09 +08:00 |
|
earthjasonlin
|
643f1dc35a
|
fix(dashboard): extract labels/data from tuple list for Chart.js
|
2026-07-06 22:13:46 +08:00 |
|
earthjasonlin
|
f448a900f5
|
feat(i18n): add English localization with per-user language preference and navbar toggle
|
2026-07-06 22:07:05 +08:00 |
|
earthjasonlin
|
172e33e121
|
fix(detail): prevent dt labels from wrapping, allow dd values to wrap
|
2026-07-06 21:13:37 +08:00 |
|
earthjasonlin
|
e7b109ab6d
|
fix(postcards): move notes to right side before action buttons in list, use dl grid format in detail page
|
2026-07-06 21:13:01 +08:00 |
|
earthjasonlin
|
e75c4df4e8
|
style: set CJK+English fonts, reduce base font size to 14px, lighten text colors
|
2026-07-06 21:10:59 +08:00 |
|
earthjasonlin
|
68c88a7910
|
feat(postcards): add notes field to postcards with edit, detail, and truncated list display
|
2026-07-06 21:07:28 +08:00 |
|
earthjasonlin
|
f6db3a4f55
|
feat(dashboard): split country stats into sent/received bar charts side by side
|
2026-07-06 20:41:39 +08:00 |
|
earthjasonlin
|
cf06ab236d
|
revert(dashboard): restore Chart.js bar chart for country distribution
|
2026-07-06 20:35:43 +08:00 |
|
earthjasonlin
|
3320dc95ca
|
feat(dashboard): replace Chart.js with pure HTML/CSS bar chart, flags render correctly
|
2026-07-06 20:34:52 +08:00 |
|
earthjasonlin
|
31eb6dcfc9
|
feat(dashboard): add country distribution bar chart using Chart.js
|
2026-07-06 20:20:46 +08:00 |
|
earthjasonlin
|
200602c1e6
|
feat: auto-trim whitespace from text inputs on form submit globally
|
2026-07-06 20:10:54 +08:00 |
|
earthjasonlin
|
a0e7f46cc5
|
fix(postcards): auto-fill today date on page load for new postcards
|
2026-07-06 20:09:28 +08:00 |
|
earthjasonlin
|
91b4ff8ed4
|
feat(postcards): auto-fill today date on status change, card_number always uppercase
|
2026-07-06 20:06:42 +08:00 |
|
earthjasonlin
|
6157e40db9
|
fix(profiles): remove duplicate border, center-align textarea/button; notes read-only on postcards page
|
2026-07-06 19:41:21 +08:00 |
|
earthjasonlin
|
9db6b849d4
|
feat(profiles): notes shown on postcards page, save stays on current page
|
2026-07-06 19:39:54 +08:00 |
|
earthjasonlin
|
b6d43b3db4
|
feat(profiles): add private notes field per profile, visible only to owner
|
2026-07-06 19:36:29 +08:00 |
|
earthjasonlin
|
233da50554
|
chore: startup scripts one-click launch uvicorn server
|
2026-07-06 19:31:55 +08:00 |
|
earthjasonlin
|
367235fb99
|
fix(admin-invites): badge default bg color, registered users as plain text list
|
2026-07-06 08:43:07 +08:00 |
|
earthjasonlin
|
53c9c4bb86
|
chore: remove test_error.py
|
2026-07-06 08:39:38 +08:00 |
|
earthjasonlin
|
501e27400b
|
fix(models): resolve ambiguous foreign keys between User and InviteCode
|
2026-07-06 08:39:33 +08:00 |
|
earthjasonlin
|
755409f386
|
feat(admin-invites): show registered usernames per invite code, track invited_by_code_id on User
|
2026-07-06 08:37:49 +08:00 |
|
earthjasonlin
|
293a021500
|
fix(admin-invites): left-align create card conditional fields, convert local datetime to UTC on save
|
2026-07-06 08:35:55 +08:00 |
|
earthjasonlin
|
09270bb4af
|
fix(admin-invites): align create card conditional fields styling with edit card
|
2026-07-06 08:33:56 +08:00 |
|
earthjasonlin
|
b9d9de2fc3
|
fix(admin-invites): create form conditional fields inline with nowrap labels, match input styling
|
2026-07-06 08:32:36 +08:00 |
|
earthjasonlin
|
b285c4b588
|
fix(admin-invites): create form label margin-top:0, edit form inline conditional fields
|
2026-07-06 08:27:34 +08:00 |
|
earthjasonlin
|
9aab88ae8f
|
fix(invites): register strftime Jinja2 filter, fix 500 error on admin invites page
|
2026-07-06 08:24:20 +08:00 |
|
earthjasonlin
|
f0a4e704ea
|
fix(admin-invites): create card uses form-card style, align save/delete with select via align-self flex-end
|
2026-07-06 08:21:54 +08:00 |
|
earthjasonlin
|
b10be81505
|
fix(admin-invites): display times in Asia/Shanghai (CST) instead of UTC
|
2026-07-06 08:20:14 +08:00 |
|
earthjasonlin
|
1354032914
|
fix(admin-invites): add margin-top to create button, align save/delete buttons bottom with select via invisible label
|
2026-07-06 08:18:51 +08:00 |
|
earthjasonlin
|
fd7e700e7d
|
fix(admin-invites): increase create form gap, align edit buttons bottom with select
|
2026-07-06 08:17:00 +08:00 |
|
earthjasonlin
|
6af99f36f2
|
fix(admin-invites): unify button height/size, fit-content width for create button
|
2026-07-06 08:15:08 +08:00 |
|
earthjasonlin
|
d4aed47c0a
|
fix(admin-invites): left-align all fields on mobile
|
2026-07-06 08:13:42 +08:00 |
|
earthjasonlin
|
386cc614e7
|
fix(admin-invites): left-align create button
|
2026-07-06 08:12:57 +08:00 |
|
earthjasonlin
|
b4bec6e5e6
|
fix(admin-invites): stack create form fields vertically, unify row height and spacing
|
2026-07-06 08:12:25 +08:00 |
|
earthjasonlin
|
b66527b6d8
|
fix(admin-invites): unify form field styles, fix mobile layout for create and edit forms
|
2026-07-06 08:10:36 +08:00 |
|
earthjasonlin
|
b58956937e
|
feat(invite): add invite code registration system
|
2026-07-06 01:13:07 +08:00 |
|
earthjasonlin
|
a7c5082ff6
|
chore: rename app to 星笺 (Mailova)
|
2026-07-06 00:41:24 +08:00 |
|
earthjasonlin
|
741b51ad6c
|
feat(showcase): sort postcards by time descending
|
2026-07-06 00:27:39 +08:00 |
|
earthjasonlin
|
66ba163ef6
|
feat(showcase): lightbox, checkbox per-card toggle, lazyload, fix toggle Y-align, remove navbar on public page
|
2026-07-06 00:24:03 +08:00 |
|
earthjasonlin
|
2c0229b12f
|
fix(settings): use Query alias for tab param, fix showcase tab persistence
|
2026-07-06 00:10:30 +08:00 |
|
earthjasonlin
|
e0ef607a05
|
fix(showcase): tab stay, Y-center toggle, group postcards by sent/received, hide navbar on public page, remove profiles/xx/showcase
|
2026-07-06 00:05:15 +08:00 |
|
earthjasonlin
|
c550289527
|
refactor(ui): merge showcase settings into settings page tab, fix profile showcase GET route, fix layout
|
2026-07-05 23:56:28 +08:00 |
|
earthjasonlin
|
148cfdf2a4
|
feat(showcase): add public showcase page with per-profile/per-postcard visibility controls
|
2026-07-05 23:45:23 +08:00 |
|
earthjasonlin
|
b412f5001e
|
feat(models): add showcase fields to User, Profile, Postcard
|
2026-07-05 23:35:45 +08:00 |
|
earthjasonlin
|
46670c72fa
|
fix(auth): set session expires_at to non-nullable with 1 year max
|
2026-07-05 23:21:54 +08:00 |
|
earthjasonlin
|
d7780ea6ad
|
feat(ui): move detail page badge next to card number title
|
2026-07-05 23:16:11 +08:00 |
|
earthjasonlin
|
23c61363a6
|
fix(ui): shorten mark-delivered button text to 已送达
|
2026-07-05 23:15:38 +08:00 |
|
earthjasonlin
|
a502c14c99
|
fix(ui): improve detail page mobile layout - smaller title, compact back button, action buttons in one row
|
2026-07-05 23:15:10 +08:00 |
|
earthjasonlin
|
a4cd204237
|
fix(ui): remove duplicate back link from detail page, keep top-left back button
|
2026-07-05 23:12:59 +08:00 |
|
earthjasonlin
|
71a029057a
|
feat(ui): add back button left of card number on detail page
|
2026-07-05 23:11:05 +08:00 |
|
earthjasonlin
|
41aa2058bc
|
fix(ui): vertically center all badges
|
2026-07-05 23:09:47 +08:00 |
|