Skip to content

Survey details re-design#172

Open
ihsankahveci wants to merge 3 commits intokc-pit-2026-testfrom
survey-details
Open

Survey details re-design#172
ihsankahveci wants to merge 3 commits intokc-pit-2026-testfrom
survey-details

Conversation

@ihsankahveci
Copy link
Copy Markdown
Collaborator

📄 Description

I updated the Survey Details page.

  1. In the Survey Info, I updated with relevant information, LocationName, SurveyCode, etc/
  2. Survey responses appear in the middle and only show things related to Gift Cards and consent.
  3. QR Codes appear at the bottom for a better visual experience.
  4. The Edit Survey button is renamed to Edit Gift Card Info, and
  5. The pages in the "edit" mode are updated to include Gift Card pages.

✅ Checklist

  • Tests added/updated where needed
  • Docs added/updated if applicable
  • I have linked the issue this PR closes (if any)

🔗 Related Issues

Resolves #<issue-number>

💡 Type of change

Type Checked?
🐞 Bug fix [ ]
✨ New feature [ ]
📝 Documentation [ ]
♻️ Refactor [X]
🛠️ Build/CI [ ]
Other (explain) [ ]

🧪 How to test

Please go the Survey Dashboard, click on Survey Details and play around.

📝 Notes to reviewers

…component to enhance data handling and display
@ihsankahveci ihsankahveci requested a review from Copilot January 26, 2026 07:56
@ihsankahveci ihsankahveci changed the base branch from main to kc-pit-2026-test January 26, 2026 07:57
Copy link
Copy Markdown
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 redesigns the Survey Details page with a focus on improving the user experience and updating terminology from "referral code" to "coupon code" throughout the application. The changes reorganize the Survey Details page layout, add location filtering to the dashboard, update the survey form with new questions and conditional logic, and update deployment configurations.

Changes:

  • Redesigned Survey Details page to prioritize gift card information and improve QR code display
  • Updated terminology from "referral code" to "coupon code" across multiple files
  • Added location-based filtering to the Survey Entry Dashboard
  • Enhanced survey form with winter shelter tracking, conditional field visibility based on age, and calculated values
  • Updated survey-core and survey-react-ui dependencies from 2.3.15 to 2.5.7
  • Modified deployment workflows to target new branch names and Azure slots

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
client/src/pages/SurveyDetails/SurveyDetails.tsx Restructured page to show gift card info first, changed data fetching from single survey to filtering all surveys, updated UI labels
client/src/pages/Survey/utils/survey.json Added winter shelter tracking, calculated values for minor children, conditional visibility for adult-only questions, age range updates, new end page for comments
client/src/pages/Survey/utils/surveyUtils.tsx Updated edit mode to include gift card pages (indices 16-17), updated comments
client/src/pages/SurveyEntryDashboard/SurveyEntryDashboard.tsx Added location filtering capability, reordered table columns (survey code, location, staff name)
client/src/pages/SurveyEntryDashboard/components/FilterDialog.tsx Added location dropdown to filter dialog
client/src/pages/SurveyEntryDashboard/components/SurveyEntryDashboardRow.tsx Reordered columns, moved "View Details" button to end
client/src/pages/SurveyEntryDashboard/utils/SurveyEntryDashboardUtils.tsx Added filterSurveysByLocation function, updated searchable fields
client/src/pages/ApplyReferral/ApplyReferral.tsx Updated all text references from "referral code" to "coupon code"
client/src/pages/QrPage/QrPage.tsx Updated labels and button text to use "coupon code" terminology
client/src/pages/Login/Login.tsx Updated welcome message to "Point-in-Time Count 2026"
client/src/components/Header.tsx Restructured header with centered title, removed "RDS Mobile" branding
client/src/styles/*.css Formatting improvements (indentation, whitespace), added qr-buttons class, updated header styling
client/package.json Updated survey-core and survey-react-ui to version 2.5.7
server/src/database/survey/survey.controller.ts Updated comment from "referral code" to "coupon code"
server/src/routes/*.ts Updated error messages to use "coupon code" terminology
server/src/middleware/auth.ts Updated error messages to say "Administration" instead of "admin"
server/src/scripts/generateSeeds.ts Updated comments to use "coupon code" terminology
server/src/scripts/locations.yaml New file with 26 survey location definitions for King County
.github/workflows/*.yml Updated deployment workflows to target kc-pit-2026 branches and new Azure app slots

Comment on lines 18 to +26
if (isEditMode) {
// Edit mode only uses first 3 pages: volunteer-pre-screen, consent, survey-validation
surveyJson.title = 'Homelessness Experience Survey (Edit Mode)';
surveyJson.pages = surveyJson.pages.slice(0, 3);
// surveyJson.pages = surveyJson.pages.slice(0, 4);
surveyJson.pages = [
...surveyJson.pages.slice(0, 4),
surveyJson.pages[16],
surveyJson.pages[17]
].filter(page => page !== undefined);
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

Hardcoded page indices (16 and 17) are fragile and will break if pages are reordered in survey.json. The comment says "Edit mode only uses first 3 pages" but the code now includes 6 pages (0-3, plus 16-17). Consider using page names instead of indices for better maintainability, or update the comment to accurately reflect the new behavior.

Copilot uses AI. Check for mistakes.
Comment on lines 153 to 155
{/* Coupon Code Information */}
<div className="referral-info">
<h3>Referral Information</h3>
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

Inconsistent terminology: The comment says "Coupon Code Information" but the actual heading in the UI is "Referral Information" and uses terms like "Referred By Code" and "Generated Referral Codes". For consistency with the terminology change from "referral" to "coupon" throughout this PR, consider updating this section to use "Coupon" terminology (e.g., "Coupon Information", "Received From Coupon Code", "Generated Coupon Codes").

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +24
data: surveys,
isLoading: loading
} = surveyService.useSurveysWithUsersAndLocations() || {};
const survey = surveys?.find(s => s._id === id);
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

This change fetches ALL surveys and then filters by ID, instead of fetching a single survey. This is inefficient and will cause performance issues as the number of surveys grows. The original useSurveyWithUser hook fetched only the specific survey needed. Consider keeping the original approach or creating a more efficient method to fetch a single survey with location data.

Suggested change
data: surveys,
isLoading: loading
} = surveyService.useSurveysWithUsersAndLocations() || {};
const survey = surveys?.find(s => s._id === id);
data: survey,
isLoading: loading
} = surveyService.useSurveyWithUser(id ?? '');

Copilot uses AI. Check for mistakes.
ihsankahveci and others added 2 commits January 26, 2026 00:07
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Updated fetchSurveyWithUser to include location data
- Modified useSurveyWithUser to fetch user and location in parallel
- Changed SurveyDetails to use useSurveyWithUser instead of useSurveysWithUsersAndLocations
- Now fetches only the specific survey by ID, not all surveys
- Added locationName to SurveyWithUser type

This addresses the review comment about inefficient data fetching in PR #172.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
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

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

Comment on lines +381 to +386
),
survey.locationObjectId
? fetchAndDeserialize<LocationDocument>(
`/api/locations/${survey.locationObjectId}`
)
: Promise.resolve(null)
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The parallel fetch of user and location doesn't handle potential errors gracefully. If either fetchAndDeserialize call fails (e.g., user or location not found), the entire Promise.all will reject, causing the whole function to fail even if the survey itself was retrieved successfully. Consider adding error handling within the Promise.all to catch individual fetch failures and return null for that specific field while still returning the survey data with "Unknown" values for failed fetches.

Suggested change
),
survey.locationObjectId
? fetchAndDeserialize<LocationDocument>(
`/api/locations/${survey.locationObjectId}`
)
: Promise.resolve(null)
).catch(() => null),
survey.locationObjectId
? fetchAndDeserialize<LocationDocument>(
`/api/locations/${survey.locationObjectId}`
).catch(() => null)
: Promise.resolve<LocationDocument | null>(null)

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +26
surveyJson.pages = [
...surveyJson.pages.slice(0, 4),
surveyJson.pages[16],
surveyJson.pages[17]
].filter(page => page !== undefined);
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The code uses hardcoded indices 16 and 17 to access specific survey pages without validating that these indices exist in the array. While the filter removes undefined values, if the survey.json structure changes and these pages are moved or removed, this code will silently exclude them without any error or warning. Consider adding validation to ensure these pages exist, or better yet, select pages by their name property rather than hardcoded indices (e.g., surveyJson.pages.filter(page => ['volunteer-pre-screen', 'age_check', 'consent', 'survey-validation', 'giftCards', 'giftCards2'].includes(page.name))).

Copilot uses AI. Check for mistakes.
.join('\n\n')}
</pre>
</div>
{/* Edit Pre-screen Questions Button */}
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The comment on line 134 is outdated. It says "Edit Pre-screen Questions Button" but the button text has been changed to "Edit Gift Card Information" and its purpose has been updated to edit gift card related pages. The comment should be updated to reflect this: "Edit Gift Card Information Button"

Suggested change
{/* Edit Pre-screen Questions Button */}
{/* Edit Gift Card Information Button */}

Copilot uses AI. Check for mistakes.
// Edit mode only uses first 3 pages: volunteer-pre-screen, consent, survey-validation
surveyJson.title = 'Homelessness Experience Survey (Edit Mode)';
surveyJson.pages = surveyJson.pages.slice(0, 3);
// surveyJson.pages = surveyJson.pages.slice(0, 4);
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

There is commented-out code on line 21 that should be removed. Commented code in production codebase can cause confusion about intent and makes the code harder to maintain. If this line is no longer needed, it should be deleted entirely.

Suggested change
// surveyJson.pages = surveyJson.pages.slice(0, 4);

Copilot uses AI. Check for mistakes.
@@ -18,7 +18,13 @@ export const initializeSurvey = (
if (isEditMode) {
// Edit mode only uses first 3 pages: volunteer-pre-screen, consent, survey-validation
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The comment on line 19 is outdated and incorrect. It states "Edit mode only uses first 3 pages: volunteer-pre-screen, consent, survey-validation" but the code now includes pages 0-3 (4 pages total) plus pages 16 and 17 (giftCards and giftCards2). The comment should be updated to accurately reflect the new behavior: "Edit mode includes volunteer-pre-screen, age_check, consent, survey-validation, giftCards, and giftCards2 pages"

Suggested change
// Edit mode only uses first 3 pages: volunteer-pre-screen, consent, survey-validation
// Edit mode includes volunteer-pre-screen, age_check, consent, survey-validation, giftCards, and giftCards2 pages

Copilot uses AI. Check for mistakes.
throw new Error(
'Survey not found or you do not have permission to view it'
);
return null;
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The error handling has been changed in a way that loses important information. Previously, the API would throw an error with a specific message ("Survey not found or you do not have permission to view it") that would be captured in the error variable from SWR. Now, the function returns null without distinguishing between a 404 (not found) and a 403 (no permission). This makes debugging more difficult and provides less helpful feedback. Consider checking the response status in fetchSurveyWithUser and throwing appropriate errors for different failure cases, or at minimum preserve the error information that SWR naturally provides.

Suggested change
return null;
throw new Error('Survey not found or you do not have permission to view it');

Copilot uses AI. Check for mistakes.
.map(field => {
const answer = survey.responses[field];
const label = labelMap[field] || field;
return `${label}: ${answer ?? 'N/A'}`;
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The field 'email_phone_consent' is a checkbox type that returns an array of values (either ['email'], ['phone'], ['email', 'phone'], or an empty array/null). The current display code treats it as a simple value and will display it as comma-separated array items or "[object Object]" rather than in a user-friendly format. Consider adding special handling to display this as "Email, Phone", "Email", "Phone", or "None" based on the array contents.

Suggested change
return `${label}: ${answer ?? 'N/A'}`;
let formattedAnswer: string;
if (field === 'email_phone_consent') {
const value = answer as unknown;
if (
!value ||
(Array.isArray(value) && value.length === 0)
) {
formattedAnswer = 'None';
} else if (Array.isArray(value)) {
const parts: string[] = [];
if (value.includes('email')) {
parts.push('Email');
}
if (value.includes('phone')) {
parts.push('Phone');
}
formattedAnswer = parts.join(', ') || 'None';
} else {
formattedAnswer = String(value);
}
} else {
formattedAnswer = String(answer ?? 'N/A');
}
return `${label}: ${formattedAnswer}`;

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