-
Notifications
You must be signed in to change notification settings - Fork 167
Make Status Site Calendar Functional with users OOO data #1375
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
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Summary by CodeRabbit
WalkthroughAdds a new RTK Query tag type "Logs", introduces a logs API slice with a getLogs endpoint and lazy hook, and integrates lazy log fetching into UserSearchField to map REQUEST_CREATED logs into calendar data. Updates the SearchField prop signature to emit CalendarData[] and adjusts loading/submit logic accordingly. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant SearchField as UserSearchField
participant UsersAPI as Users API Query
participant LogsAPI as Logs API (RTK Query)
participant Parent as Parent Component
User->>SearchField: Enter username and submit
SearchField->>UsersAPI: Query user by text
UsersAPI-->>SearchField: User result (or none)
alt user found
SearchField->>LogsAPI: useLazyGetLogsQuery(params: username,type,format,dev)
LogsAPI-->>SearchField: LogsResponse
Note over SearchField: Filter REQUEST_CREATED<br/>toMs(timestamp) ➜ CalendarData[]
SearchField->>Parent: onSearchTextSubmitted(user, CalendarData[])
else no user
SearchField->>Parent: onSearchTextSubmitted(undefined, [])
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review by Korbit AI
Korbit automatically attempts to detect when you fix issues in new commits.
| Category | Issue | Status |
|---|---|---|
| Unconstrained string parameters ▹ view | ||
| Redundant undefined fallback for username ▹ view | ||
| Function recreation on every render ▹ view | ||
| Event handler with multiple responsibilities ▹ view | ✅ Fix detected | |
| Unmaintainable Hard-coded API Parameters ▹ view | ||
| Ambiguous date/time field types ▹ view | ||
| Unexplained Magic Number in Timestamp Conversion ▹ view | ||
| Unnecessary parameter spreading ▹ view | ||
| Invalid type casting in toMs function ▹ view |
Files scanned
| File Path | Reviewed |
|---|---|
| src/app/services/api.ts | ✅ |
| src/app/services/logsApi.ts | ✅ |
| src/components/Calendar/UserSearchField.tsx | ✅ |
Explore our documentation to understand the languages and file types we support and the files we ignore.
Check out our docs on how you can make Korbit work best for you and your team.
|
|
||
| // Fetch logs for OOO data only | ||
| const logsResult = await triggerGetLogs({ | ||
| username: user.username || undefined, |
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.
Redundant undefined fallback for username 
Tell me more
What is the issue?
Unnecessary fallback to undefined when user.username is already optional and could be undefined.
Why this matters
This creates confusing logic where an empty string would be converted to undefined, which may not be the intended behavior and could cause API calls to fail unexpectedly.
Suggested change ∙ Feature Preview
Pass the username directly without the unnecessary fallback:
const logsResult = await triggerGetLogs({
username: user.username,
type: 'REQUEST_CREATED',
format: 'feed',
dev: true,
});Provide feedback to improve future suggestions
💬 Looking for more details? Reply to this comment to chat with Korbit.
| const toMs = (value?: number | string) => { | ||
| if (typeof value === 'string') { | ||
| const parsed = Date.parse(value); | ||
| return isNaN(parsed) ? undefined : parsed; | ||
| } | ||
| if (typeof value !== 'number') return undefined as unknown as number; | ||
| return value >= 1e12 ? value : value * 1000; | ||
| }; |
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.
Function recreation on every render 
Tell me more
What is the issue?
Timestamp conversion function is defined inside the component causing recreation on every render.
Why this matters
Function recreation on each render cycle wastes memory and CPU cycles, especially problematic when processing arrays of log entries.
Suggested change ∙ Feature Preview
Move the toMs function outside the component or wrap it in useCallback:
const toMs = useCallback((value?: number | string) => {
if (typeof value === 'string') {
const parsed = Date.parse(value);
return isNaN(parsed) ? undefined : parsed;
}
if (typeof value !== 'number') return undefined as unknown as number;
return value >= 1e12 ? value : value * 1000;
}, []);Provide feedback to improve future suggestions
💬 Looking for more details? Reply to this comment to chat with Korbit.
| query: (params) => ({ | ||
| url: '/logs', | ||
| params: { | ||
| username: params.username, | ||
| type: params.type, | ||
| format: params.format, | ||
| dev: params.dev, | ||
| }, | ||
| }), |
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.
Unnecessary parameter spreading 
Tell me more
What is the issue?
The query method unnecessarily spreads parameters individually when the entire params object could be passed directly, violating the KISS principle.
Why this matters
Manual parameter spreading creates maintenance overhead as any new parameter would require modifying both the type and the spreading code. This violates DRY and makes the code more prone to errors.
Suggested change ∙ Feature Preview
query: (params) => ({
url: '/logs',
params
}),Provide feedback to improve future suggestions
💬 Looking for more details? Reply to this comment to chat with Korbit.
| const parsed = Date.parse(value); | ||
| return isNaN(parsed) ? undefined : parsed; | ||
| } | ||
| if (typeof value !== 'number') return undefined as unknown as number; |
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.
Invalid type casting in toMs function 
Tell me more
What is the issue?
The toMs function returns undefined cast as number when the input is not a number, which creates a type inconsistency.
Why this matters
This type casting will cause runtime errors when the returned value is used in numeric operations or comparisons, as undefined cannot be treated as a number.
Suggested change ∙ Feature Preview
Return undefined directly and update the return type to allow undefined:
const toMs = (value?: number | string): number | undefined => {
if (typeof value === 'string') {
const parsed = Date.parse(value);
return isNaN(parsed) ? undefined : parsed;
}
if (typeof value !== 'number') return undefined;
return value >= 1e12 ? value : value * 1000;
};Provide feedback to improve future suggestions
💬 Looking for more details? Reply to this comment to chat with Korbit.
| timestamp?: string | number; | ||
| from?: string | number; | ||
| until?: string | number; |
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.
Ambiguous date/time field types 
Tell me more
What is the issue?
Date/time fields accept both string and number types without validation or normalization, creating ambiguity in how temporal data should be handled.
Why this matters
This will lead to inconsistent date handling throughout the application, potential runtime errors when consuming code expects a specific format, and difficulty in performing date operations like comparisons or formatting.
Suggested change ∙ Feature Preview
Define consistent types for temporal fields. Either use a single type (e.g., ISO string) or create a union with specific formats:
type LogEntry = {
type: string;
timestamp?: string; // ISO 8601 format
from?: string; // ISO 8601 format
until?: string; // ISO 8601 format
taskTitle?: string;
};Or if the API returns mixed formats, add transformation logic in the query to normalize the data.
Provide feedback to improve future suggestions
💬 Looking for more details? Reply to this comment to chat with Korbit.
| const handleOnSubmit = async (e: React.FormEvent) => { | ||
| e.preventDefault(); | ||
| setDisplayList([]); | ||
| const user = usersList.find( | ||
| (user: userDataType) => user.username === searchText | ||
| ); | ||
| onSearchTextSubmitted(user, data); | ||
|
|
||
| if (!user) { | ||
| onSearchTextSubmitted(undefined, []); | ||
| return; | ||
| } | ||
|
|
||
| // Fetch logs for OOO data only | ||
| const logsResult = await triggerGetLogs({ | ||
| username: user.username || undefined, | ||
| type: 'REQUEST_CREATED', | ||
| format: 'feed', | ||
| dev: true, | ||
| }); | ||
|
|
||
| const logsResponse = logsResult.data; | ||
|
|
||
| const oooEntries = (logsResponse?.data || []) | ||
| .filter((log: LogEntry) => log && log.type === 'REQUEST_CREATED') | ||
| .map((log: LogEntry) => ({ | ||
| startTime: toMs(log.from), | ||
| endTime: toMs(log.until), | ||
| status: 'OOO', | ||
| })) | ||
| .filter((e) => e.startTime && e.endTime); | ||
|
|
||
| const mapped = [ | ||
| { | ||
| userId: user.id, | ||
| data: oooEntries, | ||
| }, | ||
| ]; | ||
|
|
||
| onSearchTextSubmitted(user, mapped); | ||
| }; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
| const toMs = (value?: number | string) => { | ||
| if (typeof value === 'string') { | ||
| const parsed = Date.parse(value); | ||
| return isNaN(parsed) ? undefined : parsed; | ||
| } | ||
| if (typeof value !== 'number') return undefined as unknown as number; | ||
| return value >= 1e12 ? value : value * 1000; | ||
| }; |
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.
Unexplained Magic Number in Timestamp Conversion 
Tell me more
What is the issue?
The toMs function contains a magic number (1e12) without explanation of its significance in the timestamp conversion logic.
Why this matters
Future developers will need to deduce why this specific threshold was chosen for timestamp conversion, making maintenance more difficult.
Suggested change ∙ Feature Preview
const MILLISECONDS_TIMESTAMP_THRESHOLD = 1e12; // Threshold to differentiate between seconds and milliseconds timestamps
const toMs = (value?: number | string) => {
if (typeof value === 'string') {
const parsed = Date.parse(value);
return isNaN(parsed) ? undefined : parsed;
}
if (typeof value !== 'number') return undefined as unknown as number;
return value >= MILLISECONDS_TIMESTAMP_THRESHOLD ? value : value * 1000;
};Provide feedback to improve future suggestions
💬 Looking for more details? Reply to this comment to chat with Korbit.
| const logsResult = await triggerGetLogs({ | ||
| username: user.username || undefined, | ||
| type: 'REQUEST_CREATED', | ||
| format: 'feed', | ||
| dev: true, | ||
| }); |
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.
Unmaintainable Hard-coded API Parameters 
Tell me more
What is the issue?
Hard-coded string literals 'REQUEST_CREATED' and 'feed' are used directly in the API call without type safety or centralized configuration.
Why this matters
Changes to these values would require searching through code, and typos won't be caught by the compiler.
Suggested change ∙ Feature Preview
const LOG_TYPES = {
REQUEST_CREATED: 'REQUEST_CREATED'
} as const;
const LOG_FORMATS = {
FEED: 'feed'
} as const;
const logsResult = await triggerGetLogs({
username: user.username || undefined,
type: LOG_TYPES.REQUEST_CREATED,
format: LOG_FORMATS.FEED,
dev: true,
});Provide feedback to improve future suggestions
💬 Looking for more details? Reply to this comment to chat with Korbit.
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: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/Calendar/UserSearchField.tsx (1)
98-111: Minor: avoid recomputing users for validationYou already search for the user on submit. Consider deriving isValidUsername by caching that lookup (or by setting a selected user on click) to avoid repeated O(n) scans on every render.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
src/app/services/api.ts(1 hunks)src/app/services/logsApi.ts(1 hunks)src/components/Calendar/UserSearchField.tsx(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/app/services/logsApi.ts (1)
src/app/services/api.ts (1)
api(9-38)
src/components/Calendar/UserSearchField.tsx (1)
src/interfaces/user.type.ts (1)
userDataType(1-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build (18.x)
🔇 Additional comments (3)
src/app/services/api.ts (1)
31-31: Add Logs tag type — looks goodThe tag type matches the slice usage and enables cache participation for logs endpoints.
If any slices currently invalidate/provide 'Logs', confirm they use the exact same string literal to avoid cache misses.
src/components/Calendar/UserSearchField.tsx (2)
168-174: Good: disable submit during fetch and invalid inputDisabling on loading, isLogsFetching, empty/invalid username prevents bad requests.
16-21: Incorrect — not a global breaking changeThe onSearchTextSubmitted signature change is confined to src/components/Calendar/UserSearchField.tsx. Its consumer src/pages/calendar/index.tsx already calls onSearchTextSubmitted={(user, data) => …}, and the Issues search component is a different file (src/components/issues/SearchField.tsx) that still expects a string. No widespread call-site updates are required.
Likely an incorrect or invalid review comment.
src/app/services/logsApi.ts
Outdated
| type LogEntry = { | ||
| type: string; | ||
| timestamp?: string | number; | ||
| from?: string | number; | ||
| until?: string | number; | ||
| taskTitle?: string; | ||
| }; |
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.
🧹 Nitpick
Export types for reuse in consumers
Calendar/UserSearchField redefines LogEntry locally. Exporting types here avoids drift and duplication.
Apply this diff:
-type LogEntry = {
+export type LogEntry = {
type: string;
timestamp?: string | number;
from?: string | number;
until?: string | number;
taskTitle?: string;
};
-type LogsResponse = {
+export type LogsResponse = {
data: LogEntry[];
message?: string;
};Also applies to: 18-22
🤖 Prompt for AI Agents
In src/app/services/logsApi.ts around lines 10-16 (and similarly for lines
18-22), the LogEntry type is declared locally but not exported, causing
duplicate redefinitions in consumers like Calendar/UserSearchField; export the
type so other modules can import and reuse it (e.g., change the declaration to
an exported type or interface) and update any local consumers to import this
exported LogEntry rather than redefining it.
| getLogs: builder.query<LogsResponse, LogsQueryParams>({ | ||
| query: (params) => ({ | ||
| url: '/logs', | ||
| params: { | ||
| username: params.username, | ||
| type: params.type, | ||
| format: params.format, | ||
| dev: params.dev, | ||
| }, | ||
| }), | ||
| providesTags: ['Logs'], | ||
| }), |
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.
🧹 Nitpick
Consider narrowing param and payload types
If the backend has known enums (e.g., type: 'REQUEST_CREATED' | ... and format: 'feed' | ...), modeling those as string literal unions will prevent typos at call sites.
🤖 Prompt for AI Agents
In src/app/services/logsApi.ts around lines 25 to 36, the query currently
accepts broad string types for params.type and params.format; narrow these by
defining and using string-literal unions or exported enums for known backend
values (e.g., type: 'REQUEST_CREATED' | 'REQUEST_COMPLETED' | ... and format:
'feed' | 'json' | ...), update the LogsQueryParams type to reference those
unions/enums, adjust the builder.query generic to use the new type, and update
any call sites to import the new enums/unions so callers get compile-time checks
against typos.
| query: (params) => ({ | ||
| url: '/logs', | ||
| params: { | ||
| username: params.username, | ||
| type: params.type, | ||
| format: params.format, | ||
| dev: params.dev, | ||
| }, | ||
| }), | ||
| providesTags: ['Logs'], |
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
Avoid sending undefined/falsey query params
fetchBaseQuery will serialize params directly; sending undefined/empty values can lead to confusing server behavior. Build the params object conditionally to include only defined keys.
Apply this diff:
- query: (params) => ({
- url: '/logs',
- params: {
- username: params.username,
- type: params.type,
- format: params.format,
- dev: params.dev,
- },
- }),
+ query: (params) => {
+ const q: Record<string, string | boolean> = {};
+ if (params.username) q.username = params.username;
+ if (params.type) q.type = params.type;
+ if (params.format) q.format = params.format;
+ if (params.dev === true) q.dev = true;
+ return {
+ url: '/logs',
+ params: q,
+ };
+ },📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| query: (params) => ({ | |
| url: '/logs', | |
| params: { | |
| username: params.username, | |
| type: params.type, | |
| format: params.format, | |
| dev: params.dev, | |
| }, | |
| }), | |
| providesTags: ['Logs'], | |
| query: (params) => { | |
| const q: Record<string, string | boolean> = {}; | |
| if (params.username) q.username = params.username; | |
| if (params.type) q.type = params.type; | |
| if (params.format) q.format = params.format; | |
| if (params.dev === true) q.dev = true; | |
| return { | |
| url: '/logs', | |
| params: q, | |
| }; | |
| }, | |
| providesTags: ['Logs'], |
🤖 Prompt for AI Agents
In src/app/services/logsApi.ts around lines 26 to 35, the generated query always
includes keys even when params values are undefined/falsey which causes
fetchBaseQuery to serialize unwanted params; change the query builder to
construct the params object conditionally so only keys with defined
(non-undefined) values are included (e.g., build an empty object and add
username/type/format/dev only when params.username !== undefined, etc., or use a
small helper to filter out undefined entries) so the request URL contains only
intended query parameters.
| overrideExisting: true, | ||
| }); |
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.
🧹 Nitpick
Drop overrideExisting unless you need to replace existing endpoints
Setting overrideExisting: true can accidentally mask endpoint name collisions from other injectors. Prefer the default false unless you’re intentionally overriding.
Apply this diff:
- overrideExisting: true,
+ // Prefer the default (false) to avoid masking accidental name collisions
+ overrideExisting: false,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| overrideExisting: true, | |
| }); | |
| // Prefer the default (false) to avoid masking accidental name collisions | |
| overrideExisting: false, | |
| }); |
🤖 Prompt for AI Agents
In src/app/services/logsApi.ts around lines 38 to 39, the configuration
currently sets overrideExisting: true which can mask endpoint name collisions;
remove the overrideExisting property (or set it to false) so the default
behavior prevents accidental endpoint replacement, then run the injector/tests
to verify no intentional overrides are required and update any callers if a
deliberate override was intended.
| import classNames from './UserSearchField.module.scss'; | ||
| import { useGetAllUsersQuery } from '@/app/services/usersApi'; | ||
| import { logs } from '@/constants/calendar'; | ||
| import { useLazyGetLogsQuery } from '@/app/services/logsApi'; |
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.
🧹 Nitpick
De-duplicate LogEntry type; import from logsApi instead
Reuse the exported LogEntry type to avoid divergence.
Apply this diff:
-import { useLazyGetLogsQuery } from '@/app/services/logsApi';
+import { useLazyGetLogsQuery, type LogEntry } from '@/app/services/logsApi';And remove the local duplicate:
-type LogEntry = {
- type: string;
- timestamp?: string | number;
- from?: string | number;
- until?: string | number;
- taskTitle?: string;
-};Also applies to: 8-15
🤖 Prompt for AI Agents
In src/components/Calendar/UserSearchField.tsx around lines 4 to 15, the file
defines a local duplicate LogEntry type; instead import the exported LogEntry
type from '@/app/services/logsApi' (add it to the existing import on line 4) and
remove the local LogEntry definition and any other duplicated type declarations
between lines 8–15 so the component uses the single shared LogEntry type from
logsApi.
| type CalendarData = { | ||
| userId: string; | ||
| data: { | ||
| startTime: number | undefined; | ||
| endTime: number | undefined; | ||
| status: string; | ||
| }[]; | ||
| }; |
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.
🧹 Nitpick
Constrain status to a specific literal
If this component only emits OOO entries, narrow status to 'OOO' to catch accidental values.
Apply this diff:
- data: {
- startTime: number | undefined;
- endTime: number | undefined;
- status: string;
- }[];
+ data: Array<{
+ startTime: number | undefined;
+ endTime: number | undefined;
+ status: 'OOO';
+ }>;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| type CalendarData = { | |
| userId: string; | |
| data: { | |
| startTime: number | undefined; | |
| endTime: number | undefined; | |
| status: string; | |
| }[]; | |
| }; | |
| type CalendarData = { | |
| userId: string; | |
| data: Array<{ | |
| startTime: number | undefined; | |
| endTime: number | undefined; | |
| status: 'OOO'; | |
| }>; | |
| }; |
🤖 Prompt for AI Agents
In src/components/Calendar/UserSearchField.tsx around lines 24 to 31, the
CalendarData type currently allows any string for the status field; constrain it
to the specific literal 'OOO' by replacing the status: string type with status:
'OOO' so TypeScript will catch accidental values—update the type definition
accordingly and run type checks to ensure all usages conform to the narrowed
literal type.
| const toMs = (value?: number | string) => { | ||
| if (typeof value === 'string') { | ||
| const parsed = Date.parse(value); | ||
| return isNaN(parsed) ? undefined : parsed; | ||
| } | ||
| if (typeof value !== 'number') return undefined as unknown as number; | ||
| return value >= 1e12 ? value : value * 1000; | ||
| }; |
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.
Fix toMs return type and remove unsafe cast
Returning undefined as unknown as number lies to the type system and can hide bugs. Return number | undefined and use Number.isNaN for clarity.
Apply this diff:
- const toMs = (value?: number | string) => {
- if (typeof value === 'string') {
- const parsed = Date.parse(value);
- return isNaN(parsed) ? undefined : parsed;
- }
- if (typeof value !== 'number') return undefined as unknown as number;
- return value >= 1e12 ? value : value * 1000;
- };
+ const toMs = (value?: number | string): number | undefined => {
+ if (typeof value === 'string') {
+ const parsed = Date.parse(value);
+ return Number.isNaN(parsed) ? undefined : parsed;
+ }
+ if (typeof value !== 'number') return undefined;
+ return value >= 1e12 ? value : value * 1000;
+ };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const toMs = (value?: number | string) => { | |
| if (typeof value === 'string') { | |
| const parsed = Date.parse(value); | |
| return isNaN(parsed) ? undefined : parsed; | |
| } | |
| if (typeof value !== 'number') return undefined as unknown as number; | |
| return value >= 1e12 ? value : value * 1000; | |
| }; | |
| const toMs = (value?: number | string): number | undefined => { | |
| if (typeof value === 'string') { | |
| const parsed = Date.parse(value); | |
| return Number.isNaN(parsed) ? undefined : parsed; | |
| } | |
| if (typeof value !== 'number') return undefined; | |
| return value >= 1e12 ? value : value * 1000; | |
| }; |
🤖 Prompt for AI Agents
In src/components/Calendar/UserSearchField.tsx around lines 45 to 52, the toMs
function currently lies to TypeScript by returning "undefined as unknown as
number" and uses isNaN; change the function signature to return number |
undefined, remove the unsafe cast, and use Number.isNaN for clarity: when value
is a string parse it and return parsed or undefined; when value is not a number
return undefined; otherwise return value (treating values < 1e12 as seconds and
multiply by 1000). Ensure the function's TypeScript signature and all call sites
accept number | undefined.
| // Fetch logs for OOO data only | ||
| const logsResult = await triggerGetLogs({ | ||
| username: user.username || undefined, | ||
| type: 'REQUEST_CREATED', | ||
| format: 'feed', | ||
| dev: true, | ||
| }); | ||
|
|
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.
Do not hardcode dev=true in production paths
Leaking a dev flag to the API from client code can expose internal behavior. Gate it with an env var and omit when disabled.
Apply this diff:
- const logsResult = await triggerGetLogs({
+ const logsResult = await triggerGetLogs({
username: user.username || undefined,
type: 'REQUEST_CREATED',
format: 'feed',
- dev: true,
+ dev:
+ process.env.NEXT_PUBLIC_LOGS_DEV === 'true'
+ ? true
+ : undefined,
});Note: With the paired logsApi change to drop falsey params, dev will be omitted unless explicitly enabled.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Fetch logs for OOO data only | |
| const logsResult = await triggerGetLogs({ | |
| username: user.username || undefined, | |
| type: 'REQUEST_CREATED', | |
| format: 'feed', | |
| dev: true, | |
| }); | |
| // Fetch logs for OOO data only | |
| const logsResult = await triggerGetLogs({ | |
| username: user.username || undefined, | |
| type: 'REQUEST_CREATED', | |
| format: 'feed', | |
| dev: | |
| process.env.NEXT_PUBLIC_LOGS_DEV === 'true' | |
| ? true | |
| : undefined, | |
| }); |
🤖 Prompt for AI Agents
In src/components/Calendar/UserSearchField.tsx around lines 69–76, the call to
triggerGetLogs hardcodes dev: true; change it to only pass dev when a build-time
env var enables it (e.g. VITE_ENABLE_DEV_LOGS or REACT_APP_ENABLE_DEV_LOGS).
Read the env var into a boolean (e.g. const enableDevLogs =
Boolean(import.meta.env.VITE_ENABLE_DEV_LOGS) or
process.env.REACT_APP_ENABLE_DEV_LOGS), and conditionally include dev: true in
the triggerGetLogs call only when enableDevLogs is truthy so the param is
omitted in production builds (the logsApi will drop falsy params).
| const oooEntries = (logsResponse?.data || []) | ||
| .filter((log: LogEntry) => log && log.type === 'REQUEST_CREATED') | ||
| .map((log: LogEntry) => ({ | ||
| startTime: toMs(log.from), | ||
| endTime: toMs(log.until), | ||
| status: 'OOO', | ||
| })) | ||
| .filter((e) => e.startTime && e.endTime); | ||
|
|
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
Preserve zero epoch and tighten filtering
Truthiness check drops 0 timestamps. Use nullish checks instead.
Apply this diff:
- .filter((e) => e.startTime && e.endTime);
+ .filter((e) => e.startTime != null && e.endTime != null);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const oooEntries = (logsResponse?.data || []) | |
| .filter((log: LogEntry) => log && log.type === 'REQUEST_CREATED') | |
| .map((log: LogEntry) => ({ | |
| startTime: toMs(log.from), | |
| endTime: toMs(log.until), | |
| status: 'OOO', | |
| })) | |
| .filter((e) => e.startTime && e.endTime); | |
| const oooEntries = (logsResponse?.data || []) | |
| .filter((log: LogEntry) => log && log.type === 'REQUEST_CREATED') | |
| .map((log: LogEntry) => ({ | |
| startTime: toMs(log.from), | |
| endTime: toMs(log.until), | |
| status: 'OOO', | |
| })) | |
| .filter((e) => e.startTime != null && e.endTime != null); |
🤖 Prompt for AI Agents
In src/components/Calendar/UserSearchField.tsx around lines 79 to 87, the final
.filter currently uses a truthiness check (e.startTime && e.endTime) which will
drop valid timestamps equal to 0; change the filter to check for null/undefined
explicitly (e.g., e.startTime !== null && e.startTime !== undefined && e.endTime
!== null && e.endTime !== undefined, or the shorter e.startTime != null &&
e.endTime != null) so zero epoch values are preserved.
Date: 29-09-2025
Developer Name: Rishi Chaubey
Issue Ticket Number
Description
Documentation Updated?
Under Feature Flag
Database Changes
Breaking Changes
Development Tested?
Screenshots
Screenshot 1
Test Coverage
Screenshot 1
Additional Notes
Description by Korbit AI
What change is being made?
Inject a new Logs API and wire it into the calendar user search to fetch and attach OOO log entries as calendar data.
Why are these changes being made?
Add a real logs endpoint integration to replace mock data and provide structured, per-user OOO entries for the calendar view. This enables using actual server data for calendar rendering and improves data accuracy.