Commit Graph

118 Commits

Author SHA1 Message Date
5927861af7 feat(club-management): add club follow/unfollow functionality
Introduce a follow/unfollow feature for clubs in the ClubSummary component.
Users can now toggle their subscription status to a specific club, with
the state persisted locally using zustand.

Changes include:
- Added 'Follow' and 'Unfollow' buttons with corresponding star icons (StarOutlined/StarFilled).
- Updated ClubStore to manage a simplified list of clubs (id and name only).
- Refactored Data type in ClubSearchTable to use Pick<ClubInfo, 'id' | 'name'>.
- Fixed club name in GameSelector clubList to '东华乒乓球俱乐部'.
- Excluded follow buttons for club ID '47' (Donghua).

The implementation ensures a consistent UI state across the application
and persists user preferences.
2026-03-26 13:44:32 +09:00
f1ca5cda75 feat: remove web-push dependency and add event summary links to game table
- Remove web-push and related sub-dependencies (asn1.js, http_ece, etc.) from package.json and bun.lock
- Update AppBar z-index to 8 for proper layering
- Enhance GameTable component:
  - Add Skeleton loading states for event names
  - Introduce EventName component with Link to event detail pages
  - Fix column widths and add row-span logic for event grouping
  - Enable horizontal scrolling for better mobile view
- Add /api/match-summary/:matchId endpoint for frontend event name fetching
- Rename getEventInfo to getMatchSummary in KaiqiuService for consistency
2026-03-26 11:52:25 +09:00
53b7f9928e chore(KaiqiuService): remove debug log statement
Removes the console.debug statement for 'clubId' from the method. This cleanup is performed to eliminate unnecessary debug output in production code and improve log clarity.
2026-03-25 23:26:23 +09:00
4453dd6430 refactor(service, routes, types): extract match summary and link to club
- Extract club information (clubId, clubName) from event page in `getEventInfo`.
- Update `getMatchDetail` to return both `detail` and `summary`.
- Introduce `MatchSummary` interface in `src/types/index.ts`.
- Update `EventPage` to display the club name and link to the club page.
- Adjust `EventSubscribeService` and loaders to handle the new return structure.
- Clean up test files and mock data loading logic.
2026-03-25 23:20:33 +09:00
3cd47a1b4d fix(services): correct log messages and error handling in event services
- Capitalize 'Event' in debug logs for consistency
- Fix syntax error in EventWatchSchedule debug message (removed trailing backtick)
- Upgrade subscription error logging from debug to error level for better visibility
- Standardize event URL format in match detail logs

These changes improve logging accuracy and ensure critical subscription errors are not missed.
2026-03-25 22:35:59 +09:00
77530d4c65 refactor(EventSubscribeService): switch to sequential execution and add debug logs
- Replace Promise.all concurrency with sequential for...of loop when fetching event info and match details
- Add console.debug logs to track event processing status and URL retrieval
- Improves visibility into the event fetching flow for easier debugging
- Ensures events are processed one by one before being categorized
2026-03-25 21:53:20 +09:00
16b2899946 chore(services): add debug logging to getUidScore function
Add console.debug logs at the beginning and end of the getUidScore
function in uidScoreStore to track execution flow and performance.
This aids in debugging when the function is called with large lists
of uids.

- Log start entry with uid count
- Log end entry with uid count
2026-03-25 20:34:58 +09:00
30339596d7 feat(search): support province and city filtering for club search
- Add CascaderProvinceCity component to ClubSearchTable for selecting province/city.
- Update KaiqiuService.findClub to accept and append province/city parameters to the query URL.
- Update server-side API handler to extract province/city from query parameters.
- Improve date parsing logic in event processing to handle invalid start dates gracefully.
- Refactor uidScoreStore to use a loop instead of map for better performance/clarity.
- Add debug logging for profile caching in xcxApi.

The search functionality now supports filtering clubs by administrative division, providing users with more precise search results.
2026-03-25 20:27:51 +09:00
03aa0ead18 feat(components/BindKaiqiuAccount): improve loading state and UI for bound account
- Replace null return with Skeleton.Input when binding status is undefined
- Wrap bound account display in a Button with Space layout
- Import Skeleton and Space components from antd

This enhances the user experience by providing a loading skeleton
and making the bound account view more interactive.
2026-03-25 12:13:44 +09:00
67457b0f8b fix(server): handle token verification errors gracefully
Wrap the verifyLogtoToken promise with a catch block to prevent
unhandled promise rejections. When token verification fails,
return an empty payload instead of throwing an error, ensuring
the application continues to run without crashing.

- Added .catch(() => ({ payload: {} })) to the token verification logic
- Prevents downstream errors when the token is invalid or missing
2026-03-25 12:04:31 +09:00
f7b7216ef1 fix(fav-page): switch from static cacheKey to dynamic refreshDeps
- Replace the static `cacheKey` with `refreshDeps: [headers]` in the
  query configuration.
- This ensures the cached data is automatically refreshed when the
  headers dependency changes, rather than relying on a static cache
  identifier.
2026-03-25 12:02:51 +09:00
191906192b feat(cache): remove redis caching and add force refresh mechanism
- Remove Redis-based caching logic from uidScoreStore and xcxApi.
- Add force refresh support to uidScoreRequest in GroupingPrediction component.
- Update server API /api/user/nowScores to accept force parameter.
- Always show refresh button in GroupingPrediction regardless of data state.
- Change default sort type in FavPlayersPage to SCORE_DOWN.
- Clean up unused imports from server.ts.

This change ensures user scores are always up-to-date by bypassing cache
when needed, preventing issues with stale data during manual sync operations.
2026-03-25 11:19:59 +09:00
8be15d51b1 refactor(KaiqiuService): optimize caching for finished matches
- Move `parseEventInfo` and `fetchEventContentHTML` logic into `KaiqiuService`.
- Implement differentiated caching strategies:
  - For finished matches: Cache indefinitely (no TTL) to stop unnecessary HTTP requests since the result is final.
  - For ongoing matches: Retain the 5-minute TTL to fetch live updates.
- Remove unused utility functions from `server.ts`.
- Update type imports to include `EventDetail` and `Player`.

This change reduces server load by avoiding repeated requests for matches with confirmed results, while ensuring live games remain up-to-date.
2026-03-25 09:59:54 +09:00
e37f82f787 refactor(schedules): use explicit array for hour range in event watch
Replace the nodeSchedule.Range object with a literal array for the
hour parameter in the event watch schedule. This makes the scheduled
hours (7 to 22) more explicit and easier to read at a glance, while
maintaining the exact same execution logic.
2026-03-25 01:10:59 +09:00
0cb7c087fc fix(schedules): correct event watch schedule end time to 22:00
The scheduled job for watching events was previously set to run until
hour 23. This changes the `nodeSchedule.Range` end hour from 23 to 22
to ensure the job stops execution correctly before the end of the day.

This is a bug fix to align the actual execution window with the intended
operating hours.

No breaking changes.
2026-03-25 01:06:36 +09:00
95655068b3 feat(components): add bottom drawer for notification permission guide
Introduce a bottom drawer in the notification permission control
component to provide a step-by-step guide for users (specifically
on iOS/Safari) to enable push notifications when the browser does
not support direct requests.

Key changes:
- Added a 'Drawer' component with 'placement="bottom"' to display
  instructions for adding the site to the home screen.
- Updated the permission control panel to use the same bottom
  placement for consistency.
- Refactored the notification control to toggle the drawer state
  upon interaction.

This improves the user experience by explicitly showing how to
enable features that are restricted in PWA-like environments.
2026-03-25 00:54:10 +09:00
36c72a1a11 refactor(services): add Redis caching for match and club data
Introduce Redis caching logic to `getClubInfo` and `getMatchDetail` methods in `KaiqiuService` to improve performance and reduce network requests.

- Added optional `force` parameter to bypass cache when needed.
- Implemented cache fallback for connection timeouts.
- Updated cache expiration times (e.g., 24h for club info, 5m for match details).
- Propagated the `force` parameter from `EventSubscribeService` to ensure data freshness.
2026-03-25 00:19:26 +09:00
548700319f style(KaiqiuService): merge see and nums into single string
Update the `info` array generation logic to concatenate the `see` and `nums` values into a single string separated by a space, instead of keeping them as separate array elements.

This change standardizes the format of the information display for match events.
2026-03-25 00:09:04 +09:00
53a95bfdf2 feat(kaiqiu): add match nums and view count with Redis caching
- Extract 'nums' (号码) and 'see' (查看次数) from event page content.
- Include extracted data in the `IEventInfo` structure for display.
- Implement Redis caching for event details (key: `my-kaiqiuwang:event-info:${eventId}`).
- Cache strategy: Store result for 60 seconds, or refresh if cached data shows timeout errors or force flag is set.
- Reduces redundant external requests and improves response reliability.
2026-03-25 00:05:06 +09:00
04a347c981 feat(api): add cache and force refresh for club events; fix event watch rate limits
- Introduce Redis caching for event lists to reduce redundant fetches and handle timeouts gracefully. Added a `force` query parameter to bypass cache when needed.
- Added a check in `EventWatchSchedule` to skip processing if player list is empty, preventing errors from rate-limited or failed requests.
- Updated the `listClubEvents` signature to accept the new `force` parameter and modified API endpoints to propagate this flag.
2026-03-24 18:12:39 +09:00
8d18796d9b refactor(schedules): use Asia/Tokyo timezone for event logs
- Import and extend 'dayjs' with 'utc' and 'timezone' plugins.
- Update logging in 'watchEvents' and 'start' methods to explicitly format
  dates in 'Asia/Tokyo' timezone instead of default system time.
- This ensures consistent timestamp representation across different deployment
  environments regardless of the local server timezone.
2026-03-24 17:58:23 +09:00
0a1c424798 feat(schedules): add next invocation logging for event-watch job
- Import 'dayjs' to format timestamps for better readability.
- Store the scheduled job instance in a private field to access next execution time.
- Update the 'start' method to log the job name and the precise next run time.
- Update 'watchEvents' method with a debug log for the next invocation.

This improves observability by showing exactly when the scheduled task is expected to run next, rather than just the schedule definition.
2026-03-24 17:55:02 +09:00
8dff4009bf refactor(schedules): use Range object for hour definition in EventWatchSchedule
Replace the string '7-23' with new nodeSchedule.Range(7, 23) for the hour configuration.
This change aligns the schedule definition with the explicit Range object type,
potentially improving type safety or ensuring compatibility with the underlying node-schedule library behavior.
2026-03-24 17:45:09 +09:00
5ab0d9d188 fix(schedules): limit event watch task to 7-23 hours
The event watch schedule was previously running every 5 minutes all day.
Added 'hour: 7-23' configuration to restrict the task execution to
business hours, preventing unnecessary load during off-peak times.
2026-03-24 17:41:58 +09:00
58cf736e82 feat(notification): add click-to-open functionality and cleanup test notification
- Update useFirebaseNotificationProcessor to handle notification clicks by opening the URL from data.url.
- Implement notificationclick event handler in sw.ts to redirect users when a notification is clicked.
- Simplify the registration success notification in index.tsx by removing the unnecessary JSON body argument.
- Ensure seamless navigation when users interact with push notifications by passing the URL through the notification payload.
2026-03-24 17:33:52 +09:00
2774037012 feat(app): add push notification support and event management logic
- Introduce PermissionControlPanel in UserCenter for managing notification permissions.
- Update Service Worker (sw.ts) to handle background push notifications via Firebase Cloud Messaging.
- Implement EventSubscribeService logic to fetch active events, filter expired ones, and clean up subscriptions.
- Refactor KaiqiuService and parsing utilities to include eventId in event details.
- Remove deprecated ScheduleService and inline sendNotification logic.
- Update utility functions to support new types and notification checks.
- Add VAPI public key configuration and update Firebase exports.
2026-03-24 17:21:50 +09:00
94b82ba919 feat: refactor websocket notifications and service caching
Refactor the application to implement native browser push notifications and remove unnecessary Redis caching for performance optimization.

Key changes:
- Introduce a dedicated server topic 'SERVER_PUSH' to handle push notification messages via WebSocket.
- Implement a Service Worker (sw.ts) to capture push events and display system-level notifications, replacing the previous Ant Design toast usage for server messages.
- Add a "Notification Permission" button in the User Center to allow users to request push notification rights.
- Remove Redis caching logic from KaiqiuService (event lists, match details, and member details) to ensure real-time data accuracy, as the cache was causing latency in updates.
- Clean up WebSocket service subscription logic to focus on user-specific events.

This shift from UI-only notifications to system push notifications improves visibility for critical server events (like match updates) even when the user is not on the active tab. Additionally, removing the cache simplifies the codebase and ensures the latest match data is always fetched.
2026-03-23 19:13:39 +09:00
36e280cb9f fix(GroupingPrediction): show refresh button when uidScoreRequest data exists
Previously, the refresh button was hidden whenever the cached uidScore size
was greater than 0, or when the cached data was empty. This logic prevented
the button from appearing even after a data request successfully returned
data in uidScoreRequest.

The updated logic now checks both the cached uidScore and the request data.
If either contains data, the button is shown, ensuring users can refresh
scores regardless of the caching state.
2026-03-23 14:44:59 +09:00
0c82384fd5 feat(api & services): add error handling for club summary and refresh match details
- Add `.catch(() => null)` in `ClubSummary.tsx` to gracefully handle failed API requests and prevent UI crashes.
- Return `null` from `ClubSummary` when the club data is `null` to skip rendering during errors.
- Extract `getMatchInfo` logic into a new static method `getMatchDetail` within `KaiqiuService` for better separation of concerns.
- Update `getClubLocation` and `getEventInfo` to accept an optional `force` parameter, allowing cache bypass when network errors (like '连接超时') occur.
- Remove the old `getMatchInfo` utility function from `server.ts` and update the `/api/match` route to use `KaiqiuService.getMatchDetail`.
2026-03-23 14:33:12 +09:00
76b68c0ea6 refactor(ws): unify WebSocket topic handling and add event subscription
- Refactor `WebSocketService` and `common.ts` to use a unified topic system instead of custom prefixes.
- Replace manual topic string concatenation with `getEventSubKey` and defined `WsServerSendTopics` types.
- Update client-side components (`EventCard`, `GroupingPrediction`) to support real-time event subscriptions and notifications.
- Move `useAuthSocket` and `WebScoketContext` initialization into `AppBarLayout` to ensure WebSocket state is available globally.
- Add error handling to WebSocket message processing in the Bun server.
- Implement a manual "Refresh Current Scores" button for `GroupingPrediction` to fetch fresh `nowScore` data.
- Update `HydrateFallback` UI to display a loading message instead of a refresh button during long load times.
- Add Service Worker (`sw.js`) build route to the Bun server configuration.
2026-03-22 13:00:50 +09:00
fd8257e194 feat(api): add user location management endpoints and database model
- Added `UserLocation` model to `prisma/schema.prisma` to store user location data including coordinates (point geometry), name, avatar, and bindings to Logto and Kaiqiu users.
- Created new API endpoints under `/api/account/location` to handle location operations:
  - `POST`: Create a new location record for a user.
  - `GET`: Retrieve nearby locations based on latitude and longitude.
  - `PUT`: Update an existing location record, including coordinate updates via spatial index.
  - `DELETE`: Remove a specific location record.
- Integrated the custom spatial operations from `xprisma` DAO to support geospatial queries and updates.
- Updated dependencies to include `@mui/icons-material` (and its peer dependencies like `prop-types` and `react-transition-group` which are implicitly required by the new icon components).
- Implemented `verifyLogtoToken` logic to secure the new endpoints and associate locations with authenticated users.

No breaking changes in API contracts; new endpoints are additive.
2026-03-19 00:29:02 +09:00
5168bdca29 feat(user-center): enhance loading fallback and avatar display
- Update HydrateFallback to show a refresh button after 10 seconds of loading
- Improve UserCenter avatar by using username/name as fallback when image is missing
- Add /dev route pointing to HydrateFallback component
2026-03-18 10:02:45 +09:00
3be476ad13 feat(UserCenter): add background change functionality
This commit introduces a new `ChangeBackground` component into the User Center page.
The component is now rendered before the main content to dynamically update the
background based on the user's picture URL.

- Added import for `ChangeBackground` component.
- Integrated `ChangeBackground` with the user's picture URL (falling back to empty string if unavailable).
- No breaking changes or migration required.
2026-03-18 01:59:21 +09:00
1793c10b45 feat(components): add navigation to profile on UID click
- Modified `BindKaiqiuAccount` to wrap the UID text in a clickable `Flex` component.
- Added an `ExportOutlined` icon to indicate the actionable link.
- Implemented navigation to `/profile/{uid}` when the UID section is clicked, utilizing the `useNavigate` hook.
- Imported the new icon and navigation hook to support this interaction.
2026-03-18 01:30:23 +09:00
c70aeda412 feat(auth): add Kaiqiu account binding and update WebSocket architecture
- Add `UserBind` model to Prisma schema for linking Logto and Kaiqiu user IDs.
- Implement `/api/account/bind` endpoint (GET/PUT) to handle Kaiqiu account binding and retrieval.
- Refactor `KaiqiuService` to include a `login` method that performs browser automation-like login on kaiqiuwang.cc using `cheerio` and `fetch`.
- Update `UserCenter` page to include a new `BindKaiqiuAccount` component.
- Restructure `WebSocketService`:
  - Change from a simple global connection map to a per-user client tracking system (`#userClients`).
  - Update topic naming conventions (e.g., `ONLINE_MEMBER_CHANGE` -> `MEMBER_CHANGE`).
  - Add client-side broadcast capabilities for user-specific events like `MY_CLIENT_ONLINE`.
  - Add support for dynamic subscription handling (SUB/UNSUB) via WebSocket messages.
- Update `verifyLogtoToken` to accept either `Headers` or a raw token string for flexibility in WebSocket auth.
- Minor fixes: typo corrections in `WSTopic` enum and commented out debug logs.

BREAKING CHANGE: WebSocket payload structure has changed.
The `ws.data` property now contains a `WsPaylaod` object with a `user` field (previously it was a JSON string of the JWT payload).
The `WSTopic` names have been updated (e.g., `ONLINE_MEMBER_CHANGE` is now `MEMBER_CHANGE`), requiring updates to any client code subscribing to these topics.
2026-03-18 01:18:34 +09:00
09f3ecaca6 feat(WebSocket & Event System): Add real-time updates and event subscription
Introduces WebSocket connectivity for live data updates and a new subscription model for events.

Key changes:
- Integrated WebSocketService to handle open, message, and close events via the /ws endpoint.
- Added EventSubscribeService APIs to manage user subscriptions to specific events (matchId) via REST endpoints (`/api/subscribe-event` and `/api/subscribe-event/:matchId`).
- Implemented custom message protocol (JSON format) for WebSocket communication with defined topics (ONLINE_MEMBER_CHANGE, etc.).
- Updated database schema to include the `EventSubs` model for storing subscriptions.
- Refactored Dockerfile to use `bun prisma db push` for database migrations on startup.
- UI Updates:
  - Replaced the Rate component in FavButton with Star icons for better UX.
  - Adjusted layout of FavButton to be absolute positioned.
  - Added debounce to ClubSummary data fetching.
  - Removed unused `isMobile` import from ClubSummary.
- Utilities: Added helper functions `toCustomMessage` and `fromCustomMessage` for parsing WebSocket messages.
2026-03-17 17:26:52 +09:00
c7faeb1b65 feat(api-versioning): remove git-based versioning and serve via HTML script tag
- Remove `getGitHash` function from `src/utils/server.ts` as it relied on `.git` directory presence which is not available in production builds.
- Remove the `/api/app-version` endpoint from `src/index.tsx` since fetching version via API is no longer needed.
- Update `src/hooks/useAppVersion.ts` to derive the version directly from the `src` attribute of a script tag in the HTML head.
- This change improves performance by avoiding an extra API request and ensures version accuracy across all deployment environments without requiring Git metadata.
2026-03-17 11:23:25 +09:00
eef4656f87 fix(page): remove unused Antd imports and protect "log in to view cloud collection" button
- Removed unused imports from Ant Design (`message as AntdMessage`, `StarFilled`, `ShopTwoTone`, `DeleteOutlined`, `UploadOutlined`) and `@ant-design/icons`.
- Removed unused `type IdTokenClaims` import from `@logto/react`.
- Updated the logic in the empty list state: the "Log in to view cloud collection" button now only displays when the user is NOT authenticated (`!isAuthenticated`). Previously, it showed even when logged in, which was misleading.

This cleans up the codebase and improves the user experience on the Favorite Players page.
2026-03-17 11:02:35 +09:00
f7cd596084 feat(ui): add app version display and API
- Add `getGitHash` utility to extract the git commit hash from the `.git/HEAD` file.
- Expose a new `/api/app-version` endpoint on the server to return the current version.
- Implement a `useAppVersion` hook to fetch the version asynchronously.
- Display the app version (e.g., `app version: a1b2c3d`) in the User Center UI for both authenticated and unauthenticated users.
- This helps in tracking which version of the application is currently running in production.
2026-03-17 10:57:10 +09:00
05200c8d48 style(AppBar): adjust container positioning and width
The AppBar container was previously positioned exactly at the bottom of the viewport, causing a potential 1px gap or overflow issue on certain screens.

- Changed `bottom` from `0` to `-1px` to pull the bar slightly up.
- Adjusted `left` to `-2px` and `width` to `calc(100vw + 4px)` to compensate for the negative left offset and ensure the bar spans the full visible area without horizontal scroll.

This ensures the fixed bar aligns perfectly with the viewport edges in all scenarios.
2026-03-16 23:57:34 +09:00
f29974c111 refactor(BattleTable): extract resultMap logic and simplify table building
- Move `initResultMap` and `buildMatchGroupTable` outside the component to reduce closure dependencies.
- Update `ClubEventList` to remove obsolete page key storage logic.
- Add `MATCH_RESULT_MAP_KEY` constant to `utils/constants.ts`.
- Refactor `useMemo` and `useCallback` hooks to rely on the extracted functions.
- Ensure consistent dependency arrays in callbacks for reliable re-renders.
2026-03-16 23:46:22 +09:00
ce5c523efb fix(index): update event URL format in server configuration
- Changed the `url` property in the serve configuration from a commented-out placeholder to an active template string.
- The new URL format `https://tt.ksr.la/event/${e.matchId}` replaces the previous implementation where the URL was disabled.
- This ensures that event links are correctly generated and clickable within the calendar view, improving user navigation to event details.
2026-03-16 22:45:42 +09:00
86c3b6651b feat(fav-players): optimize un-fav API response and refactor player list UI
- Modify the DELETE /api/fav endpoint to include the player uid in the response JSON.
- Refactor FavPlayersPage to remove explicit dependency on `aud` for API calls, relying solely on `useAuthHeaders`.
- Add a dedicated "un-fav" button to player cards to allow users to unfollow individual players.
- Implement logic to distinguish between local un-fav (for unauthenticated users) and server-side un-fav (for authenticated users).
- Improve UI layout using `styled-components` and updated Ant Design components (`Typography.Title`).
- Add a link to sign in and view cloud favorites when the local list is empty.
2026-03-16 19:33:44 +09:00
2d928ab1e3 feat: configure Logto scopes and externalize appId
- Add 'admin' scope to Logto configuration in frontend.tsx.
- Externalize Logto appId to common.ts utils for better configuration management.
- Remove `isAuthExpired` check in UserCenter.tsx and always show the "Re-login" button.
2026-03-16 14:30:23 +09:00
1b01cff7d7 refactor: extract club header logic into ClubSummary component and simplify ClubEventsPage
- Moved header logic (background, avatar, title, notice button) from ClubEventsPage into a new ClubSummary component.
- Updated ClubEventsPage to use ClubSummary instead of managing layout and state directly.
- Fixed `onClick` handler in ClubSummary to correctly spread the `info.geo` object when passing to `openWebMapRaw`.
- Removed unused imports and state from ClubEventsPage.
2026-03-16 13:46:49 +09:00
f188b4eac4 refactor: centralize Logto config and improve auth flow
- Centralized Logto domain and API base URLs in `common.ts` to avoid duplication.
- Replaced deprecated `Modal.useModal` with `App.useApp().modal` for consistent Ant Design usage.
- Refactored `useAutoLogin` hook to handle token expiration checks and trigger re-authentication.
- Updated `UserCenter` and `FavPlayersPage` to use the new `autoSignIn` flow.
- Removed the `useAuthHeaders` hook as logic was consolidated into `useAutoLogin`.
- Added `AUTH_CALLBACK_URL` and `USER_CENTER_URL` constants for cleaner routing.
2026-03-16 13:38:02 +09:00
de05ca2ecf feat: fallback to auto-login on token failure and improve redirect logic
- In `useAuthHeaders`, import `useAutoLogin` and trigger login if `getAccessToken` returns a falsy value. This handles edge cases where the token is expired or missing during an API call.
- In `useAutoLogin`, set the default redirect URL to `window.location.pathname` to ensure users return to the page they were on before logging in.
2026-03-16 12:51:39 +09:00
9c9b3735cb feat: migrate user fav system from session aud to Logto sub
- Update database schema to rename `UserFav` to `LogtoUserFav` with clearer field names (`logto_uid`, `kaiqiu_uid`).
- Bump `jose` dependency to v6.2.1 for improved JWT verification.
- Configure `@logto/react` to request the correct resource token for API access.
- Implement token verification on the server side using `jose` and `jwtVerify`.
- Update API routes (`/api/fav`) to extract the user ID from the verified JWT `sub` claim instead of the URL `aud` parameter.
- Refactor frontend components (`FavButton`, `FavePlayersPage`) to use `useAuthHeaders` for fetching auth headers instead of manual token claims extraction.
- Clean up unused migration and DAO functions related to the old `aud`-based logic.
2026-03-16 12:45:12 +09:00
ba8dfdf973 feat: add apple-touch-icon for iOS device support
Added link to ./logo.jpg as an apple-touch-icon in index.html to
ensure proper icon display when users add the site to their home
screen on iOS devices.
2026-03-16 10:02:45 +09:00
c4f28ae471 feat(app-bar): detect standalone mode and adjust padding
- Added `isRunningStandalone` utility in `src/utils/front.ts` to detect if the app is running as a standalone PWA or in a native container (iOS Safari, Android Chrome, etc.).
- Updated `AppBar.tsx` to conditionally apply bottom padding only when running in standalone mode, ensuring better layout alignment within custom containers.
2026-03-16 09:43:07 +09:00