Feature/admin home#67
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughAdds CreationTime audit fields across backend DTOs and frontend contexts, refactors auth to use ICurrentUser with token bootstrap, introduces EntityMap and getMonthlyCreationChange, and rebuilds the admin dashboard into a responsive kanban layout integrating live student data. ChangesAudit Field Integration & Dashboard Kanban Refactor
Sequence Diagram(s)sequenceDiagram
participant DashboardPage
participant StudentProvider
participant Helper as getMonthlyCreationChange
DashboardPage->>StudentProvider: studentActions.getAllStudents()
StudentProvider-->>DashboardPage: students[]
DashboardPage->>Helper: getMonthlyCreationChange(students)
Helper-->>DashboardPage: percent
DashboardPage->>DashboardPage: render kanban cards (Applications, Courses, Students)
sequenceDiagram
participant AuthProvider
participant LocalStorage as localStorage
participant SessionStorage as sessionStorage
participant Dispatch as authenticateSuccess
AuthProvider->>LocalStorage: read token on mount
alt token valid
AuthProvider->>SessionStorage: read userName
AuthProvider->>Dispatch: dispatch authenticateSuccess(currentUser)
else invalid/missing
AuthProvider->>LocalStorage: remove token
AuthProvider->>SessionStorage: clear
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@next-ts/app/`(dashboard)/admin/(protected)/dashboard/page.tsx:
- Around line 60-62: The trend icon is hardcoded to ArrowUpOutlined; change the
rendering in the stat trend block that uses
getMonthlyCreationChange(studentState.students) so it conditionally shows
ArrowUpOutlined when the value is >= 0 and ArrowDownOutlined when the value is <
0 (keep the numeric result next to the icon); update the JSX in the component
that uses styles.statTrend to branch on the result of getMonthlyCreationChange
rather than always rendering ArrowUpOutlined.
In `@next-ts/src/lib/common/helper-methods.ts`:
- Around line 151-169: The monthly bucketing uses local-time getters and
unvalidated Date parsing; change now/currentMonth/currentYear to use UTC
(now.getUTCMonth()/now.getUTCFullYear()), compute previousMonth/previousYear
from those UTC values, and when iterating items replace new
Date(item.creationTime) with a validated Date (e.g., const createdAt = new
Date(item.creationTime); if (isNaN(createdAt.getTime())) return;) then use
createdAt.getUTCMonth() and createdAt.getUTCFullYear() for comparisons; update
any references to currentMonth/currentYear/previousMonth/previousYear and
createdAt in the items.forEach block accordingly.
In `@next-ts/src/providers/application-provider/context.ts`:
- Line 23: Update the interface in context.ts to make the creationTime field
optional (add '?') so it matches ICourse and IStudent and supports partial
hydration/construction; locate the interface/type that declares creationTime in
this file (context.ts) and change creationTime: Date to creationTime?: Date and
run typechecks to ensure downstream usages handle undefined appropriately.
- Line 34: Remove the misplaced creationTime property from the
IApplicationStateContext interface and add it to the ICourseApplication entity
interface instead: locate IApplicationStateContext and delete the creationTime
field, then open ICourseApplication and declare creationTime?: Date (or
appropriate type) there so the timestamp lives on the entity rather than the
state container.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: c5751d4e-a15b-44e9-bbc4-33bfebdcf4fc
📒 Files selected for processing (10)
aspnet-core/src/Moipone.PublicSite.Application/CourseApplications/Dto/CourseApplicationDto.csaspnet-core/src/Moipone.PublicSite.Application/ShortCourses/Dto/ShortCourseDto.csaspnet-core/src/Moipone.PublicSite.Application/Students/Dto/StudentDto.csnext-ts/app/(dashboard)/admin/(protected)/dashboard/page.tsxnext-ts/app/(dashboard)/admin/(protected)/dashboard/style.tsnext-ts/src/lib/common/constants.tsxnext-ts/src/lib/common/helper-methods.tsnext-ts/src/providers/application-provider/context.tsnext-ts/src/providers/course-provider/context.tsnext-ts/src/providers/student-provider/context.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
next-ts/src/components/Loader/style.ts (1)
4-50: ⚡ Quick winRespect
prefers-reduced-motionfor continuous loader animations.The loader runs continuous rotation/contrast/hue animations with no reduced-motion fallback. Add a media query override to disable or simplify animations for motion-sensitive users.
Also applies to: 68-173
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@next-ts/src/components/Loader/style.ts` around lines 4 - 50, The keyframe animations (`@keyframes` loaderRotation, loaderRoundness, loaderColorize) run continuously and must respect users' motion preferences; add a CSS media query for prefers-reduced-motion: reduce or disable these animations (e.g., set animation: none or a non-moving simplified animation) for the loader elements that reference these keyframes so rotation/contrast/hue changes stop for motion-sensitive users; update the stylesheet to include that media query and ensure the same override is applied wherever those keyframes are used (search for references to loaderRotation, loaderRoundness, loaderColorize in this file).next-ts/src/components/Loader/index.tsx (1)
55-56: ⚡ Quick winAdd accessible status text for the live region.
Line 55 sets a live status region, but it has no readable status message. Add hidden text like “Loading…” so screen readers can announce it.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@next-ts/src/components/Loader/index.tsx` around lines 55 - 56, The live region div with class styles.overlay and attributes role="status" aria-live="polite" is missing readable status text; add an accessible, screen-reader-only message such as "Loading…" inside that div alongside {spinner} (e.g., a span with a visually-hidden/sr-only class from your styles) so screen readers will announce the loading state; ensure the helper class (e.g., styles.srOnly or styles.visuallyHidden) exists in the component stylesheet to hide it visually but keep it available to assistive tech.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@next-ts/app/layout.tsx`:
- Line 25: The root layout currently wraps all page content with
HydrationWrapper which forces a client-side mount and causes server render to
return null; remove HydrationWrapper from the root layout so that children are
rendered server-side (i.e., replace or delete the HydrationWrapper wrapper
around children in layout.tsx), and instead apply the hydration gating pattern
only to specific client-only components by wrapping those narrow components with
HydrationWrapper (or a new client-only wrapper) where needed; reference
HydrationWrapper and children in layout.tsx to locate the change and ensure the
root layout returns the server-rendered children directly.
In `@next-ts/src/components/Loader/index.tsx`:
- Line 9: The component uses React.FC but React isn't imported, causing a
namespace error; import the FC type from 'react' (e.g. add import { FC } from
'react') and update the component signature to use FC<LoaderProps> (const
Loader: FC<LoaderProps> = ...) or alternatively import React (import React from
'react') if you prefer keeping React.FC; ensure Loader and LoaderProps names are
preserved.
---
Nitpick comments:
In `@next-ts/src/components/Loader/index.tsx`:
- Around line 55-56: The live region div with class styles.overlay and
attributes role="status" aria-live="polite" is missing readable status text; add
an accessible, screen-reader-only message such as "Loading…" inside that div
alongside {spinner} (e.g., a span with a visually-hidden/sr-only class from your
styles) so screen readers will announce the loading state; ensure the helper
class (e.g., styles.srOnly or styles.visuallyHidden) exists in the component
stylesheet to hide it visually but keep it available to assistive tech.
In `@next-ts/src/components/Loader/style.ts`:
- Around line 4-50: The keyframe animations (`@keyframes` loaderRotation,
loaderRoundness, loaderColorize) run continuously and must respect users' motion
preferences; add a CSS media query for prefers-reduced-motion: reduce or disable
these animations (e.g., set animation: none or a non-moving simplified
animation) for the loader elements that reference these keyframes so
rotation/contrast/hue changes stop for motion-sensitive users; update the
stylesheet to include that media query and ensure the same override is applied
wherever those keyframes are used (search for references to loaderRotation,
loaderRoundness, loaderColorize in this file).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 9aa9600c-75c9-4f31-aebd-25bc00eae85d
📒 Files selected for processing (6)
next-ts/app/layout.tsxnext-ts/src/components/ContactForm/index.tsxnext-ts/src/components/HydrationWrapper/index.tsxnext-ts/src/components/Loader/index.tsxnext-ts/src/components/Loader/style.tsnext-ts/src/providers/application-provider/context.ts
💤 Files with no reviewable changes (1)
- next-ts/src/providers/application-provider/context.ts
|
@coderabbitai resolve |
✅ Actions performedComments resolved. Approval is disabled; enable |
mblebelo
left a comment
There was a problem hiding this comment.
All checks passed and conversations resolved ✅
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
next-ts/src/providers/auth-provider/index.tsx (1)
81-93:⚠️ Potential issue | 🟠 Major | ⚡ Quick winLogout does not clear token from localStorage or cookie.
Login stores the token in both
localStorage(line 66) and a cookie (line 64), butlogoutonly clearssessionStorage. The token remains accessible after logout.🐛 Proposed fix
const logout = () => { dispatch(logoutPending()); try { + localStorage.removeItem("token"); + document.cookie = "token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"; sessionStorage.clear(); dispatch(logoutSuccess()); router.push('/') }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@next-ts/src/providers/auth-provider/index.tsx` around lines 81 - 93, The logout function currently only clears sessionStorage; update the logout implementation (the logout function that dispatches logoutPending/logoutSuccess/logoutError and calls router.push('/')) to also remove the auth token from localStorage and delete the auth cookie set during login (use the same cookie name used during login), then proceed to dispatch logoutSuccess and navigate; ensure cookie removal uses proper expiration or path/domain matching the original set operation and keep sessionStorage.clear() as well.
🧹 Nitpick comments (1)
next-ts/src/lib/common/constants.tsx (1)
192-206: 💤 Low valueHardcoded badge value will become stale.
The
badge: '12'is static and won't reflect the actual application count. Consider removing it from the static config and computing it dynamically in the sidebar component where you have access to application state.♻️ Suggested approach
- { path: '/admin/applications', icon: FileTextOutlined, label: 'Applications', badge: '12' }, + { path: '/admin/applications', icon: FileTextOutlined, label: 'Applications' },Then in
AdminSidebar, compute the badge from application provider state:const { applications } = useApplicationState(); const pendingCount = applications?.filter(a => a.status === 'pending').length; // Use pendingCount to render badge dynamically🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@next-ts/src/lib/common/constants.tsx` around lines 192 - 206, The dashboardNavItems constant includes a hardcoded badge ('12') which will become stale; remove the badge property from the static config (dashboardNavItems) and instead calculate and render the badge inside the AdminSidebar component by reading application state (e.g., useApplicationState() to get applications and compute pendingCount = applications.filter(a => a.status === 'pending').length) and pass that dynamic count to the sidebar item rendering logic so the badge is derived at render time rather than hardcoded.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@next-ts/src/providers/auth-provider/actions.ts`:
- Line 11: Add and export an action creator for the new
AuthActionEnums.setSessionUser enum so the reducer can be invoked; implement
export const setSessionUser = createAction<IAuthStateContext,
ICurrentUser>(AuthActionEnums.setSessionUser, (user: ICurrentUser) => ({
currentUser: user })); using the existing createAction, IAuthStateContext and
ICurrentUser types and ensure the symbol name setSessionUser is exported; if you
don't want it used yet, add a TODO comment explaining it's reserved for future
use instead.
- Around line 25-31: The createAction call for authenticateSuccess is using the
wrong enum constant (AuthActionEnums.logoutSuccess); update the action type to
AuthActionEnums.authenticateSuccess so the returned action has the correct type
string and triggers the right reducer; locate the authenticateSuccess export and
replace the enum reference while keeping the payload factory and types
(IAuthStateContext, ICurrentUser, RequestState.Success) unchanged.
In `@next-ts/src/providers/auth-provider/index.tsx`:
- Around line 27-30: The expiry branch currently only clears sessionStorage (exp
check around sessionStorage.clear()), leaving the stale token in localStorage so
it will be read again; update that branch to also remove the persisted auth
token from localStorage (either clear localStorage or call
localStorage.removeItem with the same token key used elsewhere) so
expired/invalid tokens are fully purged on expiry.
- Around line 41-43: The catch block that currently calls sessionStorage.clear()
should also remove the malformed auth token from localStorage so it doesn't
cause repeated decode failures on each mount; update the catch following the
token decoding logic to call localStorage.removeItem(...) using the same key
your app uses to store the token (the auth token key used elsewhere in this
provider), or call localStorage.clear() if you purposely want to wipe all
localStorage, ensuring this change is made inside the existing catch block where
token decoding fails.
---
Outside diff comments:
In `@next-ts/src/providers/auth-provider/index.tsx`:
- Around line 81-93: The logout function currently only clears sessionStorage;
update the logout implementation (the logout function that dispatches
logoutPending/logoutSuccess/logoutError and calls router.push('/')) to also
remove the auth token from localStorage and delete the auth cookie set during
login (use the same cookie name used during login), then proceed to dispatch
logoutSuccess and navigate; ensure cookie removal uses proper expiration or
path/domain matching the original set operation and keep sessionStorage.clear()
as well.
---
Nitpick comments:
In `@next-ts/src/lib/common/constants.tsx`:
- Around line 192-206: The dashboardNavItems constant includes a hardcoded badge
('12') which will become stale; remove the badge property from the static config
(dashboardNavItems) and instead calculate and render the badge inside the
AdminSidebar component by reading application state (e.g., useApplicationState()
to get applications and compute pendingCount = applications.filter(a => a.status
=== 'pending').length) and pass that dynamic count to the sidebar item rendering
logic so the badge is derived at render time rather than hardcoded.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: f045f774-23db-47fa-8e0b-0d59fc5b8e03
📒 Files selected for processing (8)
next-ts/app/(dashboard)/admin/(protected)/dashboard/style.tsnext-ts/src/components/About/style.tsnext-ts/src/components/Admin/AdminSidebar/index.tsxnext-ts/src/lib/common/constants.tsxnext-ts/src/providers/auth-provider/actions.tsnext-ts/src/providers/auth-provider/context.tsnext-ts/src/providers/auth-provider/index.tsxnext-ts/src/providers/auth-provider/reducer.ts
✅ Files skipped from review due to trivial changes (1)
- next-ts/src/components/About/style.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@next-ts/src/providers/auth-provider/index.tsx`:
- Around line 27-30: The logout/expiry/failure cleanup paths currently call
localStorage.removeItem("token") and sessionStorage.clear() but do not clear the
auth cookie set at Line 66; update each cleanup location (the blocks containing
localStorage.removeItem("token"); sessionStorage.clear(); return; — also the
similar blocks around Lines 42-45 and 86-90) to also clear the cookie named
"token" (either by invoking a new clearAuthCookie() helper or by expiring the
cookie with proper path/SameSite/Secure attributes) so the cookie is removed
from the browser in every token-invalid/logout/failure path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 9a95029a-9e43-49e9-9b62-065b03485aa4
📒 Files selected for processing (2)
next-ts/src/providers/auth-provider/actions.tsnext-ts/src/providers/auth-provider/index.tsx
| if (!exp || Date.now() >= exp * 1000) { | ||
| localStorage.removeItem("token"); | ||
| sessionStorage.clear(); | ||
| return; |
There was a problem hiding this comment.
Clear the auth cookie in every token-invalid/logout cleanup path.
You set the token cookie at Line 66, but Lines 27-30, 42-45, and 86-90 only clear storage. The cookie can remain and keep being sent after logout/expiry/failure.
🐛 Proposed fix
if (!exp || Date.now() >= exp * 1000) {
localStorage.removeItem("token");
+ document.cookie = "token=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; secure; samesite=strict";
sessionStorage.clear();
return;
}
@@
} catch {
localStorage.removeItem("token");
+ document.cookie = "token=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; secure; samesite=strict";
sessionStorage.clear();
}
@@
try {
localStorage.removeItem("token");
+ document.cookie = "token=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; secure; samesite=strict";
sessionStorage.clear();
dispatch(logoutSuccess());
router.push('/')Also applies to: 42-45, 86-90
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@next-ts/src/providers/auth-provider/index.tsx` around lines 27 - 30, The
logout/expiry/failure cleanup paths currently call
localStorage.removeItem("token") and sessionStorage.clear() but do not clear the
auth cookie set at Line 66; update each cleanup location (the blocks containing
localStorage.removeItem("token"); sessionStorage.clear(); return; — also the
similar blocks around Lines 42-45 and 86-90) to also clear the cookie named
"token" (either by invoking a new clearAuthCookie() helper or by expiring the
cookie with proper path/SameSite/Secure attributes) so the cookie is removed
from the browser in every token-invalid/logout/failure path.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Summary by CodeRabbit
New Features
Improvements
Bug Fixes