-
Notifications
You must be signed in to change notification settings - Fork 0
feat(dashboard): Add locations dashboard and API integration #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- New dashboard index page with location cards - Added locations store with real-time updates - Created API endpoint for fetching locations - Updated sidebar component to use href prop - Refactored location queries and types
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThis change introduces dynamic location listing and loading states in the dashboard and sidebar. It adds new Pinia stores for locations and sidebar items, a secure API for fetching user locations, and a utility for authenticated event handling. The sidebar-button component's navigation prop is renamed from Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DashboardPage
participant LocationsStore
participant SidebarStore
participant API
participant DB
User->>DashboardPage: Visit /dashboard
DashboardPage->>LocationsStore: refresh()
LocationsStore->>API: GET /api/locations
API->>DB: findLocations(userId)
DB-->>API: Locations[]
API-->>LocationsStore: Locations[]
LocationsStore->>SidebarStore: update sidebarItems with Locations
DashboardPage->>User: Show loading, then locations or empty state
SidebarStore->>User: Show sidebar items with locations and loading indicator
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~18 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope changes found. Possibly related PRs
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
utils/define-authenticated-event-handler.ts (1)
25-32
: Remove commented code.The commented code appears to be leftover from development and should be removed to keep the codebase clean.
-// export default defineEventHandler(async (event) => { -// if (!event.context.user) { -// return sendError(event, createError({ -// statusCode: 401, -// statusMessage: "Unauthorized", -// })); -// } -// });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
components/sidebar-button.vue
(2 hunks)lib/db/queries/location.ts
(1 hunks)lib/types.ts
(1 hunks)pages/dashboard.vue
(2 hunks)pages/dashboard/index.vue
(1 hunks)server/api/locations.get.ts
(1 hunks)server/api/locations.post.ts
(1 hunks)stores/locations.ts
(1 hunks)stores/sidebar.ts
(1 hunks)utils/define-authenticated-event-handler.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
lib/db/queries/location.ts (1)
lib/db/schema/location.ts (1)
location
(8-18)
server/api/locations.get.ts (2)
utils/define-authenticated-event-handler.ts (1)
defineAuthenticatedEventHandler
(11-23)lib/db/queries/location.ts (1)
findLocations
(11-15)
utils/define-authenticated-event-handler.ts (1)
lib/auth.ts (1)
UserWithId
(11-13)
stores/locations.ts (1)
stores/sidebar.ts (1)
useSidebarStore
(8-15)
server/api/locations.post.ts (1)
utils/define-authenticated-event-handler.ts (1)
defineAuthenticatedEventHandler
(11-23)
lib/types.ts (1)
lib/auth.ts (1)
UserWithId
(11-13)
🔇 Additional comments (17)
lib/db/queries/location.ts (1)
11-15
: LGTM! Well-implemented database query function.The
findLocations
function correctly filters locations byuserId
using Drizzle ORM'seq
condition, ensuring data isolation between users. The implementation follows the existing patterns in the file and is secure against SQL injection.stores/sidebar.ts (2)
1-6
: Well-defined type interface.The
SidebarItem
type is properly structured with all necessary properties for sidebar navigation items. The use ofhref
instead ofto
aligns with the navigation prop standardization mentioned in the PR objectives.
8-15
: Clean Pinia store implementation.The store follows Pinia composition API best practices with reactive references for
sidebarItems
andloading
state. The implementation is minimal yet sufficient for managing sidebar state.components/sidebar-button.vue (2)
2-7
: Consistent prop rename from 'to' to 'href'.The prop definition has been correctly updated to use
href
instead ofto
, maintaining the same functionality while standardizing navigation prop naming across the application.
18-21
: All prop references correctly updated.The template properly uses
props.href
in both the:to
binding and the conditional class logic for active route highlighting. The functionality remains intact after the prop rename.server/api/locations.get.ts (1)
1-6
: Secure and well-structured API endpoint.The endpoint correctly uses
defineAuthenticatedEventHandler
to enforce authentication and securely accesses the user's locations using their ID from the event context. The implementation follows good security practices by ensuring users can only access their own location data.lib/types.ts (2)
1-1
: Improved type consistency with centralized import.Using
UserWithId
from the./auth
module instead of a local type alias improves consistency and reduces duplication across the application.
6-6
: Consistent typing for authenticated user context.The
H3EventContext
interface now uses the centralizedUserWithId
type, ensuring consistent typing across all authentication-related functionality including the new API endpoints.stores/locations.ts (1)
2-5
: LGTM!The lazy fetch configuration is appropriate for a store, allowing manual control over when data is loaded. The sidebar store integration aligns well with the PR objectives for dynamic sidebar updates.
utils/define-authenticated-event-handler.ts (2)
1-9
: LGTM!The type definitions are well-structured and properly extend the H3Event type to guarantee the presence of an authenticated user in the context.
11-23
: LGTM!The authentication logic is robust with proper error handling and type safety. The 401 response is appropriate for unauthorized access attempts.
pages/dashboard/index.vue (2)
1-8
: LGTM!The script setup properly integrates with the locations store and follows Vue 3 Composition API best practices. The onMounted refresh ensures fresh data is loaded when the component initializes.
10-44
: LGTM!The template perfectly implements all requirements from issues #25 and #26:
- Loading indicator during data fetch
- Location cards displaying name and description
- Empty state with clear call-to-action
- Responsive grid layout for location cards
The conditional rendering logic is clean and user-friendly.
pages/dashboard.vue (3)
3-11
: LGTM!The store integrations are properly implemented, and the conditional refresh logic ensures location data is only fetched when needed on the dashboard root path.
45-45
: LGTM!The prop changes from
to
tohref
are consistent with the sidebar-button component API updates mentioned in the AI summary.Also applies to: 51-51, 72-72
55-68
: LGTM!The dynamic sidebar item rendering properly implements the requirements with appropriate loading states and seamless integration with existing sidebar buttons. The skeleton loading indicator provides good UX during data fetch.
server/api/locations.post.ts (1)
7-9
: LGTM!The refactor to use
defineAuthenticatedEventHandler
is a clean improvement that centralizes authentication logic while maintaining all existing functionality. This enhances code consistency and maintainability across API endpoints.
watchEffect(() => { | ||
if (data.value) { | ||
sidebarStore.sidebarItems = data.value?.map(location => ({ | ||
id: `location-${location.id}`, | ||
label: location.name, | ||
icon: "tabler:map-pin-filled", | ||
href: `/dashboard/${location.id}`, | ||
})); | ||
} | ||
sidebarStore.loading = status.value === "pending"; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Handle the case where location data becomes null or undefined.
The current logic only updates sidebar items when data.value
is truthy, but doesn't clear them when data becomes null or undefined after being initially populated.
watchEffect(() => {
- if (data.value) {
+ if (data.value && data.value.length > 0) {
sidebarStore.sidebarItems = data.value?.map(location => ({
id: `location-${location.id}`,
label: location.name,
icon: "tabler:map-pin-filled",
href: `/dashboard/${location.id}`,
}));
+ } else if (data.value && data.value.length === 0) {
+ sidebarStore.sidebarItems = [];
}
sidebarStore.loading = status.value === "pending";
});
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In stores/locations.ts around lines 7 to 17, the code updates
sidebarStore.sidebarItems only when data.value is truthy but does not clear
sidebarItems if data.value becomes null or undefined later. Modify the
watchEffect to explicitly set sidebarStore.sidebarItems to an empty array or
clear it when data.value is falsy, ensuring the sidebar items reflect the
current state of location data accurately.
- Update environment name in GitHub workflow to use proper capitalization - Rename useLocationStore to useLocationsStore for consistency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
.github/workflows/lint.yml (2)
1-2
: Rename workflow for accuracyThe workflow is still called “Lint”, yet linting is now just a step of the consolidated
build
job. This is confusing when reading the Actions list or configuring required status checks.Rename the file header (
name:
) to something that reflects its new scope, e.g.CI
,Build & Lint
, or similar.
10-12
: Environment & runtime sanity-check
- The blank line at Line 10 is superfluous; trimming avoids accidental indentation mistakes.
environment: Build
requires a repository environment named exactly “Build”. If that environment isn’t configured, the job will stall in “Waiting for environment…”. Verify its existence or remove the key.- You upgraded to Node
22.x
, which is not yet the LTS release. Double-check that the project really targets this version (CI ≠ prod). If not, stay on20.x
LTS.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/workflows/lint.yml
(1 hunks)stores/locations.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- stores/locations.ts
closes #25
closes #26
Summary by CodeRabbit
New Features
Improvements
Bug Fixes