Skip to content

fix: improve onboarding and handle undefined values#243

Closed
Benbenzhouz wants to merge 10 commits intomainfrom
fix-onboarding
Closed

fix: improve onboarding and handle undefined values#243
Benbenzhouz wants to merge 10 commits intomainfrom
fix-onboarding

Conversation

@Benbenzhouz
Copy link
Contributor

Changes

Onboarding Improvements

  • Fixed undefined value handling in UserInputArea
  • Fixed AddressAutocomplete undefined errors
  • Improved address input validation

Environment Variables

  • Restored original environment variable names with fallback support
  • Supports both NEXT_PUBLIC_API_BASE_URL and NEXT_PUBLIC_API_URL
  • Centralized API config management via getApiBaseUrl() function
  • No breaking changes to existing environment variable names

Other Fixes

  • Fixed ESLint errors (prefer nullish coalescing)
  • Improved error handling

Environment Variables (No Changes Required)

  • NEXT_PUBLIC_API_BASE_URL (preferred)
  • NEXT_PUBLIC_API_URL (fallback)

Ben Zhou and others added 10 commits December 20, 2025 15:13
- Replace || with ?? in AuthCallbackContent.tsx
- Replace || with ?? in UserInputArea.tsx
- Replace || with ?? in GoogleOAuthButton.tsx
- Replace || with ?? in AddressAutocomplete.tsx
- Replace || with ?? in publicApiSlice.ts
- Replace || with ?? in axiosBaseQuery.ts
- Fix useEffect dependency in AddressAutocomplete.tsx
- Remove console.log statements in AuthCallbackContent.tsx
- Create unified getApiBaseUrl() utility function
- Remove hardcoded localhost fallbacks from all files
- Production environment now requires API URL to be configured
- Development environment allows localhost fallback with warning
- Improves code quality and prevents production misconfigurations

Files updated:
- src/utils/api-config.ts (new)
- src/services/places.ts
- src/lib/axiosBaseQuery.ts
- src/features/public/publicApiSlice.ts
- src/components/GoogleOAuthButton.tsx
- src/app/(public)/blogs/page.tsx
- src/app/(public)/blogs/components/BlogList.tsx
- src/app/(public)/blogs/[id]/page.tsx
- Remove unnecessary NEXT_PUBLIC_API_BASE_URL fallback
- Use only NEXT_PUBLIC_API_URL as it's the actual configured variable
- Simplify code and error messages
- Change from NEXT_PUBLIC_API_URL to NEXT_PUBLIC_API_BASE_URL
- This matches the actual configured environment variable name
- Keep same behavior as before: NEXT_PUBLIC_API_BASE_URL ?? localhost fallback
- Remove production environment check to match original usage
- Environment variable name unchanged: NEXT_PUBLIC_API_BASE_URL
- Function only provides centralized management, no behavior change
…upport

- Restore NEXT_PUBLIC_API_BASE_URL and NEXT_PUBLIC_API_URL support
- Keep function for centralized management
- Match original behavior exactly
Copilot AI review requested due to automatic review settings December 21, 2025 09:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the onboarding flow by fixing undefined value handling and centralizes API configuration management through a new utility function. The changes address ESLint warnings and improve error handling in the OAuth callback flow.

Key Changes:

  • Introduced centralized API base URL configuration via getApiBaseUrl() utility function with fallback support for both NEXT_PUBLIC_API_BASE_URL and NEXT_PUBLIC_API_URL
  • Fixed undefined value handling in AddressAutocomplete and UserInputArea components by accepting string | undefined types and providing appropriate fallbacks
  • Enhanced address formatting validation to match backend requirements for Australian addresses (State Postcode format)

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/utils/api-config.ts New utility providing centralized API base URL configuration with environment variable fallback support
src/services/places.ts Updated to use centralized getApiBaseUrl() function
src/lib/axiosBaseQuery.ts Migrated to use getApiBaseUrl() and fixed ESLint nullish coalescing preference
src/features/public/publicApiSlice.ts Updated to use centralized API configuration
src/components/ui/AddressAutocomplete.tsx Enhanced to handle undefined values, improved address formatting with state/postcode validation, and added defensive null checks
src/components/GoogleOAuthButton.tsx Migrated to use getApiBaseUrl() function
src/app/onboarding/components/UserInputArea.tsx Updated to accept undefined userInput prop and added appropriate null coalescing operators
src/app/auth/callback/AuthCallbackContent.tsx Added validation for required user fields and fallback values for optional fields
src/app/(public)/blogs/page.tsx Updated to use centralized API configuration
src/app/(public)/blogs/components/BlogList.tsx Updated to use centralized API configuration
src/app/(public)/blogs/[id]/page.tsx Updated to use centralized API configuration
package.json Added explicit port 3000 to dev script

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +119 to +120
if (value !== undefined && value !== inputValue) {
setInputValue(value ?? '');
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition value !== inputValue will be true on every render when value is undefined and inputValue is '' (empty string), causing unnecessary state updates. Consider using a more precise check like value !== undefined && value !== inputValue or checking if both are empty/undefined before updating.

Suggested change
if (value !== undefined && value !== inputValue) {
setInputValue(value ?? '');
const normalizedValue = value ?? '';
if (normalizedValue !== inputValue) {
setInputValue(normalizedValue);

Copilot uses AI. Check for mistakes.
Comment on lines +52 to 70
// Validate parsed user data
if (!parsedUser._id || !parsedUser.email) {
// eslint-disable-next-line no-console
console.error('[AuthCallback] Invalid user data:', parsedUser);
router.replace('/login?error=oauth_invalid_data');
return;
}

dispatch(
setCredentials({
csrfToken,
user: {
_id: parsedUser._id,
email: parsedUser.email,
firstName: parsedUser.firstName,
lastName: parsedUser.lastName,
role: parsedUser.role,
status: parsedUser.status,
email: parsedUser.email ?? '',
firstName: parsedUser.firstName ?? '',
lastName: parsedUser.lastName ?? '',
role: parsedUser.role ?? 'user',
status: parsedUser.status ?? 'active',
},
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validation check only verifies that _id and email exist, but then provides fallback values for other fields. However, if email is an empty string (falsy but not null/undefined), it will pass validation but be overridden to an empty string anyway. The validation should either require all critical fields or only validate fields that truly cannot have fallback values.

Copilot uses AI. Check for mistakes.
onClick={() => onTextSubmit(userInput)}
disabled={disabled || userInput.trim() === ''}
onClick={() => onTextSubmit(userInput ?? '')}
disabled={disabled || !userInput || userInput.trim() === ''}
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition disabled || !userInput || userInput.trim() === '' is redundant. If !userInput is true (meaning userInput is undefined, null, or empty string), then userInput.trim() === '' will either throw an error (for undefined/null) or be redundant (for empty string). The check should be simplified to disabled || !userInput?.trim() which safely handles all cases.

Copilot uses AI. Check for mistakes.
onClick={() => onTextSubmit(userInput)}
disabled={disabled || userInput.trim() === ''}
onClick={() => onTextSubmit(userInput ?? '')}
disabled={disabled || !userInput || userInput.trim() === ''}
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition disabled || !userInput || userInput.trim() === '' is redundant. If !userInput is true (meaning userInput is undefined, null, or empty string), then userInput.trim() === '' will either throw an error (for undefined/null) or be redundant (for empty string). The check should be simplified to disabled || !userInput?.trim() which safely handles all cases.

Copilot uses AI. Check for mistakes.
Comment on lines +186 to +188
// Ensure postcode is 4 digits
const postcode = components.postalCode.replace(/\D/g, '').substring(0, 4);
if (postcode.length === 4) {
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The postcode validation uses .substring(0, 4) to ensure exactly 4 digits, but only adds the postcode if the length is 4. This means postcodes like "200" (3 digits after removing non-digits) would be silently dropped. Consider whether this is the intended behavior or if validation should fail more explicitly for invalid postcodes.

Suggested change
// Ensure postcode is 4 digits
const postcode = components.postalCode.replace(/\D/g, '').substring(0, 4);
if (postcode.length === 4) {
// Ensure postcode is at most 4 digits
const postcode = components.postalCode.replace(/\D/g, '').substring(0, 4);
if (postcode.length > 0) {

Copilot uses AI. Check for mistakes.
Comment on lines +179 to +183
// Ensure state is uppercase and 2-3 characters
const state = components.administrativeAreaLevel1
.toUpperCase()
.substring(0, 3);
statePostcode.push(state);
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The state abbreviation is truncated to 3 characters using .substring(0, 3), but Australian state codes should be 2-3 characters maximum. However, the comment says "2-3 characters" but the code allows any input to be truncated to 3 chars. If the input is a full state name like "New South Wales", this would result in "NEW" instead of "NSW". Consider validating that the state is already an abbreviation or mapping full names to abbreviations.

Copilot uses AI. Check for mistakes.
if (value !== undefined && value !== inputValue) {
setInputValue(value ?? '');
}
}, [value, inputValue]);
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The useEffect dependency array includes inputValue which creates an infinite loop. When the effect runs and value !== inputValue, it calls setInputValue(value ?? ''), which updates inputValue. This change to inputValue triggers the effect again because inputValue is in the dependency array, creating a loop. Remove inputValue from the dependency array to fix this.

Suggested change
}, [value, inputValue]);
}, [value]);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants