7818 lines
353 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Build Power. Not Rent It. Own your digital infrastructure.">
<meta name="author" content="Bunker Operations">
<link rel="canonical" href="https://bnkserve.org/v2/frontend/pages/public/response-wall-page/">
<link rel="prev" href="../campaign-page/">
<link rel="next" href="../map-page/">
<link rel="icon" href="../../../../../assets/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
<title>Response Wall - Changemaker Lite</title>
<link rel="stylesheet" href="../../../../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../../../../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
<link rel="stylesheet" href="../../../../../stylesheets/extra.css">
<link rel="stylesheet" href="../../../../../stylesheets/home.css">
<link rel="stylesheet" href="../../../../../assets/css/video-player.css">
<script>__md_scope=new URL("../../../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<meta property="og:type" content="website" />
<meta property="og:title" content="Response Wall - Changemaker Lite" />
<meta property="og:description" content="Build Power. Not Rent It. Own your digital infrastructure." />
<meta property="og:image" content="https://bnkserve.org/assets/images/social/v2/frontend/pages/public/response-wall-page.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content="https://bnkserve.org/v2/frontend/pages/public/response-wall-page/" />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:title" content="Response Wall - Changemaker Lite" />
<meta property="twitter:description" content="Build Power. Not Rent It. Own your digital infrastructure." />
<meta property="twitter:image" content="https://bnkserve.org/assets/images/social/v2/frontend/pages/public/response-wall-page.png" />
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#response-wall-page" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../../../../.." title="Changemaker Lite" class="md-header__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
<img src="../../../../../assets/logo.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Changemaker Lite
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Response Wall
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
changemaker.lite
</div>
</a>
</div>
</nav>
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../../../../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../../../../" class="md-tabs__link">
V2 Documentation
</a>
</li>
<li class="md-tabs__item">
<a href="../../../../../phil/" class="md-tabs__link">
Philosophy
</a>
</li>
<li class="md-tabs__item">
<a href="../../../../../v1/" class="md-tabs__link">
V1 Documentation (Legacy)
</a>
</li>
<li class="md-tabs__item">
<a href="../../../../../blog/" class="md-tabs__link">
Blog
</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../../../../.." title="Changemaker Lite" class="md-nav__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
<img src="../../../../../assets/logo.png" alt="logo">
</a>
Changemaker Lite
</label>
<div class="md-nav__source">
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
changemaker.lite
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" checked>
<div class="md-nav__link md-nav__container">
<a href="../../../../" class="md-nav__link ">
<span class="md-ellipsis">
V2 Documentation
</span>
</a>
<label class="md-nav__link " for="__nav_2" id="__nav_2_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
V2 Documentation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_2" >
<div class="md-nav__link md-nav__container">
<a href="../../../../getting-started/" class="md-nav__link ">
<span class="md-ellipsis">
Getting Started
</span>
</a>
<label class="md-nav__link " for="__nav_2_2" id="__nav_2_2_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Getting Started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../getting-started/quick-start/" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_3" >
<div class="md-nav__link md-nav__container">
<a href="../../../../architecture/" class="md-nav__link ">
<span class="md-ellipsis">
Architecture
</span>
</a>
<label class="md-nav__link " for="__nav_2_3" id="__nav_2_3_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_3">
<span class="md-nav__icon md-icon"></span>
Architecture
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../architecture/dual-api/" class="md-nav__link">
<span class="md-ellipsis">
Dual API System
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../architecture/authentication/" class="md-nav__link">
<span class="md-ellipsis">
Authentication & Security
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_4" >
<div class="md-nav__link md-nav__container">
<a href="../../../../backend/" class="md-nav__link ">
<span class="md-ellipsis">
Backend
</span>
</a>
<label class="md-nav__link " for="__nav_2_4" id="__nav_2_4_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_4">
<span class="md-nav__icon md-icon"></span>
Backend
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../backend/modules/" class="md-nav__link">
<span class="md-ellipsis">
Modules
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../backend/services/" class="md-nav__link">
<span class="md-ellipsis">
Services
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../backend/middleware/" class="md-nav__link">
<span class="md-ellipsis">
Middleware
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../backend/utilities/" class="md-nav__link">
<span class="md-ellipsis">
Utilities
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_5" checked>
<div class="md-nav__link md-nav__container">
<a href="../../../" class="md-nav__link ">
<span class="md-ellipsis">
Frontend
</span>
</a>
<label class="md-nav__link " for="__nav_2_5" id="__nav_2_5_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_5_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2_5">
<span class="md-nav__icon md-icon"></span>
Frontend
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../components/" class="md-nav__link">
<span class="md-ellipsis">
Components
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../layouts/" class="md-nav__link">
<span class="md-ellipsis">
Layouts
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_5_4" checked>
<div class="md-nav__link md-nav__container">
<a href="../../" class="md-nav__link ">
<span class="md-ellipsis">
Pages
</span>
</a>
<label class="md-nav__link " for="__nav_2_5_4" id="__nav_2_5_4_label" tabindex="0">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_5_4_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2_5_4">
<span class="md-nav__icon md-icon"></span>
Pages
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../admin/" class="md-nav__link">
<span class="md-ellipsis">
Admin Pages
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_5_4_3" checked>
<div class="md-nav__link md-nav__container">
<a href="../" class="md-nav__link ">
<span class="md-ellipsis">
Public Pages
</span>
</a>
<label class="md-nav__link " for="__nav_2_5_4_3" id="__nav_2_5_4_3_label" tabindex="0">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="4" aria-labelledby="__nav_2_5_4_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2_5_4_3">
<span class="md-nav__icon md-icon"></span>
Public Pages
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../campaigns-list-page/" class="md-nav__link">
<span class="md-ellipsis">
Campaigns List
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../campaign-page/" class="md-nav__link">
<span class="md-ellipsis">
Campaign Detail
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Response Wall
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Response Wall
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="On this page">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
On this page
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#features" class="md-nav__link">
<span class="md-ellipsis">
Features
</span>
</a>
<nav class="md-nav" aria-label="Features">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-campaign-context-header" class="md-nav__link">
<span class="md-ellipsis">
1. Campaign Context Header
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-statistics-dashboard" class="md-nav__link">
<span class="md-ellipsis">
2. Statistics Dashboard
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-filtering-and-sorting-controls" class="md-nav__link">
<span class="md-ellipsis">
3. Filtering and Sorting Controls
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-response-cards" class="md-nav__link">
<span class="md-ellipsis">
4. Response Cards
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#5-submit-response-modal" class="md-nav__link">
<span class="md-ellipsis">
5. Submit Response Modal
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#6-pagination" class="md-nav__link">
<span class="md-ellipsis">
6. Pagination
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#user-workflow" class="md-nav__link">
<span class="md-ellipsis">
User Workflow
</span>
</a>
<nav class="md-nav" aria-label="User Workflow">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#browsing-responses" class="md-nav__link">
<span class="md-ellipsis">
Browsing Responses
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#filtering-and-sorting" class="md-nav__link">
<span class="md-ellipsis">
Filtering and Sorting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#submitting-a-response" class="md-nav__link">
<span class="md-ellipsis">
Submitting a Response
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#upvoting" class="md-nav__link">
<span class="md-ellipsis">
Upvoting
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#component-structure" class="md-nav__link">
<span class="md-ellipsis">
Component Structure
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#state-management" class="md-nav__link">
<span class="md-ellipsis">
State Management
</span>
</a>
<nav class="md-nav" aria-label="State Management">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#component-state" class="md-nav__link">
<span class="md-ellipsis">
Component State
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#derived-state" class="md-nav__link">
<span class="md-ellipsis">
Derived State
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#state-flow" class="md-nav__link">
<span class="md-ellipsis">
State Flow
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#api-integration" class="md-nav__link">
<span class="md-ellipsis">
API Integration
</span>
</a>
<nav class="md-nav" aria-label="API Integration">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#endpoints-used" class="md-nav__link">
<span class="md-ellipsis">
Endpoints Used
</span>
</a>
<nav class="md-nav" aria-label="Endpoints Used">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-get-campaign-basic-info" class="md-nav__link">
<span class="md-ellipsis">
1. Get Campaign (Basic Info)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-get-response-statistics" class="md-nav__link">
<span class="md-ellipsis">
2. Get Response Statistics
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-list-responses" class="md-nav__link">
<span class="md-ellipsis">
3. List Responses
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-submit-response" class="md-nav__link">
<span class="md-ellipsis">
4. Submit Response
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#5-upvote-response" class="md-nav__link">
<span class="md-ellipsis">
5. Upvote Response
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#request-examples" class="md-nav__link">
<span class="md-ellipsis">
Request Examples
</span>
</a>
<nav class="md-nav" aria-label="Request Examples">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#fetch-responses" class="md-nav__link">
<span class="md-ellipsis">
Fetch Responses
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#submit-response" class="md-nav__link">
<span class="md-ellipsis">
Submit Response
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#upvote-response" class="md-nav__link">
<span class="md-ellipsis">
Upvote Response
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#code-examples" class="md-nav__link">
<span class="md-ellipsis">
Code Examples
</span>
</a>
<nav class="md-nav" aria-label="Code Examples">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#statistics-cards" class="md-nav__link">
<span class="md-ellipsis">
Statistics Cards
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sort-and-filter-controls" class="md-nav__link">
<span class="md-ellipsis">
Sort and Filter Controls
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#response-cards" class="md-nav__link">
<span class="md-ellipsis">
Response Cards
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#submit-response-modal" class="md-nav__link">
<span class="md-ellipsis">
Submit Response Modal
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#pagination" class="md-nav__link">
<span class="md-ellipsis">
Pagination
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#performance-considerations" class="md-nav__link">
<span class="md-ellipsis">
Performance Considerations
</span>
</a>
<nav class="md-nav" aria-label="Performance Considerations">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-parallel-data-fetching" class="md-nav__link">
<span class="md-ellipsis">
1. Parallel Data Fetching
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-optimistic-upvote-updates" class="md-nav__link">
<span class="md-ellipsis">
2. Optimistic Upvote Updates
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-server-side-filtering" class="md-nav__link">
<span class="md-ellipsis">
3. Server-Side Filtering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-pagination" class="md-nav__link">
<span class="md-ellipsis">
4. Pagination
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#5-scroll-to-top-on-page-change" class="md-nav__link">
<span class="md-ellipsis">
5. Scroll to Top on Page Change
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#responsive-design" class="md-nav__link">
<span class="md-ellipsis">
Responsive Design
</span>
</a>
<nav class="md-nav" aria-label="Responsive Design">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#breakpoint-behavior" class="md-nav__link">
<span class="md-ellipsis">
Breakpoint Behavior
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mobile-adaptations" class="md-nav__link">
<span class="md-ellipsis">
Mobile Adaptations
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#accessibility" class="md-nav__link">
<span class="md-ellipsis">
Accessibility
</span>
</a>
<nav class="md-nav" aria-label="Accessibility">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#keyboard-navigation" class="md-nav__link">
<span class="md-ellipsis">
Keyboard Navigation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#aria-labels" class="md-nav__link">
<span class="md-ellipsis">
ARIA Labels
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#screen-reader-support" class="md-nav__link">
<span class="md-ellipsis">
Screen Reader Support
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#troubleshooting" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
<nav class="md-nav" aria-label="Troubleshooting">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#issue-upvotes-not-persisting" class="md-nav__link">
<span class="md-ellipsis">
Issue: Upvotes Not Persisting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#issue-statistics-not-updating-after-submission" class="md-nav__link">
<span class="md-ellipsis">
Issue: Statistics Not Updating After Submission
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#issue-verified-only-filter-shows-no-results" class="md-nav__link">
<span class="md-ellipsis">
Issue: "Verified Only" Filter Shows No Results
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#issue-pagination-showing-wrong-total" class="md-nav__link">
<span class="md-ellipsis">
Issue: Pagination Showing Wrong Total
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#related-documentation" class="md-nav__link">
<span class="md-ellipsis">
Related Documentation
</span>
</a>
<nav class="md-nav" aria-label="Related Documentation">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#public-pages" class="md-nav__link">
<span class="md-ellipsis">
Public Pages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-pages" class="md-nav__link">
<span class="md-ellipsis">
Admin Pages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#components" class="md-nav__link">
<span class="md-ellipsis">
Components
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#api-documentation" class="md-nav__link">
<span class="md-ellipsis">
API Documentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#architecture" class="md-nav__link">
<span class="md-ellipsis">
Architecture
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../map-page/" class="md-nav__link">
<span class="md-ellipsis">
Map
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../shifts-page/" class="md-nav__link">
<span class="md-ellipsis">
Shifts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../landing-page/" class="md-nav__link">
<span class="md-ellipsis">
Landing Page
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../media-gallery-page/" class="md-nav__link">
<span class="md-ellipsis">
Media Gallery
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../media-viewer-page/" class="md-nav__link">
<span class="md-ellipsis">
Media Viewer
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../volunteer/" class="md-nav__link">
<span class="md-ellipsis">
Volunteer Pages
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_6" >
<div class="md-nav__link md-nav__container">
<a href="../../../../database/" class="md-nav__link ">
<span class="md-ellipsis">
Database
</span>
</a>
<label class="md-nav__link " for="__nav_2_6" id="__nav_2_6_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_6">
<span class="md-nav__icon md-icon"></span>
Database
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../database/schema/" class="md-nav__link">
<span class="md-ellipsis">
Schema Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../database/migrations/" class="md-nav__link">
<span class="md-ellipsis">
Migrations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../database/seeding/" class="md-nav__link">
<span class="md-ellipsis">
Seeding
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../database/indexes/" class="md-nav__link">
<span class="md-ellipsis">
Indexes
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../database/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_7" >
<div class="md-nav__link md-nav__container">
<a href="../../../../features/" class="md-nav__link ">
<span class="md-ellipsis">
Features
</span>
</a>
<label class="md-nav__link " for="__nav_2_7" id="__nav_2_7_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_7">
<span class="md-nav__icon md-icon"></span>
Features
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../features/influence/" class="md-nav__link">
<span class="md-ellipsis">
Influence
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../features/map/" class="md-nav__link">
<span class="md-ellipsis">
Map
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../features/landing-pages/" class="md-nav__link">
<span class="md-ellipsis">
Landing Pages
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../features/email-templates/" class="md-nav__link">
<span class="md-ellipsis">
Email Templates
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../features/media/" class="md-nav__link">
<span class="md-ellipsis">
Media
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../features/newsletter/" class="md-nav__link">
<span class="md-ellipsis">
Newsletter
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../features/observability/" class="md-nav__link">
<span class="md-ellipsis">
Observability
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../features/tunnel/" class="md-nav__link">
<span class="md-ellipsis">
Tunnel
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_8" >
<div class="md-nav__link md-nav__container">
<a href="../../../../deployment/" class="md-nav__link ">
<span class="md-ellipsis">
Deployment
</span>
</a>
<label class="md-nav__link " for="__nav_2_8" id="__nav_2_8_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_8">
<span class="md-nav__icon md-icon"></span>
Deployment
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../deployment/docker-compose/" class="md-nav__link">
<span class="md-ellipsis">
Docker Compose
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../deployment/environment-variables/" class="md-nav__link">
<span class="md-ellipsis">
Environment Variables
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../deployment/nginx/" class="md-nav__link">
<span class="md-ellipsis">
Nginx Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../deployment/ssl-tls/" class="md-nav__link">
<span class="md-ellipsis">
SSL/TLS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../deployment/tunneling/" class="md-nav__link">
<span class="md-ellipsis">
Tunneling
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../deployment/monitoring-stack/" class="md-nav__link">
<span class="md-ellipsis">
Monitoring Stack
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../deployment/healthchecks/" class="md-nav__link">
<span class="md-ellipsis">
Health Checks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../deployment/scaling/" class="md-nav__link">
<span class="md-ellipsis">
Scaling
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../deployment/backup-restore/" class="md-nav__link">
<span class="md-ellipsis">
Backup & Restore
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_9" >
<div class="md-nav__link md-nav__container">
<a href="../../../../development/" class="md-nav__link ">
<span class="md-ellipsis">
Development
</span>
</a>
<label class="md-nav__link " for="__nav_2_9" id="__nav_2_9_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_9">
<span class="md-nav__icon md-icon"></span>
Development
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../development/local-setup/" class="md-nav__link">
<span class="md-ellipsis">
Local Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../development/docker-workflow/" class="md-nav__link">
<span class="md-ellipsis">
Docker Workflow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../development/git-workflow/" class="md-nav__link">
<span class="md-ellipsis">
Git Workflow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../development/npm-commands/" class="md-nav__link">
<span class="md-ellipsis">
NPM Commands
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../development/migrations/" class="md-nav__link">
<span class="md-ellipsis">
Migrations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../development/typescript/" class="md-nav__link">
<span class="md-ellipsis">
TypeScript
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../development/testing/" class="md-nav__link">
<span class="md-ellipsis">
Testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../development/debugging/" class="md-nav__link">
<span class="md-ellipsis">
Debugging
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../development/code-style/" class="md-nav__link">
<span class="md-ellipsis">
Code Style
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_10" >
<div class="md-nav__link md-nav__container">
<a href="../../../../api-reference/" class="md-nav__link ">
<span class="md-ellipsis">
API Reference
</span>
</a>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_10_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_10">
<span class="md-nav__icon md-icon"></span>
API Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_11" >
<div class="md-nav__link md-nav__container">
<a href="../../../../user-guides/" class="md-nav__link ">
<span class="md-ellipsis">
User Guides
</span>
</a>
<label class="md-nav__link " for="__nav_2_11" id="__nav_2_11_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_11_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_11">
<span class="md-nav__icon md-icon"></span>
User Guides
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../user-guides/admin-guide/" class="md-nav__link">
<span class="md-ellipsis">
Admin Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../user-guides/campaign-manager-guide/" class="md-nav__link">
<span class="md-ellipsis">
Campaign Manager Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../user-guides/map-organizer-guide/" class="md-nav__link">
<span class="md-ellipsis">
Map Organizer Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../user-guides/content-editor-guide/" class="md-nav__link">
<span class="md-ellipsis">
Content Editor Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../user-guides/volunteer-guide/" class="md-nav__link">
<span class="md-ellipsis">
Volunteer Guide
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_12" >
<div class="md-nav__link md-nav__container">
<a href="../../../../troubleshooting/" class="md-nav__link ">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
<label class="md-nav__link " for="__nav_2_12" id="__nav_2_12_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_12_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_12">
<span class="md-nav__icon md-icon"></span>
Troubleshooting
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../troubleshooting/faq/" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../troubleshooting/common-errors/" class="md-nav__link">
<span class="md-ellipsis">
Common Errors
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../troubleshooting/auth-issues/" class="md-nav__link">
<span class="md-ellipsis">
Auth Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../troubleshooting/database-issues/" class="md-nav__link">
<span class="md-ellipsis">
Database Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../troubleshooting/docker-issues/" class="md-nav__link">
<span class="md-ellipsis">
Docker Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../troubleshooting/email-issues/" class="md-nav__link">
<span class="md-ellipsis">
Email Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../troubleshooting/geocoding-issues/" class="md-nav__link">
<span class="md-ellipsis">
Geocoding Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../troubleshooting/monitoring-issues/" class="md-nav__link">
<span class="md-ellipsis">
Monitoring Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../troubleshooting/performance-optimization/" class="md-nav__link">
<span class="md-ellipsis">
Performance Optimization
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_13" >
<div class="md-nav__link md-nav__container">
<a href="../../../../migration/" class="md-nav__link ">
<span class="md-ellipsis">
Migration
</span>
</a>
<label class="md-nav__link " for="__nav_2_13" id="__nav_2_13_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_13">
<span class="md-nav__icon md-icon"></span>
Migration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../migration/feature-parity/" class="md-nav__link">
<span class="md-ellipsis">
Feature Parity
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../migration/breaking-changes/" class="md-nav__link">
<span class="md-ellipsis">
Breaking Changes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../migration/api-changes/" class="md-nav__link">
<span class="md-ellipsis">
API Changes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../migration/data-migration/" class="md-nav__link">
<span class="md-ellipsis">
Data Migration
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_14" >
<div class="md-nav__link md-nav__container">
<a href="../../../../contributing/" class="md-nav__link ">
<span class="md-ellipsis">
Contributing
</span>
</a>
<label class="md-nav__link " for="__nav_2_14" id="__nav_2_14_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_14_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_14">
<span class="md-nav__icon md-icon"></span>
Contributing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../../../contributing/development-setup/" class="md-nav__link">
<span class="md-ellipsis">
Development Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../contributing/code-of-conduct/" class="md-nav__link">
<span class="md-ellipsis">
Code of Conduct
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../contributing/pull-requests/" class="md-nav__link">
<span class="md-ellipsis">
Pull Requests
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../../contributing/roadmap/" class="md-nav__link">
<span class="md-ellipsis">
Roadmap
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../../phil/" class="md-nav__link">
<span class="md-ellipsis">
Philosophy
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../../v1/" class="md-nav__link">
<span class="md-ellipsis">
V1 Documentation (Legacy)
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../../../blog/" class="md-nav__link">
<span class="md-ellipsis">
Blog
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="On this page">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
On this page
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#features" class="md-nav__link">
<span class="md-ellipsis">
Features
</span>
</a>
<nav class="md-nav" aria-label="Features">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-campaign-context-header" class="md-nav__link">
<span class="md-ellipsis">
1. Campaign Context Header
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-statistics-dashboard" class="md-nav__link">
<span class="md-ellipsis">
2. Statistics Dashboard
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-filtering-and-sorting-controls" class="md-nav__link">
<span class="md-ellipsis">
3. Filtering and Sorting Controls
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-response-cards" class="md-nav__link">
<span class="md-ellipsis">
4. Response Cards
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#5-submit-response-modal" class="md-nav__link">
<span class="md-ellipsis">
5. Submit Response Modal
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#6-pagination" class="md-nav__link">
<span class="md-ellipsis">
6. Pagination
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#user-workflow" class="md-nav__link">
<span class="md-ellipsis">
User Workflow
</span>
</a>
<nav class="md-nav" aria-label="User Workflow">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#browsing-responses" class="md-nav__link">
<span class="md-ellipsis">
Browsing Responses
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#filtering-and-sorting" class="md-nav__link">
<span class="md-ellipsis">
Filtering and Sorting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#submitting-a-response" class="md-nav__link">
<span class="md-ellipsis">
Submitting a Response
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#upvoting" class="md-nav__link">
<span class="md-ellipsis">
Upvoting
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#component-structure" class="md-nav__link">
<span class="md-ellipsis">
Component Structure
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#state-management" class="md-nav__link">
<span class="md-ellipsis">
State Management
</span>
</a>
<nav class="md-nav" aria-label="State Management">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#component-state" class="md-nav__link">
<span class="md-ellipsis">
Component State
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#derived-state" class="md-nav__link">
<span class="md-ellipsis">
Derived State
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#state-flow" class="md-nav__link">
<span class="md-ellipsis">
State Flow
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#api-integration" class="md-nav__link">
<span class="md-ellipsis">
API Integration
</span>
</a>
<nav class="md-nav" aria-label="API Integration">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#endpoints-used" class="md-nav__link">
<span class="md-ellipsis">
Endpoints Used
</span>
</a>
<nav class="md-nav" aria-label="Endpoints Used">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-get-campaign-basic-info" class="md-nav__link">
<span class="md-ellipsis">
1. Get Campaign (Basic Info)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-get-response-statistics" class="md-nav__link">
<span class="md-ellipsis">
2. Get Response Statistics
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-list-responses" class="md-nav__link">
<span class="md-ellipsis">
3. List Responses
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-submit-response" class="md-nav__link">
<span class="md-ellipsis">
4. Submit Response
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#5-upvote-response" class="md-nav__link">
<span class="md-ellipsis">
5. Upvote Response
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#request-examples" class="md-nav__link">
<span class="md-ellipsis">
Request Examples
</span>
</a>
<nav class="md-nav" aria-label="Request Examples">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#fetch-responses" class="md-nav__link">
<span class="md-ellipsis">
Fetch Responses
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#submit-response" class="md-nav__link">
<span class="md-ellipsis">
Submit Response
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#upvote-response" class="md-nav__link">
<span class="md-ellipsis">
Upvote Response
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#code-examples" class="md-nav__link">
<span class="md-ellipsis">
Code Examples
</span>
</a>
<nav class="md-nav" aria-label="Code Examples">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#statistics-cards" class="md-nav__link">
<span class="md-ellipsis">
Statistics Cards
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sort-and-filter-controls" class="md-nav__link">
<span class="md-ellipsis">
Sort and Filter Controls
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#response-cards" class="md-nav__link">
<span class="md-ellipsis">
Response Cards
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#submit-response-modal" class="md-nav__link">
<span class="md-ellipsis">
Submit Response Modal
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#pagination" class="md-nav__link">
<span class="md-ellipsis">
Pagination
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#performance-considerations" class="md-nav__link">
<span class="md-ellipsis">
Performance Considerations
</span>
</a>
<nav class="md-nav" aria-label="Performance Considerations">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-parallel-data-fetching" class="md-nav__link">
<span class="md-ellipsis">
1. Parallel Data Fetching
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-optimistic-upvote-updates" class="md-nav__link">
<span class="md-ellipsis">
2. Optimistic Upvote Updates
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-server-side-filtering" class="md-nav__link">
<span class="md-ellipsis">
3. Server-Side Filtering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-pagination" class="md-nav__link">
<span class="md-ellipsis">
4. Pagination
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#5-scroll-to-top-on-page-change" class="md-nav__link">
<span class="md-ellipsis">
5. Scroll to Top on Page Change
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#responsive-design" class="md-nav__link">
<span class="md-ellipsis">
Responsive Design
</span>
</a>
<nav class="md-nav" aria-label="Responsive Design">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#breakpoint-behavior" class="md-nav__link">
<span class="md-ellipsis">
Breakpoint Behavior
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mobile-adaptations" class="md-nav__link">
<span class="md-ellipsis">
Mobile Adaptations
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#accessibility" class="md-nav__link">
<span class="md-ellipsis">
Accessibility
</span>
</a>
<nav class="md-nav" aria-label="Accessibility">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#keyboard-navigation" class="md-nav__link">
<span class="md-ellipsis">
Keyboard Navigation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#aria-labels" class="md-nav__link">
<span class="md-ellipsis">
ARIA Labels
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#screen-reader-support" class="md-nav__link">
<span class="md-ellipsis">
Screen Reader Support
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#troubleshooting" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
<nav class="md-nav" aria-label="Troubleshooting">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#issue-upvotes-not-persisting" class="md-nav__link">
<span class="md-ellipsis">
Issue: Upvotes Not Persisting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#issue-statistics-not-updating-after-submission" class="md-nav__link">
<span class="md-ellipsis">
Issue: Statistics Not Updating After Submission
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#issue-verified-only-filter-shows-no-results" class="md-nav__link">
<span class="md-ellipsis">
Issue: "Verified Only" Filter Shows No Results
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#issue-pagination-showing-wrong-total" class="md-nav__link">
<span class="md-ellipsis">
Issue: Pagination Showing Wrong Total
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#related-documentation" class="md-nav__link">
<span class="md-ellipsis">
Related Documentation
</span>
</a>
<nav class="md-nav" aria-label="Related Documentation">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#public-pages" class="md-nav__link">
<span class="md-ellipsis">
Public Pages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-pages" class="md-nav__link">
<span class="md-ellipsis">
Admin Pages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#components" class="md-nav__link">
<span class="md-ellipsis">
Components
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#api-documentation" class="md-nav__link">
<span class="md-ellipsis">
API Documentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#architecture" class="md-nav__link">
<span class="md-ellipsis">
Architecture
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<nav class="md-path" aria-label="Navigation" >
<ol class="md-path__list">
<li class="md-path__item">
<a href="../../../../.." class="md-path__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-path__item">
<a href="../../../../" class="md-path__link">
<span class="md-ellipsis">
V2 Documentation
</span>
</a>
</li>
<li class="md-path__item">
<a href="../../../" class="md-path__link">
<span class="md-ellipsis">
Frontend
</span>
</a>
</li>
<li class="md-path__item">
<a href="../../" class="md-path__link">
<span class="md-ellipsis">
Pages
</span>
</a>
</li>
<li class="md-path__item">
<a href="../" class="md-path__link">
<span class="md-ellipsis">
Public Pages
</span>
</a>
</li>
</ol>
</nav>
<article class="md-content__inner md-typeset">
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/v2/frontend/pages/public/response-wall-page.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/v2/frontend/pages/public/response-wall-page.md" title="View source of this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg>
</a>
<h1 id="response-wall-page">Response Wall Page<a class="headerlink" href="#response-wall-page" title="Permanent link">&para;</a></h1>
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h2>
<p><strong>File Path:</strong> <code>admin/src/pages/public/ResponseWallPage.tsx</code> (492 lines)</p>
<p><strong>Route:</strong> <code>/responses/:campaignId</code></p>
<p><strong>Role Requirements:</strong> Public access (no authentication required)</p>
<p><strong>Purpose:</strong> Community-driven response wall displaying user-submitted campaign feedback, verification status, government official replies, and social engagement through upvoting. Serves as social proof and community building tool for advocacy campaigns.</p>
<p><strong>Key Features:</strong></p>
<ul>
<li>Campaign-specific response display with back navigation</li>
<li>Real-time statistics cards (Total Responses, Verified, Total Upvotes)</li>
<li>Multi-criteria sorting (Recent, Most Upvoted, Verified Only)</li>
<li>Government level filtering (Federal, Provincial, Municipal, All)</li>
<li>Response cards with upvote functionality</li>
<li>User comments and representative details</li>
<li>Verification badges for confirmed responses</li>
<li>Response submission modal with long-form input</li>
<li>Pagination for large response sets</li>
<li>Dark blue/teal theme consistency</li>
<li>Mobile-responsive grid layout</li>
</ul>
<p><strong>Layout:</strong> Uses <code>PublicLayout</code> component with dark theme</p>
<hr />
<h2 id="features">Features<a class="headerlink" href="#features" title="Permanent link">&para;</a></h2>
<h3 id="1-campaign-context-header">1. Campaign Context Header<a class="headerlink" href="#1-campaign-context-header" title="Permanent link">&para;</a></h3>
<p>Navigation and campaign identification:</p>
<ul>
<li><strong>Back Link</strong>: Returns to campaign detail page (<code>/campaigns/:campaignId</code>)</li>
<li><strong>Campaign Title</strong>: Displays as page heading</li>
<li><strong>Breadcrumb</strong>: "Response Wall" subtitle</li>
<li><strong>Icon</strong>: Comment icon for visual context</li>
</ul>
<h3 id="2-statistics-dashboard">2. Statistics Dashboard<a class="headerlink" href="#2-statistics-dashboard" title="Permanent link">&para;</a></h3>
<p>Three key metrics displayed as cards:</p>
<ul>
<li><strong>Total Responses</strong>: Count of all submissions (verified + unverified)</li>
<li><strong>Verified Responses</strong>: Count of email-verified submissions</li>
<li><strong>Total Upvotes</strong>: Aggregate upvote count across all responses</li>
</ul>
<p><strong>Card Design:</strong>
- Large numeric display (32px font)
- Icon with brand color
- Label text below number
- Responsive grid (xs=1, sm=3 columns)
- Hover effect for visual feedback</p>
<h3 id="3-filtering-and-sorting-controls">3. Filtering and Sorting Controls<a class="headerlink" href="#3-filtering-and-sorting-controls" title="Permanent link">&para;</a></h3>
<p>User controls for response discovery:</p>
<p><strong>Sort Dropdown:</strong>
- <strong>Recent</strong>: Newest first (default, <code>createdAt DESC</code>)
- <strong>Most Upvoted</strong>: Highest upvote count first (<code>upvoteCount DESC</code>)
- <strong>Verified Only</strong>: Only email-verified responses</p>
<p><strong>Government Level Filter:</strong>
- <strong>All Levels</strong>: No filtering (default)
- <strong>Federal</strong>: Federal government responses only
- <strong>Provincial</strong>: Provincial/territorial responses only
- <strong>Municipal</strong>: Municipal/local responses only</p>
<p><strong>Layout:</strong>
- Row with two columns
- Sort on left, filter on right
- Full-width selects on mobile
- Margin below for spacing</p>
<h3 id="4-response-cards">4. Response Cards<a class="headerlink" href="#4-response-cards" title="Permanent link">&para;</a></h3>
<p>Individual response display with rich metadata:</p>
<p><strong>Card Header:</strong>
- User name (bold, 16px)
- Timestamp (relative: "2 hours ago")
- Verification badge (if <code>isVerified=true</code>)</p>
<p><strong>Card Content:</strong>
- User comment (full text, auto-wrapping)
- Quoted text if available (italicized, gray background)
- Representative details:
- Name (bold)
- District/riding
- Government level tag (colored by level)</p>
<p><strong>Card Footer:</strong>
- Upvote button with count
- Heart icon (filled if user upvoted)
- Click toggles upvote status
- Optimistic UI update</p>
<p><strong>Styling:</strong>
- Dark background (<code>colorBgContainer</code>)
- Rounded corners (8px)
- Hover elevation shadow
- Dividers between sections</p>
<h3 id="5-submit-response-modal">5. Submit Response Modal<a class="headerlink" href="#5-submit-response-modal" title="Permanent link">&para;</a></h3>
<p>Long-form response submission interface:</p>
<p><strong>Form Fields:</strong>
- <strong>Your Name</strong> (required, text input)
- <strong>Your Email</strong> (required, email validation)
- <strong>Your Postal Code</strong> (optional, for rep lookup context)
- <strong>Representative</strong> (read-only, from parent campaign context)
- <strong>Your Comment</strong> (required, TextArea, 5 rows min)
- <strong>Email Me a Copy</strong> (checkbox, default checked)</p>
<p><strong>Validation:</strong>
- Required field indicators
- Email format validation
- Min/max length checks (comment: 10-5000 chars)
- Disabled submit until valid</p>
<p><strong>Submission Flow:</strong>
1. User clicks "Submit Your Response" button
2. Modal opens with empty form
3. User fills fields
4. Clicks "Submit Response" button
5. API creates response (status: <code>unverified</code>)
6. Verification email sent if checkbox checked
7. Success modal displays
8. Form resets
9. Responses list refreshes</p>
<h3 id="6-pagination">6. Pagination<a class="headerlink" href="#6-pagination" title="Permanent link">&para;</a></h3>
<p>Ant Design Pagination component:</p>
<ul>
<li><strong>Page Size</strong>: 20 responses per page</li>
<li><strong>Total Count</strong>: Fetched from API</li>
<li><strong>Page Change</strong>: Triggers new API request</li>
<li><strong>Positioning</strong>: Centered below response grid</li>
<li><strong>Styling</strong>: Inherits dark theme from PublicLayout</li>
</ul>
<hr />
<h2 id="user-workflow">User Workflow<a class="headerlink" href="#user-workflow" title="Permanent link">&para;</a></h2>
<h3 id="browsing-responses">Browsing Responses<a class="headerlink" href="#browsing-responses" title="Permanent link">&para;</a></h3>
<ol>
<li>User arrives from campaign page via "View Response Wall" link</li>
<li>Page loads responses (default: recent, all levels)</li>
<li>User views statistics cards showing community engagement</li>
<li>User scrolls through response cards</li>
<li>User reads comments and representative details</li>
<li>User upvotes responses they agree with</li>
<li>User clicks pagination to view more responses</li>
</ol>
<h3 id="filtering-and-sorting">Filtering and Sorting<a class="headerlink" href="#filtering-and-sorting" title="Permanent link">&para;</a></h3>
<ol>
<li>User selects "Most Upvoted" from sort dropdown</li>
<li>API re-fetches responses with new sort order</li>
<li>Grid updates with reordered responses</li>
<li>User selects "Federal" from government level filter</li>
<li>API re-fetches with government level filter</li>
<li>Grid shows only federal responses</li>
<li>User resets filters to "All Levels" to see everything</li>
</ol>
<h3 id="submitting-a-response">Submitting a Response<a class="headerlink" href="#submitting-a-response" title="Permanent link">&para;</a></h3>
<ol>
<li>User clicks "Submit Your Response" button</li>
<li>Modal opens with blank form</li>
<li>User enters name: "Jane Doe"</li>
<li>User enters email: "jane@example.com"</li>
<li>User enters postal code: "K1A 0B1" (optional)</li>
<li>User writes comment: "I strongly support this bill because..."</li>
<li>User checks "Email me a copy" checkbox</li>
<li>User clicks "Submit Response"</li>
<li>API creates response with <code>isVerified=false</code></li>
<li>Backend sends verification email to jane@example.com</li>
<li>Success modal displays: "Response submitted! Check your email to verify."</li>
<li>User clicks "OK"</li>
<li>Modal closes</li>
<li>Responses grid refreshes (may not show new response if "Verified Only" filter active)</li>
</ol>
<h3 id="upvoting">Upvoting<a class="headerlink" href="#upvoting" title="Permanent link">&para;</a></h3>
<ol>
<li>User sees response they agree with</li>
<li>User clicks heart icon button</li>
<li>Optimistic update: upvote count increments, heart fills with color</li>
<li>API request to <code>/api/public/responses/:id/upvote</code></li>
<li>If API succeeds: update persists</li>
<li>If API fails: revert to previous state, show error message</li>
<li>User can click again to remove upvote (toggle behavior)</li>
</ol>
<hr />
<h2 id="component-structure">Component Structure<a class="headerlink" href="#component-structure" title="Permanent link">&para;</a></h2>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="k">import</span><span class="w"> </span><span class="nx">React</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">useState</span><span class="p">,</span><span class="w"> </span><span class="nx">useEffect</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;react&#39;</span><span class="p">;</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">useParams</span><span class="p">,</span><span class="w"> </span><span class="nx">Link</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;react-router-dom&#39;</span><span class="p">;</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="w"> </span><span class="nx">Card</span><span class="p">,</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a><span class="w"> </span><span class="nx">Row</span><span class="p">,</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a><span class="w"> </span><span class="nx">Col</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a><span class="w"> </span><span class="nx">Typography</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a><span class="w"> </span><span class="nx">Button</span><span class="p">,</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a><span class="w"> </span><span class="nx">Select</span><span class="p">,</span>
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a><span class="w"> </span><span class="nx">Statistic</span><span class="p">,</span>
</span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a><span class="w"> </span><span class="nx">Modal</span><span class="p">,</span>
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a><span class="w"> </span><span class="nx">Form</span><span class="p">,</span>
</span><span id="__span-0-13"><a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a><span class="w"> </span><span class="nx">Input</span><span class="p">,</span>
</span><span id="__span-0-14"><a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a><span class="w"> </span><span class="nx">Checkbox</span><span class="p">,</span>
</span><span id="__span-0-15"><a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a><span class="w"> </span><span class="nx">Pagination</span><span class="p">,</span>
</span><span id="__span-0-16"><a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a><span class="w"> </span><span class="nx">Tag</span><span class="p">,</span>
</span><span id="__span-0-17"><a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a><span class="w"> </span><span class="nx">Space</span><span class="p">,</span>
</span><span id="__span-0-18"><a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a><span class="w"> </span><span class="nx">message</span><span class="p">,</span>
</span><span id="__span-0-19"><a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a><span class="w"> </span><span class="nx">Grid</span>
</span><span id="__span-0-20"><a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;antd&#39;</span><span class="p">;</span>
</span><span id="__span-0-21"><a id="__codelineno-0-21" name="__codelineno-0-21" href="#__codelineno-0-21"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-0-22"><a id="__codelineno-0-22" name="__codelineno-0-22" href="#__codelineno-0-22"></a><span class="w"> </span><span class="nx">ArrowLeftOutlined</span><span class="p">,</span>
</span><span id="__span-0-23"><a id="__codelineno-0-23" name="__codelineno-0-23" href="#__codelineno-0-23"></a><span class="w"> </span><span class="nx">CommentOutlined</span><span class="p">,</span>
</span><span id="__span-0-24"><a id="__codelineno-0-24" name="__codelineno-0-24" href="#__codelineno-0-24"></a><span class="w"> </span><span class="nx">HeartOutlined</span><span class="p">,</span>
</span><span id="__span-0-25"><a id="__codelineno-0-25" name="__codelineno-0-25" href="#__codelineno-0-25"></a><span class="w"> </span><span class="nx">HeartFilled</span><span class="p">,</span>
</span><span id="__span-0-26"><a id="__codelineno-0-26" name="__codelineno-0-26" href="#__codelineno-0-26"></a><span class="w"> </span><span class="nx">CheckCircleOutlined</span><span class="p">,</span>
</span><span id="__span-0-27"><a id="__codelineno-0-27" name="__codelineno-0-27" href="#__codelineno-0-27"></a><span class="w"> </span><span class="nx">TrophyOutlined</span><span class="p">,</span>
</span><span id="__span-0-28"><a id="__codelineno-0-28" name="__codelineno-0-28" href="#__codelineno-0-28"></a><span class="w"> </span><span class="nx">FireOutlined</span>
</span><span id="__span-0-29"><a id="__codelineno-0-29" name="__codelineno-0-29" href="#__codelineno-0-29"></a><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;@ant-design/icons&#39;</span><span class="p">;</span>
</span><span id="__span-0-30"><a id="__codelineno-0-30" name="__codelineno-0-30" href="#__codelineno-0-30"></a><span class="k">import</span><span class="w"> </span><span class="nx">dayjs</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;dayjs&#39;</span><span class="p">;</span>
</span><span id="__span-0-31"><a id="__codelineno-0-31" name="__codelineno-0-31" href="#__codelineno-0-31"></a><span class="k">import</span><span class="w"> </span><span class="nx">relativeTime</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;dayjs/plugin/relativeTime&#39;</span><span class="p">;</span>
</span><span id="__span-0-32"><a id="__codelineno-0-32" name="__codelineno-0-32" href="#__codelineno-0-32"></a><span class="k">import</span><span class="w"> </span><span class="nx">PublicLayout</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;../../components/PublicLayout&#39;</span><span class="p">;</span>
</span><span id="__span-0-33"><a id="__codelineno-0-33" name="__codelineno-0-33" href="#__codelineno-0-33"></a><span class="k">import</span><span class="w"> </span><span class="nx">axios</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">&#39;axios&#39;</span><span class="p">;</span>
</span><span id="__span-0-34"><a id="__codelineno-0-34" name="__codelineno-0-34" href="#__codelineno-0-34"></a>
</span><span id="__span-0-35"><a id="__codelineno-0-35" name="__codelineno-0-35" href="#__codelineno-0-35"></a><span class="nx">dayjs</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">relativeTime</span><span class="p">);</span>
</span><span id="__span-0-36"><a id="__codelineno-0-36" name="__codelineno-0-36" href="#__codelineno-0-36"></a>
</span><span id="__span-0-37"><a id="__codelineno-0-37" name="__codelineno-0-37" href="#__codelineno-0-37"></a><span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">Title</span><span class="p">,</span><span class="w"> </span><span class="nx">Paragraph</span><span class="p">,</span><span class="w"> </span><span class="nx">Text</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Typography</span><span class="p">;</span>
</span><span id="__span-0-38"><a id="__codelineno-0-38" name="__codelineno-0-38" href="#__codelineno-0-38"></a><span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">TextArea</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Input</span><span class="p">;</span>
</span><span id="__span-0-39"><a id="__codelineno-0-39" name="__codelineno-0-39" href="#__codelineno-0-39"></a><span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">Option</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Select</span><span class="p">;</span>
</span><span id="__span-0-40"><a id="__codelineno-0-40" name="__codelineno-0-40" href="#__codelineno-0-40"></a><span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">useBreakpoint</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Grid</span><span class="p">;</span>
</span><span id="__span-0-41"><a id="__codelineno-0-41" name="__codelineno-0-41" href="#__codelineno-0-41"></a>
</span><span id="__span-0-42"><a id="__codelineno-0-42" name="__codelineno-0-42" href="#__codelineno-0-42"></a><span class="kd">interface</span><span class="w"> </span><span class="nx">Response</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-0-43"><a id="__codelineno-0-43" name="__codelineno-0-43" href="#__codelineno-0-43"></a><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-44"><a id="__codelineno-0-44" name="__codelineno-0-44" href="#__codelineno-0-44"></a><span class="w"> </span><span class="nx">userName</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-45"><a id="__codelineno-0-45" name="__codelineno-0-45" href="#__codelineno-0-45"></a><span class="w"> </span><span class="nx">userEmail</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-46"><a id="__codelineno-0-46" name="__codelineno-0-46" href="#__codelineno-0-46"></a><span class="w"> </span><span class="nx">postalCode</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
</span><span id="__span-0-47"><a id="__codelineno-0-47" name="__codelineno-0-47" href="#__codelineno-0-47"></a><span class="w"> </span><span class="nx">comment</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-48"><a id="__codelineno-0-48" name="__codelineno-0-48" href="#__codelineno-0-48"></a><span class="w"> </span><span class="nx">quotedText</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
</span><span id="__span-0-49"><a id="__codelineno-0-49" name="__codelineno-0-49" href="#__codelineno-0-49"></a><span class="w"> </span><span class="nx">isVerified</span><span class="o">:</span><span class="w"> </span><span class="kt">boolean</span><span class="p">;</span>
</span><span id="__span-0-50"><a id="__codelineno-0-50" name="__codelineno-0-50" href="#__codelineno-0-50"></a><span class="w"> </span><span class="nx">upvoteCount</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
</span><span id="__span-0-51"><a id="__codelineno-0-51" name="__codelineno-0-51" href="#__codelineno-0-51"></a><span class="w"> </span><span class="nx">representativeName</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-52"><a id="__codelineno-0-52" name="__codelineno-0-52" href="#__codelineno-0-52"></a><span class="w"> </span><span class="nx">representativeDistrict</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-53"><a id="__codelineno-0-53" name="__codelineno-0-53" href="#__codelineno-0-53"></a><span class="w"> </span><span class="nx">governmentLevel</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-54"><a id="__codelineno-0-54" name="__codelineno-0-54" href="#__codelineno-0-54"></a><span class="w"> </span><span class="nx">createdAt</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-55"><a id="__codelineno-0-55" name="__codelineno-0-55" href="#__codelineno-0-55"></a><span class="w"> </span><span class="nx">hasUpvoted?</span><span class="o">:</span><span class="w"> </span><span class="kt">boolean</span><span class="p">;</span><span class="w"> </span><span class="c1">// Client-side tracking</span>
</span><span id="__span-0-56"><a id="__codelineno-0-56" name="__codelineno-0-56" href="#__codelineno-0-56"></a><span class="p">}</span>
</span><span id="__span-0-57"><a id="__codelineno-0-57" name="__codelineno-0-57" href="#__codelineno-0-57"></a>
</span><span id="__span-0-58"><a id="__codelineno-0-58" name="__codelineno-0-58" href="#__codelineno-0-58"></a><span class="kd">interface</span><span class="w"> </span><span class="nx">Campaign</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-0-59"><a id="__codelineno-0-59" name="__codelineno-0-59" href="#__codelineno-0-59"></a><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-60"><a id="__codelineno-0-60" name="__codelineno-0-60" href="#__codelineno-0-60"></a><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
</span><span id="__span-0-61"><a id="__codelineno-0-61" name="__codelineno-0-61" href="#__codelineno-0-61"></a><span class="p">}</span>
</span><span id="__span-0-62"><a id="__codelineno-0-62" name="__codelineno-0-62" href="#__codelineno-0-62"></a>
</span><span id="__span-0-63"><a id="__codelineno-0-63" name="__codelineno-0-63" href="#__codelineno-0-63"></a><span class="kd">interface</span><span class="w"> </span><span class="nx">Stats</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-0-64"><a id="__codelineno-0-64" name="__codelineno-0-64" href="#__codelineno-0-64"></a><span class="w"> </span><span class="nx">totalResponses</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
</span><span id="__span-0-65"><a id="__codelineno-0-65" name="__codelineno-0-65" href="#__codelineno-0-65"></a><span class="w"> </span><span class="nx">verifiedResponses</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
</span><span id="__span-0-66"><a id="__codelineno-0-66" name="__codelineno-0-66" href="#__codelineno-0-66"></a><span class="w"> </span><span class="nx">totalUpvotes</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
</span><span id="__span-0-67"><a id="__codelineno-0-67" name="__codelineno-0-67" href="#__codelineno-0-67"></a><span class="p">}</span>
</span><span id="__span-0-68"><a id="__codelineno-0-68" name="__codelineno-0-68" href="#__codelineno-0-68"></a>
</span><span id="__span-0-69"><a id="__codelineno-0-69" name="__codelineno-0-69" href="#__codelineno-0-69"></a><span class="kd">const</span><span class="w"> </span><span class="nx">ResponseWallPage</span><span class="o">:</span><span class="w"> </span><span class="kt">React.FC</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-0-70"><a id="__codelineno-0-70" name="__codelineno-0-70" href="#__codelineno-0-70"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">campaignId</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useParams</span><span class="o">&lt;</span><span class="p">{</span><span class="w"> </span><span class="nx">campaignId</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="p">}</span><span class="o">&gt;</span><span class="p">();</span>
</span><span id="__span-0-71"><a id="__codelineno-0-71" name="__codelineno-0-71" href="#__codelineno-0-71"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">responses</span><span class="p">,</span><span class="w"> </span><span class="nx">setResponses</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">Response</span><span class="err">[]</span><span class="p">&gt;([]);</span>
</span><span id="__span-0-72"><a id="__codelineno-0-72" name="__codelineno-0-72" href="#__codelineno-0-72"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">campaign</span><span class="p">,</span><span class="w"> </span><span class="nx">setCampaign</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">Campaign</span><span class="w"> </span><span class="err">|</span><span class="w"> </span><span class="na">null</span><span class="p">&gt;(</span><span class="kc">null</span><span class="p">);</span>
</span><span id="__span-0-73"><a id="__codelineno-0-73" name="__codelineno-0-73" href="#__codelineno-0-73"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">stats</span><span class="p">,</span><span class="w"> </span><span class="nx">setStats</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">Stats</span><span class="p">&gt;({</span><span class="w"> </span><span class="nx">totalResponses</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">,</span><span class="w"> </span><span class="nx">verifiedResponses</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">,</span><span class="w"> </span><span class="nx">totalUpvotes</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="w"> </span><span class="p">});</span>
</span><span id="__span-0-74"><a id="__codelineno-0-74" name="__codelineno-0-74" href="#__codelineno-0-74"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">loading</span><span class="p">,</span><span class="w"> </span><span class="nx">setLoading</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span id="__span-0-75"><a id="__codelineno-0-75" name="__codelineno-0-75" href="#__codelineno-0-75"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">sortBy</span><span class="p">,</span><span class="w"> </span><span class="nx">setSortBy</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">string</span><span class="p">&gt;(</span><span class="s1">&#39;recent&#39;</span><span class="p">);</span>
</span><span id="__span-0-76"><a id="__codelineno-0-76" name="__codelineno-0-76" href="#__codelineno-0-76"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">governmentLevel</span><span class="p">,</span><span class="w"> </span><span class="nx">setGovernmentLevel</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">string</span><span class="p">&gt;(</span><span class="s1">&#39;all&#39;</span><span class="p">);</span>
</span><span id="__span-0-77"><a id="__codelineno-0-77" name="__codelineno-0-77" href="#__codelineno-0-77"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">page</span><span class="p">,</span><span class="w"> </span><span class="nx">setPage</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="mf">1</span><span class="p">);</span>
</span><span id="__span-0-78"><a id="__codelineno-0-78" name="__codelineno-0-78" href="#__codelineno-0-78"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">total</span><span class="p">,</span><span class="w"> </span><span class="nx">setTotal</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="mf">0</span><span class="p">);</span>
</span><span id="__span-0-79"><a id="__codelineno-0-79" name="__codelineno-0-79" href="#__codelineno-0-79"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">submitModalVisible</span><span class="p">,</span><span class="w"> </span><span class="nx">setSubmitModalVisible</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span id="__span-0-80"><a id="__codelineno-0-80" name="__codelineno-0-80" href="#__codelineno-0-80"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">form</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Form</span><span class="p">.</span><span class="nx">useForm</span><span class="p">();</span>
</span><span id="__span-0-81"><a id="__codelineno-0-81" name="__codelineno-0-81" href="#__codelineno-0-81"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">screens</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useBreakpoint</span><span class="p">();</span>
</span><span id="__span-0-82"><a id="__codelineno-0-82" name="__codelineno-0-82" href="#__codelineno-0-82"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">isMobile</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">!</span><span class="nx">screens</span><span class="p">.</span><span class="nx">md</span><span class="p">;</span>
</span><span id="__span-0-83"><a id="__codelineno-0-83" name="__codelineno-0-83" href="#__codelineno-0-83"></a>
</span><span id="__span-0-84"><a id="__codelineno-0-84" name="__codelineno-0-84" href="#__codelineno-0-84"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">pageSize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">20</span><span class="p">;</span>
</span><span id="__span-0-85"><a id="__codelineno-0-85" name="__codelineno-0-85" href="#__codelineno-0-85"></a>
</span><span id="__span-0-86"><a id="__codelineno-0-86" name="__codelineno-0-86" href="#__codelineno-0-86"></a><span class="w"> </span><span class="c1">// Data fetching, handlers, etc.</span>
</span><span id="__span-0-87"><a id="__codelineno-0-87" name="__codelineno-0-87" href="#__codelineno-0-87"></a>
</span><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88" href="#__codelineno-0-88"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span>
</span><span id="__span-0-89"><a id="__codelineno-0-89" name="__codelineno-0-89" href="#__codelineno-0-89"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">PublicLayout</span><span class="p">&gt;</span>
</span><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90" href="#__codelineno-0-90"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Back link and title */</span><span class="p">}</span>
</span><span id="__span-0-91"><a id="__codelineno-0-91" name="__codelineno-0-91" href="#__codelineno-0-91"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Statistics cards */</span><span class="p">}</span>
</span><span id="__span-0-92"><a id="__codelineno-0-92" name="__codelineno-0-92" href="#__codelineno-0-92"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Sort and filter controls */</span><span class="p">}</span>
</span><span id="__span-0-93"><a id="__codelineno-0-93" name="__codelineno-0-93" href="#__codelineno-0-93"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Response cards grid */</span><span class="p">}</span>
</span><span id="__span-0-94"><a id="__codelineno-0-94" name="__codelineno-0-94" href="#__codelineno-0-94"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Pagination */</span><span class="p">}</span>
</span><span id="__span-0-95"><a id="__codelineno-0-95" name="__codelineno-0-95" href="#__codelineno-0-95"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Submit modal */</span><span class="p">}</span>
</span><span id="__span-0-96"><a id="__codelineno-0-96" name="__codelineno-0-96" href="#__codelineno-0-96"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">PublicLayout</span><span class="p">&gt;</span>
</span><span id="__span-0-97"><a id="__codelineno-0-97" name="__codelineno-0-97" href="#__codelineno-0-97"></a><span class="w"> </span><span class="p">);</span>
</span><span id="__span-0-98"><a id="__codelineno-0-98" name="__codelineno-0-98" href="#__codelineno-0-98"></a><span class="p">};</span>
</span><span id="__span-0-99"><a id="__codelineno-0-99" name="__codelineno-0-99" href="#__codelineno-0-99"></a>
</span><span id="__span-0-100"><a id="__codelineno-0-100" name="__codelineno-0-100" href="#__codelineno-0-100"></a><span class="k">export</span><span class="w"> </span><span class="k">default</span><span class="w"> </span><span class="nx">ResponseWallPage</span><span class="p">;</span>
</span></code></pre></div>
<hr />
<h2 id="state-management">State Management<a class="headerlink" href="#state-management" title="Permanent link">&para;</a></h2>
<h3 id="component-state">Component State<a class="headerlink" href="#component-state" title="Permanent link">&para;</a></h3>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="c1">// Response data</span>
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">responses</span><span class="p">,</span><span class="w"> </span><span class="nx">setResponses</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">Response</span><span class="err">[]</span><span class="p">&gt;([]);</span>
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">campaign</span><span class="p">,</span><span class="w"> </span><span class="nx">setCampaign</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">Campaign</span><span class="w"> </span><span class="err">|</span><span class="w"> </span><span class="na">null</span><span class="p">&gt;(</span><span class="kc">null</span><span class="p">);</span>
</span><span id="__span-1-4"><a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">stats</span><span class="p">,</span><span class="w"> </span><span class="nx">setStats</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">Stats</span><span class="p">&gt;({</span>
</span><span id="__span-1-5"><a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a><span class="w"> </span><span class="nx">totalResponses</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">,</span>
</span><span id="__span-1-6"><a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="w"> </span><span class="nx">verifiedResponses</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">,</span>
</span><span id="__span-1-7"><a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="w"> </span><span class="nx">totalUpvotes</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span>
</span><span id="__span-1-8"><a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a><span class="p">});</span>
</span><span id="__span-1-9"><a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">loading</span><span class="p">,</span><span class="w"> </span><span class="nx">setLoading</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span id="__span-1-10"><a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a>
</span><span id="__span-1-11"><a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a><span class="c1">// Filtering and sorting</span>
</span><span id="__span-1-12"><a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">sortBy</span><span class="p">,</span><span class="w"> </span><span class="nx">setSortBy</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">string</span><span class="p">&gt;(</span><span class="s1">&#39;recent&#39;</span><span class="p">);</span><span class="w"> </span><span class="c1">// &#39;recent&#39; | &#39;upvotes&#39; | &#39;verified&#39;</span>
</span><span id="__span-1-13"><a id="__codelineno-1-13" name="__codelineno-1-13" href="#__codelineno-1-13"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">governmentLevel</span><span class="p">,</span><span class="w"> </span><span class="nx">setGovernmentLevel</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">&lt;</span><span class="nt">string</span><span class="p">&gt;(</span><span class="s1">&#39;all&#39;</span><span class="p">);</span><span class="w"> </span><span class="c1">// &#39;all&#39; | &#39;federal&#39; | &#39;provincial&#39; | &#39;municipal&#39;</span>
</span><span id="__span-1-14"><a id="__codelineno-1-14" name="__codelineno-1-14" href="#__codelineno-1-14"></a>
</span><span id="__span-1-15"><a id="__codelineno-1-15" name="__codelineno-1-15" href="#__codelineno-1-15"></a><span class="c1">// Pagination</span>
</span><span id="__span-1-16"><a id="__codelineno-1-16" name="__codelineno-1-16" href="#__codelineno-1-16"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">page</span><span class="p">,</span><span class="w"> </span><span class="nx">setPage</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="mf">1</span><span class="p">);</span>
</span><span id="__span-1-17"><a id="__codelineno-1-17" name="__codelineno-1-17" href="#__codelineno-1-17"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">total</span><span class="p">,</span><span class="w"> </span><span class="nx">setTotal</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="mf">0</span><span class="p">);</span>
</span><span id="__span-1-18"><a id="__codelineno-1-18" name="__codelineno-1-18" href="#__codelineno-1-18"></a><span class="kd">const</span><span class="w"> </span><span class="nx">pageSize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">20</span><span class="p">;</span>
</span><span id="__span-1-19"><a id="__codelineno-1-19" name="__codelineno-1-19" href="#__codelineno-1-19"></a>
</span><span id="__span-1-20"><a id="__codelineno-1-20" name="__codelineno-1-20" href="#__codelineno-1-20"></a><span class="c1">// Modal state</span>
</span><span id="__span-1-21"><a id="__codelineno-1-21" name="__codelineno-1-21" href="#__codelineno-1-21"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">submitModalVisible</span><span class="p">,</span><span class="w"> </span><span class="nx">setSubmitModalVisible</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span id="__span-1-22"><a id="__codelineno-1-22" name="__codelineno-1-22" href="#__codelineno-1-22"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">form</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Form</span><span class="p">.</span><span class="nx">useForm</span><span class="p">();</span>
</span><span id="__span-1-23"><a id="__codelineno-1-23" name="__codelineno-1-23" href="#__codelineno-1-23"></a>
</span><span id="__span-1-24"><a id="__codelineno-1-24" name="__codelineno-1-24" href="#__codelineno-1-24"></a><span class="c1">// Responsive</span>
</span><span id="__span-1-25"><a id="__codelineno-1-25" name="__codelineno-1-25" href="#__codelineno-1-25"></a><span class="kd">const</span><span class="w"> </span><span class="nx">screens</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useBreakpoint</span><span class="p">();</span>
</span><span id="__span-1-26"><a id="__codelineno-1-26" name="__codelineno-1-26" href="#__codelineno-1-26"></a><span class="kd">const</span><span class="w"> </span><span class="nx">isMobile</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">!</span><span class="nx">screens</span><span class="p">.</span><span class="nx">md</span><span class="p">;</span>
</span></code></pre></div>
<h3 id="derived-state">Derived State<a class="headerlink" href="#derived-state" title="Permanent link">&para;</a></h3>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="c1">// No complex derived state - filtering happens server-side</span>
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="c1">// All data transformations done by API</span>
</span></code></pre></div>
<h3 id="state-flow">State Flow<a class="headerlink" href="#state-flow" title="Permanent link">&para;</a></h3>
<ol>
<li><strong>Initial Load</strong>: <code>loading=true</code>, fetch campaign + responses + stats</li>
<li><strong>Data Received</strong>: <code>setCampaign()</code>, <code>setResponses()</code>, <code>setStats()</code>, <code>setTotal()</code>, <code>loading=false</code></li>
<li><strong>Sort Changed</strong>: <code>setSortBy()</code>, <code>setPage(1)</code>, refetch responses</li>
<li><strong>Filter Changed</strong>: <code>setGovernmentLevel()</code>, <code>setPage(1)</code>, refetch responses</li>
<li><strong>Page Changed</strong>: <code>setPage()</code>, refetch responses (keep sort/filter)</li>
<li><strong>Upvote Clicked</strong>: Optimistic update to <code>responses</code> array, API call</li>
<li><strong>Submit Clicked</strong>: <code>setSubmitModalVisible(true)</code>, open form</li>
<li><strong>Response Submitted</strong>: API call, <code>setSubmitModalVisible(false)</code>, refetch responses</li>
</ol>
<hr />
<h2 id="api-integration">API Integration<a class="headerlink" href="#api-integration" title="Permanent link">&para;</a></h2>
<h3 id="endpoints-used">Endpoints Used<a class="headerlink" href="#endpoints-used" title="Permanent link">&para;</a></h3>
<h4 id="1-get-campaign-basic-info">1. Get Campaign (Basic Info)<a class="headerlink" href="#1-get-campaign-basic-info" title="Permanent link">&para;</a></h4>
<div class="language-http highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="err">GET /api/public/campaigns/:campaignId</span>
</span></code></pre></div>
<p><strong>Response:</strong>
<div class="language-json highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="p">{</span>
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="w"> </span><span class="nt">&quot;id&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;cm1abc123&quot;</span><span class="p">,</span>
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="nt">&quot;title&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Support Climate Action Bill&quot;</span>
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="p">}</span>
</span></code></pre></div></p>
<h4 id="2-get-response-statistics">2. Get Response Statistics<a class="headerlink" href="#2-get-response-statistics" title="Permanent link">&para;</a></h4>
<div class="language-http highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="err">GET /api/public/responses/campaigns/:campaignId/stats</span>
</span></code></pre></div>
<p><strong>Response:</strong>
<div class="language-json highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="p">{</span>
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="w"> </span><span class="nt">&quot;totalResponses&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">342</span><span class="p">,</span>
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="nt">&quot;verifiedResponses&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">287</span><span class="p">,</span>
</span><span id="__span-6-4"><a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="w"> </span><span class="nt">&quot;totalUpvotes&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">1829</span>
</span><span id="__span-6-5"><a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a><span class="p">}</span>
</span></code></pre></div></p>
<h4 id="3-list-responses">3. List Responses<a class="headerlink" href="#3-list-responses" title="Permanent link">&para;</a></h4>
<div class="language-http highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="err">GET /api/public/responses/campaigns/:campaignId?page=1&amp;limit=20&amp;sortBy=recent&amp;governmentLevel=all</span>
</span></code></pre></div>
<p><strong>Query Parameters:</strong>
- <code>page</code>: Page number (1-indexed)
- <code>limit</code>: Items per page (default 20, max 100)
- <code>sortBy</code>: <code>recent</code> | <code>upvotes</code> | <code>verified</code>
- <code>governmentLevel</code>: <code>all</code> | <code>federal</code> | <code>provincial</code> | <code>municipal</code></p>
<p><strong>Response:</strong>
<div class="language-json highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="p">{</span>
</span><span id="__span-8-2"><a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="w"> </span><span class="nt">&quot;responses&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
</span><span id="__span-8-3"><a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="p">{</span>
</span><span id="__span-8-4"><a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="w"> </span><span class="nt">&quot;id&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;cm2abc123&quot;</span><span class="p">,</span>
</span><span id="__span-8-5"><a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a><span class="w"> </span><span class="nt">&quot;userName&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Jane Doe&quot;</span><span class="p">,</span>
</span><span id="__span-8-6"><a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a><span class="w"> </span><span class="nt">&quot;userEmail&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;jane@example.com&quot;</span><span class="p">,</span>
</span><span id="__span-8-7"><a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a><span class="w"> </span><span class="nt">&quot;postalCode&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;K1A 0B1&quot;</span><span class="p">,</span>
</span><span id="__span-8-8"><a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a><span class="w"> </span><span class="nt">&quot;comment&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;I strongly support this bill because it addresses critical climate issues...&quot;</span><span class="p">,</span>
</span><span id="__span-8-9"><a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a><span class="w"> </span><span class="nt">&quot;quotedText&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
</span><span id="__span-8-10"><a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a><span class="w"> </span><span class="nt">&quot;isVerified&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
</span><span id="__span-8-11"><a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a><span class="w"> </span><span class="nt">&quot;upvoteCount&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">47</span><span class="p">,</span>
</span><span id="__span-8-12"><a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a><span class="w"> </span><span class="nt">&quot;representativeName&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;John Smith&quot;</span><span class="p">,</span>
</span><span id="__span-8-13"><a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a><span class="w"> </span><span class="nt">&quot;representativeDistrict&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Ottawa Centre&quot;</span><span class="p">,</span>
</span><span id="__span-8-14"><a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a><span class="w"> </span><span class="nt">&quot;governmentLevel&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;federal&quot;</span><span class="p">,</span>
</span><span id="__span-8-15"><a id="__codelineno-8-15" name="__codelineno-8-15" href="#__codelineno-8-15"></a><span class="w"> </span><span class="nt">&quot;createdAt&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;2025-02-10T14:30:00.000Z&quot;</span>
</span><span id="__span-8-16"><a id="__codelineno-8-16" name="__codelineno-8-16" href="#__codelineno-8-16"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-8-17"><a id="__codelineno-8-17" name="__codelineno-8-17" href="#__codelineno-8-17"></a><span class="w"> </span><span class="p">],</span>
</span><span id="__span-8-18"><a id="__codelineno-8-18" name="__codelineno-8-18" href="#__codelineno-8-18"></a><span class="w"> </span><span class="nt">&quot;total&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">342</span><span class="p">,</span>
</span><span id="__span-8-19"><a id="__codelineno-8-19" name="__codelineno-8-19" href="#__codelineno-8-19"></a><span class="w"> </span><span class="nt">&quot;page&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
</span><span id="__span-8-20"><a id="__codelineno-8-20" name="__codelineno-8-20" href="#__codelineno-8-20"></a><span class="w"> </span><span class="nt">&quot;limit&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">20</span>
</span><span id="__span-8-21"><a id="__codelineno-8-21" name="__codelineno-8-21" href="#__codelineno-8-21"></a><span class="p">}</span>
</span></code></pre></div></p>
<h4 id="4-submit-response">4. Submit Response<a class="headerlink" href="#4-submit-response" title="Permanent link">&para;</a></h4>
<div class="language-http highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="err">POST /api/public/responses</span>
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="err">Content-Type: application/json</span>
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a>
</span><span id="__span-9-4"><a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a><span class="err">{</span>
</span><span id="__span-9-5"><a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a><span class="err"> &quot;campaignId&quot;: &quot;cm1abc123&quot;,</span>
</span><span id="__span-9-6"><a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a><span class="err"> &quot;userName&quot;: &quot;Jane Doe&quot;,</span>
</span><span id="__span-9-7"><a id="__codelineno-9-7" name="__codelineno-9-7" href="#__codelineno-9-7"></a><span class="err"> &quot;userEmail&quot;: &quot;jane@example.com&quot;,</span>
</span><span id="__span-9-8"><a id="__codelineno-9-8" name="__codelineno-9-8" href="#__codelineno-9-8"></a><span class="err"> &quot;postalCode&quot;: &quot;K1A 0B1&quot;,</span>
</span><span id="__span-9-9"><a id="__codelineno-9-9" name="__codelineno-9-9" href="#__codelineno-9-9"></a><span class="err"> &quot;comment&quot;: &quot;I strongly support this bill...&quot;,</span>
</span><span id="__span-9-10"><a id="__codelineno-9-10" name="__codelineno-9-10" href="#__codelineno-9-10"></a><span class="err"> &quot;representativeName&quot;: &quot;John Smith&quot;,</span>
</span><span id="__span-9-11"><a id="__codelineno-9-11" name="__codelineno-9-11" href="#__codelineno-9-11"></a><span class="err"> &quot;representativeDistrict&quot;: &quot;Ottawa Centre&quot;,</span>
</span><span id="__span-9-12"><a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a><span class="err"> &quot;governmentLevel&quot;: &quot;federal&quot;,</span>
</span><span id="__span-9-13"><a id="__codelineno-9-13" name="__codelineno-9-13" href="#__codelineno-9-13"></a><span class="err"> &quot;sendCopy&quot;: true</span>
</span><span id="__span-9-14"><a id="__codelineno-9-14" name="__codelineno-9-14" href="#__codelineno-9-14"></a><span class="err">}</span>
</span></code></pre></div>
<p><strong>Response:</strong>
<div class="language-json highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="p">{</span>
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="w"> </span><span class="nt">&quot;success&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="w"> </span><span class="nt">&quot;responseId&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;cm2def456&quot;</span><span class="p">,</span>
</span><span id="__span-10-4"><a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Response submitted successfully. Please check your email to verify.&quot;</span>
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a><span class="p">}</span>
</span></code></pre></div></p>
<h4 id="5-upvote-response">5. Upvote Response<a class="headerlink" href="#5-upvote-response" title="Permanent link">&para;</a></h4>
<div class="language-http highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="err">POST /api/public/responses/:id/upvote</span>
</span></code></pre></div>
<p><strong>Response:</strong>
<div class="language-json highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="p">{</span>
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="nt">&quot;success&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
</span><span id="__span-12-3"><a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a><span class="w"> </span><span class="nt">&quot;upvoteCount&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">48</span><span class="p">,</span>
</span><span id="__span-12-4"><a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a><span class="w"> </span><span class="nt">&quot;action&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;added&quot;</span>
</span><span id="__span-12-5"><a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a><span class="p">}</span>
</span></code></pre></div></p>
<p><strong>Note:</strong> Second request to same endpoint toggles (removes upvote), returns <code>"action": "removed"</code>.</p>
<h3 id="request-examples">Request Examples<a class="headerlink" href="#request-examples" title="Permanent link">&para;</a></h3>
<h4 id="fetch-responses">Fetch Responses<a class="headerlink" href="#fetch-responses" title="Permanent link">&para;</a></h4>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="nx">useEffect</span><span class="p">(()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-13-2"><a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">fetchData</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-13-3"><a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">campaignId</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="p">;</span>
</span><span id="__span-13-4"><a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a>
</span><span id="__span-13-5"><a id="__codelineno-13-5" name="__codelineno-13-5" href="#__codelineno-13-5"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-13-6"><a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a><span class="w"> </span><span class="nx">setLoading</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span id="__span-13-7"><a id="__codelineno-13-7" name="__codelineno-13-7" href="#__codelineno-13-7"></a>
</span><span id="__span-13-8"><a id="__codelineno-13-8" name="__codelineno-13-8" href="#__codelineno-13-8"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">campaignRes</span><span class="p">,</span><span class="w"> </span><span class="nx">statsRes</span><span class="p">,</span><span class="w"> </span><span class="nx">responsesRes</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span>
</span><span id="__span-13-9"><a id="__codelineno-13-9" name="__codelineno-13-9" href="#__codelineno-13-9"></a><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sb">`/api/public/campaigns/</span><span class="si">${</span><span class="nx">campaignId</span><span class="si">}</span><span class="sb">`</span><span class="p">),</span>
</span><span id="__span-13-10"><a id="__codelineno-13-10" name="__codelineno-13-10" href="#__codelineno-13-10"></a><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sb">`/api/public/responses/campaigns/</span><span class="si">${</span><span class="nx">campaignId</span><span class="si">}</span><span class="sb">/stats`</span><span class="p">),</span>
</span><span id="__span-13-11"><a id="__codelineno-13-11" name="__codelineno-13-11" href="#__codelineno-13-11"></a><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sb">`/api/public/responses/campaigns/</span><span class="si">${</span><span class="nx">campaignId</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-13-12"><a id="__codelineno-13-12" name="__codelineno-13-12" href="#__codelineno-13-12"></a><span class="w"> </span><span class="nx">params</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-13-13"><a id="__codelineno-13-13" name="__codelineno-13-13" href="#__codelineno-13-13"></a><span class="w"> </span><span class="nx">page</span><span class="p">,</span>
</span><span id="__span-13-14"><a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a><span class="w"> </span><span class="nx">limit</span><span class="o">:</span><span class="w"> </span><span class="kt">pageSize</span><span class="p">,</span>
</span><span id="__span-13-15"><a id="__codelineno-13-15" name="__codelineno-13-15" href="#__codelineno-13-15"></a><span class="w"> </span><span class="nx">sortBy</span><span class="p">,</span>
</span><span id="__span-13-16"><a id="__codelineno-13-16" name="__codelineno-13-16" href="#__codelineno-13-16"></a><span class="w"> </span><span class="nx">governmentLevel</span><span class="o">:</span><span class="w"> </span><span class="kt">governmentLevel</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">&#39;all&#39;</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nx">undefined</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">governmentLevel</span>
</span><span id="__span-13-17"><a id="__codelineno-13-17" name="__codelineno-13-17" href="#__codelineno-13-17"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-13-18"><a id="__codelineno-13-18" name="__codelineno-13-18" href="#__codelineno-13-18"></a><span class="w"> </span><span class="p">})</span>
</span><span id="__span-13-19"><a id="__codelineno-13-19" name="__codelineno-13-19" href="#__codelineno-13-19"></a><span class="w"> </span><span class="p">]);</span>
</span><span id="__span-13-20"><a id="__codelineno-13-20" name="__codelineno-13-20" href="#__codelineno-13-20"></a>
</span><span id="__span-13-21"><a id="__codelineno-13-21" name="__codelineno-13-21" href="#__codelineno-13-21"></a><span class="w"> </span><span class="nx">setCampaign</span><span class="p">(</span><span class="nx">campaignRes</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
</span><span id="__span-13-22"><a id="__codelineno-13-22" name="__codelineno-13-22" href="#__codelineno-13-22"></a><span class="w"> </span><span class="nx">setStats</span><span class="p">(</span><span class="nx">statsRes</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
</span><span id="__span-13-23"><a id="__codelineno-13-23" name="__codelineno-13-23" href="#__codelineno-13-23"></a><span class="w"> </span><span class="nx">setResponses</span><span class="p">(</span><span class="nx">responsesRes</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">responses</span><span class="p">);</span>
</span><span id="__span-13-24"><a id="__codelineno-13-24" name="__codelineno-13-24" href="#__codelineno-13-24"></a><span class="w"> </span><span class="nx">setTotal</span><span class="p">(</span><span class="nx">responsesRes</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">total</span><span class="p">);</span>
</span><span id="__span-13-25"><a id="__codelineno-13-25" name="__codelineno-13-25" href="#__codelineno-13-25"></a>
</span><span id="__span-13-26"><a id="__codelineno-13-26" name="__codelineno-13-26" href="#__codelineno-13-26"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-13-27"><a id="__codelineno-13-27" name="__codelineno-13-27" href="#__codelineno-13-27"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Failed to fetch data:&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">error</span><span class="p">);</span>
</span><span id="__span-13-28"><a id="__codelineno-13-28" name="__codelineno-13-28" href="#__codelineno-13-28"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Failed to load responses&#39;</span><span class="p">);</span>
</span><span id="__span-13-29"><a id="__codelineno-13-29" name="__codelineno-13-29" href="#__codelineno-13-29"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">finally</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-13-30"><a id="__codelineno-13-30" name="__codelineno-13-30" href="#__codelineno-13-30"></a><span class="w"> </span><span class="nx">setLoading</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span id="__span-13-31"><a id="__codelineno-13-31" name="__codelineno-13-31" href="#__codelineno-13-31"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-13-32"><a id="__codelineno-13-32" name="__codelineno-13-32" href="#__codelineno-13-32"></a><span class="w"> </span><span class="p">};</span>
</span><span id="__span-13-33"><a id="__codelineno-13-33" name="__codelineno-13-33" href="#__codelineno-13-33"></a>
</span><span id="__span-13-34"><a id="__codelineno-13-34" name="__codelineno-13-34" href="#__codelineno-13-34"></a><span class="w"> </span><span class="nx">fetchData</span><span class="p">();</span>
</span><span id="__span-13-35"><a id="__codelineno-13-35" name="__codelineno-13-35" href="#__codelineno-13-35"></a><span class="p">},</span><span class="w"> </span><span class="p">[</span><span class="nx">campaignId</span><span class="p">,</span><span class="w"> </span><span class="nx">page</span><span class="p">,</span><span class="w"> </span><span class="nx">sortBy</span><span class="p">,</span><span class="w"> </span><span class="nx">governmentLevel</span><span class="p">]);</span>
</span></code></pre></div>
<h4 id="submit-response">Submit Response<a class="headerlink" href="#submit-response" title="Permanent link">&para;</a></h4>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">handleSubmit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">(</span><span class="nx">values</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-14-3"><a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/api/public/responses&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-14-4"><a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a><span class="w"> </span><span class="nx">campaignId</span><span class="p">,</span>
</span><span id="__span-14-5"><a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a><span class="w"> </span><span class="nx">userName</span><span class="o">:</span><span class="w"> </span><span class="kt">values.userName</span><span class="p">,</span>
</span><span id="__span-14-6"><a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a><span class="w"> </span><span class="nx">userEmail</span><span class="o">:</span><span class="w"> </span><span class="kt">values.userEmail</span><span class="p">,</span>
</span><span id="__span-14-7"><a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a><span class="w"> </span><span class="nx">postalCode</span><span class="o">:</span><span class="w"> </span><span class="kt">values.postalCode</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span>
</span><span id="__span-14-8"><a id="__codelineno-14-8" name="__codelineno-14-8" href="#__codelineno-14-8"></a><span class="w"> </span><span class="nx">comment</span><span class="o">:</span><span class="w"> </span><span class="kt">values.comment</span><span class="p">,</span>
</span><span id="__span-14-9"><a id="__codelineno-14-9" name="__codelineno-14-9" href="#__codelineno-14-9"></a><span class="w"> </span><span class="nx">representativeName</span><span class="o">:</span><span class="w"> </span><span class="kt">values.representativeName</span><span class="p">,</span>
</span><span id="__span-14-10"><a id="__codelineno-14-10" name="__codelineno-14-10" href="#__codelineno-14-10"></a><span class="w"> </span><span class="nx">representativeDistrict</span><span class="o">:</span><span class="w"> </span><span class="kt">values.representativeDistrict</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s1">&#39;&#39;</span><span class="p">,</span>
</span><span id="__span-14-11"><a id="__codelineno-14-11" name="__codelineno-14-11" href="#__codelineno-14-11"></a><span class="w"> </span><span class="nx">governmentLevel</span><span class="o">:</span><span class="w"> </span><span class="kt">values.governmentLevel</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s1">&#39;federal&#39;</span><span class="p">,</span>
</span><span id="__span-14-12"><a id="__codelineno-14-12" name="__codelineno-14-12" href="#__codelineno-14-12"></a><span class="w"> </span><span class="nx">sendCopy</span><span class="o">:</span><span class="w"> </span><span class="kt">values.sendCopy</span>
</span><span id="__span-14-13"><a id="__codelineno-14-13" name="__codelineno-14-13" href="#__codelineno-14-13"></a><span class="w"> </span><span class="p">});</span>
</span><span id="__span-14-14"><a id="__codelineno-14-14" name="__codelineno-14-14" href="#__codelineno-14-14"></a>
</span><span id="__span-14-15"><a id="__codelineno-14-15" name="__codelineno-14-15" href="#__codelineno-14-15"></a><span class="w"> </span><span class="nx">Modal</span><span class="p">.</span><span class="nx">success</span><span class="p">({</span>
</span><span id="__span-14-16"><a id="__codelineno-14-16" name="__codelineno-14-16" href="#__codelineno-14-16"></a><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Response Submitted!&#39;</span><span class="p">,</span>
</span><span id="__span-14-17"><a id="__codelineno-14-17" name="__codelineno-14-17" href="#__codelineno-14-17"></a><span class="w"> </span><span class="nx">content</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Please check your email to verify your response.&#39;</span><span class="p">,</span>
</span><span id="__span-14-18"><a id="__codelineno-14-18" name="__codelineno-14-18" href="#__codelineno-14-18"></a><span class="w"> </span><span class="p">});</span>
</span><span id="__span-14-19"><a id="__codelineno-14-19" name="__codelineno-14-19" href="#__codelineno-14-19"></a>
</span><span id="__span-14-20"><a id="__codelineno-14-20" name="__codelineno-14-20" href="#__codelineno-14-20"></a><span class="w"> </span><span class="nx">setSubmitModalVisible</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span id="__span-14-21"><a id="__codelineno-14-21" name="__codelineno-14-21" href="#__codelineno-14-21"></a><span class="w"> </span><span class="nx">form</span><span class="p">.</span><span class="nx">resetFields</span><span class="p">();</span>
</span><span id="__span-14-22"><a id="__codelineno-14-22" name="__codelineno-14-22" href="#__codelineno-14-22"></a>
</span><span id="__span-14-23"><a id="__codelineno-14-23" name="__codelineno-14-23" href="#__codelineno-14-23"></a><span class="w"> </span><span class="c1">// Refresh responses list</span>
</span><span id="__span-14-24"><a id="__codelineno-14-24" name="__codelineno-14-24" href="#__codelineno-14-24"></a><span class="w"> </span><span class="nx">setPage</span><span class="p">(</span><span class="mf">1</span><span class="p">);</span>
</span><span id="__span-14-25"><a id="__codelineno-14-25" name="__codelineno-14-25" href="#__codelineno-14-25"></a><span class="w"> </span><span class="c1">// Triggers useEffect refetch</span>
</span><span id="__span-14-26"><a id="__codelineno-14-26" name="__codelineno-14-26" href="#__codelineno-14-26"></a>
</span><span id="__span-14-27"><a id="__codelineno-14-27" name="__codelineno-14-27" href="#__codelineno-14-27"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-14-28"><a id="__codelineno-14-28" name="__codelineno-14-28" href="#__codelineno-14-28"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Submit failed:&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">error</span><span class="p">);</span>
</span><span id="__span-14-29"><a id="__codelineno-14-29" name="__codelineno-14-29" href="#__codelineno-14-29"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="o">?</span><span class="p">.</span><span class="nx">data</span><span class="o">?</span><span class="p">.</span><span class="nx">message</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s1">&#39;Failed to submit response&#39;</span><span class="p">);</span>
</span><span id="__span-14-30"><a id="__codelineno-14-30" name="__codelineno-14-30" href="#__codelineno-14-30"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-14-31"><a id="__codelineno-14-31" name="__codelineno-14-31" href="#__codelineno-14-31"></a><span class="p">};</span>
</span></code></pre></div>
<h4 id="upvote-response">Upvote Response<a class="headerlink" href="#upvote-response" title="Permanent link">&para;</a></h4>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">handleUpvote</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">(</span><span class="nx">responseId</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a><span class="w"> </span><span class="c1">// Optimistic update</span>
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a><span class="w"> </span><span class="nx">setResponses</span><span class="p">(</span><span class="nx">prev</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">prev</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">r</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-4"><a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">id</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">responseId</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-5"><a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">hasUpvoted</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">!</span><span class="nx">r</span><span class="p">.</span><span class="nx">hasUpvoted</span><span class="p">;</span>
</span><span id="__span-15-6"><a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-7"><a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a><span class="w"> </span><span class="p">...</span><span class="nx">r</span><span class="p">,</span>
</span><span id="__span-15-8"><a id="__codelineno-15-8" name="__codelineno-15-8" href="#__codelineno-15-8"></a><span class="w"> </span><span class="nx">hasUpvoted</span><span class="p">,</span>
</span><span id="__span-15-9"><a id="__codelineno-15-9" name="__codelineno-15-9" href="#__codelineno-15-9"></a><span class="w"> </span><span class="nx">upvoteCount</span><span class="o">:</span><span class="w"> </span><span class="kt">r.upvoteCount</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="nx">hasUpvoted</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">-</span><span class="mf">1</span><span class="p">)</span>
</span><span id="__span-15-10"><a id="__codelineno-15-10" name="__codelineno-15-10" href="#__codelineno-15-10"></a><span class="w"> </span><span class="p">};</span>
</span><span id="__span-15-11"><a id="__codelineno-15-11" name="__codelineno-15-11" href="#__codelineno-15-11"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-15-12"><a id="__codelineno-15-12" name="__codelineno-15-12" href="#__codelineno-15-12"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">r</span><span class="p">;</span>
</span><span id="__span-15-13"><a id="__codelineno-15-13" name="__codelineno-15-13" href="#__codelineno-15-13"></a><span class="w"> </span><span class="p">}));</span>
</span><span id="__span-15-14"><a id="__codelineno-15-14" name="__codelineno-15-14" href="#__codelineno-15-14"></a>
</span><span id="__span-15-15"><a id="__codelineno-15-15" name="__codelineno-15-15" href="#__codelineno-15-15"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-16"><a id="__codelineno-15-16" name="__codelineno-15-16" href="#__codelineno-15-16"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">response</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="sb">`/api/public/responses/</span><span class="si">${</span><span class="nx">responseId</span><span class="si">}</span><span class="sb">/upvote`</span><span class="p">);</span>
</span><span id="__span-15-17"><a id="__codelineno-15-17" name="__codelineno-15-17" href="#__codelineno-15-17"></a>
</span><span id="__span-15-18"><a id="__codelineno-15-18" name="__codelineno-15-18" href="#__codelineno-15-18"></a><span class="w"> </span><span class="c1">// Update with server count (in case of race condition)</span>
</span><span id="__span-15-19"><a id="__codelineno-15-19" name="__codelineno-15-19" href="#__codelineno-15-19"></a><span class="w"> </span><span class="nx">setResponses</span><span class="p">(</span><span class="nx">prev</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">prev</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">r</span><span class="w"> </span><span class="p">=&gt;</span>
</span><span id="__span-15-20"><a id="__codelineno-15-20" name="__codelineno-15-20" href="#__codelineno-15-20"></a><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">id</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">responseId</span>
</span><span id="__span-15-21"><a id="__codelineno-15-21" name="__codelineno-15-21" href="#__codelineno-15-21"></a><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">...</span><span class="nx">r</span><span class="p">,</span><span class="w"> </span><span class="nx">upvoteCount</span><span class="o">:</span><span class="w"> </span><span class="kt">response.data.upvoteCount</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-15-22"><a id="__codelineno-15-22" name="__codelineno-15-22" href="#__codelineno-15-22"></a><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="nx">r</span>
</span><span id="__span-15-23"><a id="__codelineno-15-23" name="__codelineno-15-23" href="#__codelineno-15-23"></a><span class="w"> </span><span class="p">));</span>
</span><span id="__span-15-24"><a id="__codelineno-15-24" name="__codelineno-15-24" href="#__codelineno-15-24"></a>
</span><span id="__span-15-25"><a id="__codelineno-15-25" name="__codelineno-15-25" href="#__codelineno-15-25"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-26"><a id="__codelineno-15-26" name="__codelineno-15-26" href="#__codelineno-15-26"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Upvote failed:&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">error</span><span class="p">);</span>
</span><span id="__span-15-27"><a id="__codelineno-15-27" name="__codelineno-15-27" href="#__codelineno-15-27"></a>
</span><span id="__span-15-28"><a id="__codelineno-15-28" name="__codelineno-15-28" href="#__codelineno-15-28"></a><span class="w"> </span><span class="c1">// Revert on error</span>
</span><span id="__span-15-29"><a id="__codelineno-15-29" name="__codelineno-15-29" href="#__codelineno-15-29"></a><span class="w"> </span><span class="nx">setResponses</span><span class="p">(</span><span class="nx">prev</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">prev</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">r</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-30"><a id="__codelineno-15-30" name="__codelineno-15-30" href="#__codelineno-15-30"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">id</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">responseId</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-31"><a id="__codelineno-15-31" name="__codelineno-15-31" href="#__codelineno-15-31"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-15-32"><a id="__codelineno-15-32" name="__codelineno-15-32" href="#__codelineno-15-32"></a><span class="w"> </span><span class="p">...</span><span class="nx">r</span><span class="p">,</span>
</span><span id="__span-15-33"><a id="__codelineno-15-33" name="__codelineno-15-33" href="#__codelineno-15-33"></a><span class="w"> </span><span class="nx">hasUpvoted</span><span class="o">:</span><span class="w"> </span><span class="o">!</span><span class="nx">r</span><span class="p">.</span><span class="nx">hasUpvoted</span><span class="p">,</span>
</span><span id="__span-15-34"><a id="__codelineno-15-34" name="__codelineno-15-34" href="#__codelineno-15-34"></a><span class="w"> </span><span class="nx">upvoteCount</span><span class="o">:</span><span class="w"> </span><span class="kt">r.upvoteCount</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">hasUpvoted</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="o">-</span><span class="nx">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">1</span><span class="p">)</span>
</span><span id="__span-15-35"><a id="__codelineno-15-35" name="__codelineno-15-35" href="#__codelineno-15-35"></a><span class="w"> </span><span class="p">};</span>
</span><span id="__span-15-36"><a id="__codelineno-15-36" name="__codelineno-15-36" href="#__codelineno-15-36"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-15-37"><a id="__codelineno-15-37" name="__codelineno-15-37" href="#__codelineno-15-37"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">r</span><span class="p">;</span>
</span><span id="__span-15-38"><a id="__codelineno-15-38" name="__codelineno-15-38" href="#__codelineno-15-38"></a><span class="w"> </span><span class="p">}));</span>
</span><span id="__span-15-39"><a id="__codelineno-15-39" name="__codelineno-15-39" href="#__codelineno-15-39"></a>
</span><span id="__span-15-40"><a id="__codelineno-15-40" name="__codelineno-15-40" href="#__codelineno-15-40"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Failed to upvote. Please try again.&#39;</span><span class="p">);</span>
</span><span id="__span-15-41"><a id="__codelineno-15-41" name="__codelineno-15-41" href="#__codelineno-15-41"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-15-42"><a id="__codelineno-15-42" name="__codelineno-15-42" href="#__codelineno-15-42"></a><span class="p">};</span>
</span></code></pre></div>
<hr />
<h2 id="code-examples">Code Examples<a class="headerlink" href="#code-examples" title="Permanent link">&para;</a></h2>
<h3 id="statistics-cards">Statistics Cards<a class="headerlink" href="#statistics-cards" title="Permanent link">&para;</a></h3>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="p">&lt;</span><span class="nt">Row</span><span class="w"> </span><span class="na">gutter</span><span class="o">=</span><span class="p">{[</span><span class="mf">16</span><span class="p">,</span><span class="w"> </span><span class="mf">16</span><span class="p">]}</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">32</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Col</span><span class="w"> </span><span class="na">xs</span><span class="o">=</span><span class="p">{</span><span class="mf">24</span><span class="p">}</span><span class="w"> </span><span class="na">sm</span><span class="o">=</span><span class="p">{</span><span class="mf">8</span><span class="p">}&gt;</span>
</span><span id="__span-16-3"><a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Card</span><span class="p">&gt;</span>
</span><span id="__span-16-4"><a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Statistic</span>
</span><span id="__span-16-5"><a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a><span class="w"> </span><span class="na">title</span><span class="o">=</span><span class="s">&quot;Total Responses&quot;</span>
</span><span id="__span-16-6"><a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="p">.</span><span class="nx">totalResponses</span><span class="p">}</span>
</span><span id="__span-16-7"><a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a><span class="w"> </span><span class="na">prefix</span><span class="o">=</span><span class="p">{&lt;</span><span class="nt">CommentOutlined</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#1890ff&#39;</span><span class="w"> </span><span class="p">}}</span><span class="w"> </span><span class="p">/&gt;}</span>
</span><span id="__span-16-8"><a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a><span class="w"> </span><span class="na">valueStyle</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#1890ff&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">32</span><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-16-9"><a id="__codelineno-16-9" name="__codelineno-16-9" href="#__codelineno-16-9"></a><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-16-10"><a id="__codelineno-16-10" name="__codelineno-16-10" href="#__codelineno-16-10"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Card</span><span class="p">&gt;</span>
</span><span id="__span-16-11"><a id="__codelineno-16-11" name="__codelineno-16-11" href="#__codelineno-16-11"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Col</span><span class="p">&gt;</span>
</span><span id="__span-16-12"><a id="__codelineno-16-12" name="__codelineno-16-12" href="#__codelineno-16-12"></a>
</span><span id="__span-16-13"><a id="__codelineno-16-13" name="__codelineno-16-13" href="#__codelineno-16-13"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Col</span><span class="w"> </span><span class="na">xs</span><span class="o">=</span><span class="p">{</span><span class="mf">24</span><span class="p">}</span><span class="w"> </span><span class="na">sm</span><span class="o">=</span><span class="p">{</span><span class="mf">8</span><span class="p">}&gt;</span>
</span><span id="__span-16-14"><a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Card</span><span class="p">&gt;</span>
</span><span id="__span-16-15"><a id="__codelineno-16-15" name="__codelineno-16-15" href="#__codelineno-16-15"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Statistic</span>
</span><span id="__span-16-16"><a id="__codelineno-16-16" name="__codelineno-16-16" href="#__codelineno-16-16"></a><span class="w"> </span><span class="na">title</span><span class="o">=</span><span class="s">&quot;Verified Responses&quot;</span>
</span><span id="__span-16-17"><a id="__codelineno-16-17" name="__codelineno-16-17" href="#__codelineno-16-17"></a><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="p">.</span><span class="nx">verifiedResponses</span><span class="p">}</span>
</span><span id="__span-16-18"><a id="__codelineno-16-18" name="__codelineno-16-18" href="#__codelineno-16-18"></a><span class="w"> </span><span class="na">prefix</span><span class="o">=</span><span class="p">{&lt;</span><span class="nt">CheckCircleOutlined</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#52c41a&#39;</span><span class="w"> </span><span class="p">}}</span><span class="w"> </span><span class="p">/&gt;}</span>
</span><span id="__span-16-19"><a id="__codelineno-16-19" name="__codelineno-16-19" href="#__codelineno-16-19"></a><span class="w"> </span><span class="na">valueStyle</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#52c41a&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">32</span><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-16-20"><a id="__codelineno-16-20" name="__codelineno-16-20" href="#__codelineno-16-20"></a><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-16-21"><a id="__codelineno-16-21" name="__codelineno-16-21" href="#__codelineno-16-21"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Card</span><span class="p">&gt;</span>
</span><span id="__span-16-22"><a id="__codelineno-16-22" name="__codelineno-16-22" href="#__codelineno-16-22"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Col</span><span class="p">&gt;</span>
</span><span id="__span-16-23"><a id="__codelineno-16-23" name="__codelineno-16-23" href="#__codelineno-16-23"></a>
</span><span id="__span-16-24"><a id="__codelineno-16-24" name="__codelineno-16-24" href="#__codelineno-16-24"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Col</span><span class="w"> </span><span class="na">xs</span><span class="o">=</span><span class="p">{</span><span class="mf">24</span><span class="p">}</span><span class="w"> </span><span class="na">sm</span><span class="o">=</span><span class="p">{</span><span class="mf">8</span><span class="p">}&gt;</span>
</span><span id="__span-16-25"><a id="__codelineno-16-25" name="__codelineno-16-25" href="#__codelineno-16-25"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Card</span><span class="p">&gt;</span>
</span><span id="__span-16-26"><a id="__codelineno-16-26" name="__codelineno-16-26" href="#__codelineno-16-26"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Statistic</span>
</span><span id="__span-16-27"><a id="__codelineno-16-27" name="__codelineno-16-27" href="#__codelineno-16-27"></a><span class="w"> </span><span class="na">title</span><span class="o">=</span><span class="s">&quot;Total Upvotes&quot;</span>
</span><span id="__span-16-28"><a id="__codelineno-16-28" name="__codelineno-16-28" href="#__codelineno-16-28"></a><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="p">.</span><span class="nx">totalUpvotes</span><span class="p">}</span>
</span><span id="__span-16-29"><a id="__codelineno-16-29" name="__codelineno-16-29" href="#__codelineno-16-29"></a><span class="w"> </span><span class="na">prefix</span><span class="o">=</span><span class="p">{&lt;</span><span class="nt">HeartFilled</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#eb2f96&#39;</span><span class="w"> </span><span class="p">}}</span><span class="w"> </span><span class="p">/&gt;}</span>
</span><span id="__span-16-30"><a id="__codelineno-16-30" name="__codelineno-16-30" href="#__codelineno-16-30"></a><span class="w"> </span><span class="na">valueStyle</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#eb2f96&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">32</span><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-16-31"><a id="__codelineno-16-31" name="__codelineno-16-31" href="#__codelineno-16-31"></a><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-16-32"><a id="__codelineno-16-32" name="__codelineno-16-32" href="#__codelineno-16-32"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Card</span><span class="p">&gt;</span>
</span><span id="__span-16-33"><a id="__codelineno-16-33" name="__codelineno-16-33" href="#__codelineno-16-33"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Col</span><span class="p">&gt;</span>
</span><span id="__span-16-34"><a id="__codelineno-16-34" name="__codelineno-16-34" href="#__codelineno-16-34"></a><span class="p">&lt;/</span><span class="nt">Row</span><span class="p">&gt;</span>
</span></code></pre></div>
<h3 id="sort-and-filter-controls">Sort and Filter Controls<a class="headerlink" href="#sort-and-filter-controls" title="Permanent link">&para;</a></h3>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="p">&lt;</span><span class="nt">Row</span><span class="w"> </span><span class="na">gutter</span><span class="o">=</span><span class="p">{</span><span class="mf">16</span><span class="p">}</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">24</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Col</span><span class="w"> </span><span class="na">xs</span><span class="o">=</span><span class="p">{</span><span class="mf">24</span><span class="p">}</span><span class="w"> </span><span class="na">sm</span><span class="o">=</span><span class="p">{</span><span class="mf">12</span><span class="p">}&gt;</span>
</span><span id="__span-17-3"><a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Space</span><span class="w"> </span><span class="na">direction</span><span class="o">=</span><span class="s">&quot;vertical&quot;</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">width</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;100%&#39;</span><span class="w"> </span><span class="p">}}</span><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="p">{</span><span class="mf">4</span><span class="p">}&gt;</span>
</span><span id="__span-17-4"><a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Text</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span><span class="p">&gt;</span><span class="nx">Sort</span><span class="w"> </span><span class="nx">by</span><span class="o">:</span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span><span id="__span-17-5"><a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Select</span>
</span><span id="__span-17-6"><a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">sortBy</span><span class="p">}</span>
</span><span id="__span-17-7"><a id="__codelineno-17-7" name="__codelineno-17-7" href="#__codelineno-17-7"></a><span class="w"> </span><span class="na">onChange</span><span class="o">=</span><span class="p">{(</span><span class="nx">value</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-17-8"><a id="__codelineno-17-8" name="__codelineno-17-8" href="#__codelineno-17-8"></a><span class="w"> </span><span class="nx">setSortBy</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
</span><span id="__span-17-9"><a id="__codelineno-17-9" name="__codelineno-17-9" href="#__codelineno-17-9"></a><span class="w"> </span><span class="nx">setPage</span><span class="p">(</span><span class="mf">1</span><span class="p">);</span><span class="w"> </span><span class="c1">// Reset to page 1 when sorting changes</span>
</span><span id="__span-17-10"><a id="__codelineno-17-10" name="__codelineno-17-10" href="#__codelineno-17-10"></a><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-17-11"><a id="__codelineno-17-11" name="__codelineno-17-11" href="#__codelineno-17-11"></a><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">width</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;100%&#39;</span><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-17-12"><a id="__codelineno-17-12" name="__codelineno-17-12" href="#__codelineno-17-12"></a><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span>
</span><span id="__span-17-13"><a id="__codelineno-17-13" name="__codelineno-17-13" href="#__codelineno-17-13"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-17-14"><a id="__codelineno-17-14" name="__codelineno-17-14" href="#__codelineno-17-14"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;recent&quot;</span><span class="p">&gt;</span>
</span><span id="__span-17-15"><a id="__codelineno-17-15" name="__codelineno-17-15" href="#__codelineno-17-15"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">FireOutlined</span><span class="w"> </span><span class="p">/&gt;</span><span class="w"> </span><span class="nx">Recent</span>
</span><span id="__span-17-16"><a id="__codelineno-17-16" name="__codelineno-17-16" href="#__codelineno-17-16"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-17-17"><a id="__codelineno-17-17" name="__codelineno-17-17" href="#__codelineno-17-17"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;upvotes&quot;</span><span class="p">&gt;</span>
</span><span id="__span-17-18"><a id="__codelineno-17-18" name="__codelineno-17-18" href="#__codelineno-17-18"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">TrophyOutlined</span><span class="w"> </span><span class="p">/&gt;</span><span class="w"> </span><span class="nx">Most</span><span class="w"> </span><span class="nx">Upvoted</span>
</span><span id="__span-17-19"><a id="__codelineno-17-19" name="__codelineno-17-19" href="#__codelineno-17-19"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-17-20"><a id="__codelineno-17-20" name="__codelineno-17-20" href="#__codelineno-17-20"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;verified&quot;</span><span class="p">&gt;</span>
</span><span id="__span-17-21"><a id="__codelineno-17-21" name="__codelineno-17-21" href="#__codelineno-17-21"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">CheckCircleOutlined</span><span class="w"> </span><span class="p">/&gt;</span><span class="w"> </span><span class="nx">Verified</span><span class="w"> </span><span class="nx">Only</span>
</span><span id="__span-17-22"><a id="__codelineno-17-22" name="__codelineno-17-22" href="#__codelineno-17-22"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-17-23"><a id="__codelineno-17-23" name="__codelineno-17-23" href="#__codelineno-17-23"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Select</span><span class="p">&gt;</span>
</span><span id="__span-17-24"><a id="__codelineno-17-24" name="__codelineno-17-24" href="#__codelineno-17-24"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Space</span><span class="p">&gt;</span>
</span><span id="__span-17-25"><a id="__codelineno-17-25" name="__codelineno-17-25" href="#__codelineno-17-25"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Col</span><span class="p">&gt;</span>
</span><span id="__span-17-26"><a id="__codelineno-17-26" name="__codelineno-17-26" href="#__codelineno-17-26"></a>
</span><span id="__span-17-27"><a id="__codelineno-17-27" name="__codelineno-17-27" href="#__codelineno-17-27"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Col</span><span class="w"> </span><span class="na">xs</span><span class="o">=</span><span class="p">{</span><span class="mf">24</span><span class="p">}</span><span class="w"> </span><span class="na">sm</span><span class="o">=</span><span class="p">{</span><span class="mf">12</span><span class="p">}&gt;</span>
</span><span id="__span-17-28"><a id="__codelineno-17-28" name="__codelineno-17-28" href="#__codelineno-17-28"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Space</span><span class="w"> </span><span class="na">direction</span><span class="o">=</span><span class="s">&quot;vertical&quot;</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">width</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;100%&#39;</span><span class="w"> </span><span class="p">}}</span><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="p">{</span><span class="mf">4</span><span class="p">}&gt;</span>
</span><span id="__span-17-29"><a id="__codelineno-17-29" name="__codelineno-17-29" href="#__codelineno-17-29"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Text</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span><span class="p">&gt;</span><span class="nx">Government</span><span class="w"> </span><span class="nx">Level</span><span class="o">:</span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span><span id="__span-17-30"><a id="__codelineno-17-30" name="__codelineno-17-30" href="#__codelineno-17-30"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Select</span>
</span><span id="__span-17-31"><a id="__codelineno-17-31" name="__codelineno-17-31" href="#__codelineno-17-31"></a><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">governmentLevel</span><span class="p">}</span>
</span><span id="__span-17-32"><a id="__codelineno-17-32" name="__codelineno-17-32" href="#__codelineno-17-32"></a><span class="w"> </span><span class="na">onChange</span><span class="o">=</span><span class="p">{(</span><span class="nx">value</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-17-33"><a id="__codelineno-17-33" name="__codelineno-17-33" href="#__codelineno-17-33"></a><span class="w"> </span><span class="nx">setGovernmentLevel</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
</span><span id="__span-17-34"><a id="__codelineno-17-34" name="__codelineno-17-34" href="#__codelineno-17-34"></a><span class="w"> </span><span class="nx">setPage</span><span class="p">(</span><span class="mf">1</span><span class="p">);</span><span class="w"> </span><span class="c1">// Reset to page 1 when filter changes</span>
</span><span id="__span-17-35"><a id="__codelineno-17-35" name="__codelineno-17-35" href="#__codelineno-17-35"></a><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-17-36"><a id="__codelineno-17-36" name="__codelineno-17-36" href="#__codelineno-17-36"></a><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">width</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;100%&#39;</span><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-17-37"><a id="__codelineno-17-37" name="__codelineno-17-37" href="#__codelineno-17-37"></a><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span>
</span><span id="__span-17-38"><a id="__codelineno-17-38" name="__codelineno-17-38" href="#__codelineno-17-38"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-17-39"><a id="__codelineno-17-39" name="__codelineno-17-39" href="#__codelineno-17-39"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;all&quot;</span><span class="p">&gt;</span><span class="nx">All</span><span class="w"> </span><span class="nx">Levels</span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-17-40"><a id="__codelineno-17-40" name="__codelineno-17-40" href="#__codelineno-17-40"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;federal&quot;</span><span class="p">&gt;</span><span class="nx">Federal</span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-17-41"><a id="__codelineno-17-41" name="__codelineno-17-41" href="#__codelineno-17-41"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;provincial&quot;</span><span class="p">&gt;</span><span class="nx">Provincial</span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-17-42"><a id="__codelineno-17-42" name="__codelineno-17-42" href="#__codelineno-17-42"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;municipal&quot;</span><span class="p">&gt;</span><span class="nx">Municipal</span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-17-43"><a id="__codelineno-17-43" name="__codelineno-17-43" href="#__codelineno-17-43"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Select</span><span class="p">&gt;</span>
</span><span id="__span-17-44"><a id="__codelineno-17-44" name="__codelineno-17-44" href="#__codelineno-17-44"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Space</span><span class="p">&gt;</span>
</span><span id="__span-17-45"><a id="__codelineno-17-45" name="__codelineno-17-45" href="#__codelineno-17-45"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Col</span><span class="p">&gt;</span>
</span><span id="__span-17-46"><a id="__codelineno-17-46" name="__codelineno-17-46" href="#__codelineno-17-46"></a><span class="p">&lt;/</span><span class="nt">Row</span><span class="p">&gt;</span>
</span></code></pre></div>
<h3 id="response-cards">Response Cards<a class="headerlink" href="#response-cards" title="Permanent link">&para;</a></h3>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="p">&lt;</span><span class="nt">Row</span><span class="w"> </span><span class="na">gutter</span><span class="o">=</span><span class="p">{[</span><span class="mf">16</span><span class="p">,</span><span class="w"> </span><span class="mf">16</span><span class="p">]}&gt;</span>
</span><span id="__span-18-2"><a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="w"> </span><span class="p">{</span><span class="nx">responses</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">response</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">(</span>
</span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Col</span><span class="w"> </span><span class="na">xs</span><span class="o">=</span><span class="p">{</span><span class="mf">24</span><span class="p">}</span><span class="w"> </span><span class="na">key</span><span class="o">=</span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">id</span><span class="p">}&gt;</span>
</span><span id="__span-18-4"><a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Card</span><span class="w"> </span><span class="na">hoverable</span><span class="p">&gt;</span>
</span><span id="__span-18-5"><a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Header */</span><span class="p">}</span>
</span><span id="__span-18-6"><a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">div</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span>
</span><span id="__span-18-7"><a id="__codelineno-18-7" name="__codelineno-18-7" href="#__codelineno-18-7"></a><span class="w"> </span><span class="nx">display</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;flex&#39;</span><span class="p">,</span>
</span><span id="__span-18-8"><a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a><span class="w"> </span><span class="nx">justifyContent</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;space-between&#39;</span><span class="p">,</span>
</span><span id="__span-18-9"><a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a><span class="w"> </span><span class="nx">alignItems</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;center&#39;</span><span class="p">,</span>
</span><span id="__span-18-10"><a id="__codelineno-18-10" name="__codelineno-18-10" href="#__codelineno-18-10"></a><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">16</span>
</span><span id="__span-18-11"><a id="__codelineno-18-11" name="__codelineno-18-11" href="#__codelineno-18-11"></a><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-12"><a id="__codelineno-18-12" name="__codelineno-18-12" href="#__codelineno-18-12"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Space</span><span class="p">&gt;</span>
</span><span id="__span-18-13"><a id="__codelineno-18-13" name="__codelineno-18-13" href="#__codelineno-18-13"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Text</span><span class="w"> </span><span class="na">strong</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">16</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-14"><a id="__codelineno-18-14" name="__codelineno-18-14" href="#__codelineno-18-14"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">userName</span><span class="p">}</span>
</span><span id="__span-18-15"><a id="__codelineno-18-15" name="__codelineno-18-15" href="#__codelineno-18-15"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span><span id="__span-18-16"><a id="__codelineno-18-16" name="__codelineno-18-16" href="#__codelineno-18-16"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">isVerified</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span>
</span><span id="__span-18-17"><a id="__codelineno-18-17" name="__codelineno-18-17" href="#__codelineno-18-17"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Tag</span><span class="w"> </span><span class="na">color</span><span class="o">=</span><span class="s">&quot;green&quot;</span><span class="w"> </span><span class="na">icon</span><span class="o">=</span><span class="p">{&lt;</span><span class="nt">CheckCircleOutlined</span><span class="w"> </span><span class="p">/&gt;}&gt;</span>
</span><span id="__span-18-18"><a id="__codelineno-18-18" name="__codelineno-18-18" href="#__codelineno-18-18"></a><span class="w"> </span><span class="nx">Verified</span>
</span><span id="__span-18-19"><a id="__codelineno-18-19" name="__codelineno-18-19" href="#__codelineno-18-19"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Tag</span><span class="p">&gt;</span>
</span><span id="__span-18-20"><a id="__codelineno-18-20" name="__codelineno-18-20" href="#__codelineno-18-20"></a><span class="w"> </span><span class="p">)}</span>
</span><span id="__span-18-21"><a id="__codelineno-18-21" name="__codelineno-18-21" href="#__codelineno-18-21"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Space</span><span class="p">&gt;</span>
</span><span id="__span-18-22"><a id="__codelineno-18-22" name="__codelineno-18-22" href="#__codelineno-18-22"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Text</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">12</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-23"><a id="__codelineno-18-23" name="__codelineno-18-23" href="#__codelineno-18-23"></a><span class="w"> </span><span class="p">{</span><span class="nx">dayjs</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">createdAt</span><span class="p">).</span><span class="nx">fromNow</span><span class="p">()}</span>
</span><span id="__span-18-24"><a id="__codelineno-18-24" name="__codelineno-18-24" href="#__codelineno-18-24"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span><span id="__span-18-25"><a id="__codelineno-18-25" name="__codelineno-18-25" href="#__codelineno-18-25"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span><span id="__span-18-26"><a id="__codelineno-18-26" name="__codelineno-18-26" href="#__codelineno-18-26"></a>
</span><span id="__span-18-27"><a id="__codelineno-18-27" name="__codelineno-18-27" href="#__codelineno-18-27"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Comment */</span><span class="p">}</span>
</span><span id="__span-18-28"><a id="__codelineno-18-28" name="__codelineno-18-28" href="#__codelineno-18-28"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Paragraph</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">16</span><span class="p">,</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">14</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-29"><a id="__codelineno-18-29" name="__codelineno-18-29" href="#__codelineno-18-29"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">comment</span><span class="p">}</span>
</span><span id="__span-18-30"><a id="__codelineno-18-30" name="__codelineno-18-30" href="#__codelineno-18-30"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Paragraph</span><span class="p">&gt;</span>
</span><span id="__span-18-31"><a id="__codelineno-18-31" name="__codelineno-18-31" href="#__codelineno-18-31"></a>
</span><span id="__span-18-32"><a id="__codelineno-18-32" name="__codelineno-18-32" href="#__codelineno-18-32"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Quoted Text (if any) */</span><span class="p">}</span>
</span><span id="__span-18-33"><a id="__codelineno-18-33" name="__codelineno-18-33" href="#__codelineno-18-33"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">quotedText</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span>
</span><span id="__span-18-34"><a id="__codelineno-18-34" name="__codelineno-18-34" href="#__codelineno-18-34"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">div</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span>
</span><span id="__span-18-35"><a id="__codelineno-18-35" name="__codelineno-18-35" href="#__codelineno-18-35"></a><span class="w"> </span><span class="nx">padding</span><span class="o">:</span><span class="w"> </span><span class="kt">12</span><span class="p">,</span>
</span><span id="__span-18-36"><a id="__codelineno-18-36" name="__codelineno-18-36" href="#__codelineno-18-36"></a><span class="w"> </span><span class="nx">background</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;rgba(255,255,255,0.05)&#39;</span><span class="p">,</span>
</span><span id="__span-18-37"><a id="__codelineno-18-37" name="__codelineno-18-37" href="#__codelineno-18-37"></a><span class="w"> </span><span class="nx">borderLeft</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;3px solid #1890ff&#39;</span><span class="p">,</span>
</span><span id="__span-18-38"><a id="__codelineno-18-38" name="__codelineno-18-38" href="#__codelineno-18-38"></a><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">16</span><span class="p">,</span>
</span><span id="__span-18-39"><a id="__codelineno-18-39" name="__codelineno-18-39" href="#__codelineno-18-39"></a><span class="w"> </span><span class="nx">fontStyle</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;italic&#39;</span>
</span><span id="__span-18-40"><a id="__codelineno-18-40" name="__codelineno-18-40" href="#__codelineno-18-40"></a><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-41"><a id="__codelineno-18-41" name="__codelineno-18-41" href="#__codelineno-18-41"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Text</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">13</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-42"><a id="__codelineno-18-42" name="__codelineno-18-42" href="#__codelineno-18-42"></a><span class="w"> </span><span class="s2">&quot;{response.quotedText}&quot;</span>
</span><span id="__span-18-43"><a id="__codelineno-18-43" name="__codelineno-18-43" href="#__codelineno-18-43"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span><span id="__span-18-44"><a id="__codelineno-18-44" name="__codelineno-18-44" href="#__codelineno-18-44"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span><span id="__span-18-45"><a id="__codelineno-18-45" name="__codelineno-18-45" href="#__codelineno-18-45"></a><span class="w"> </span><span class="p">)}</span>
</span><span id="__span-18-46"><a id="__codelineno-18-46" name="__codelineno-18-46" href="#__codelineno-18-46"></a>
</span><span id="__span-18-47"><a id="__codelineno-18-47" name="__codelineno-18-47" href="#__codelineno-18-47"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Representative Info */</span><span class="p">}</span>
</span><span id="__span-18-48"><a id="__codelineno-18-48" name="__codelineno-18-48" href="#__codelineno-18-48"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">div</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span>
</span><span id="__span-18-49"><a id="__codelineno-18-49" name="__codelineno-18-49" href="#__codelineno-18-49"></a><span class="w"> </span><span class="nx">paddingTop</span><span class="o">:</span><span class="w"> </span><span class="kt">16</span><span class="p">,</span>
</span><span id="__span-18-50"><a id="__codelineno-18-50" name="__codelineno-18-50" href="#__codelineno-18-50"></a><span class="w"> </span><span class="nx">borderTop</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;1px solid rgba(255,255,255,0.1)&#39;</span><span class="p">,</span>
</span><span id="__span-18-51"><a id="__codelineno-18-51" name="__codelineno-18-51" href="#__codelineno-18-51"></a><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">12</span>
</span><span id="__span-18-52"><a id="__codelineno-18-52" name="__codelineno-18-52" href="#__codelineno-18-52"></a><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-53"><a id="__codelineno-18-53" name="__codelineno-18-53" href="#__codelineno-18-53"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Text</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">12</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-54"><a id="__codelineno-18-54" name="__codelineno-18-54" href="#__codelineno-18-54"></a><span class="w"> </span><span class="nx">Sent</span><span class="w"> </span><span class="nx">to</span><span class="o">:</span><span class="p">{</span><span class="s1">&#39; &#39;</span><span class="p">}</span>
</span><span id="__span-18-55"><a id="__codelineno-18-55" name="__codelineno-18-55" href="#__codelineno-18-55"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span><span id="__span-18-56"><a id="__codelineno-18-56" name="__codelineno-18-56" href="#__codelineno-18-56"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Text</span><span class="w"> </span><span class="na">strong</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">13</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-57"><a id="__codelineno-18-57" name="__codelineno-18-57" href="#__codelineno-18-57"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">representativeName</span><span class="p">}</span>
</span><span id="__span-18-58"><a id="__codelineno-18-58" name="__codelineno-18-58" href="#__codelineno-18-58"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span><span id="__span-18-59"><a id="__codelineno-18-59" name="__codelineno-18-59" href="#__codelineno-18-59"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">representativeDistrict</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span>
</span><span id="__span-18-60"><a id="__codelineno-18-60" name="__codelineno-18-60" href="#__codelineno-18-60"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Text</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">12</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-61"><a id="__codelineno-18-61" name="__codelineno-18-61" href="#__codelineno-18-61"></a><span class="w"> </span><span class="p">{</span><span class="s1">&#39; &#39;</span><span class="p">}</span><span class="err"></span><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">representativeDistrict</span><span class="p">}</span>
</span><span id="__span-18-62"><a id="__codelineno-18-62" name="__codelineno-18-62" href="#__codelineno-18-62"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span><span id="__span-18-63"><a id="__codelineno-18-63" name="__codelineno-18-63" href="#__codelineno-18-63"></a><span class="w"> </span><span class="p">)}</span>
</span><span id="__span-18-64"><a id="__codelineno-18-64" name="__codelineno-18-64" href="#__codelineno-18-64"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">div</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">marginTop</span><span class="o">:</span><span class="w"> </span><span class="kt">4</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-18-65"><a id="__codelineno-18-65" name="__codelineno-18-65" href="#__codelineno-18-65"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Tag</span><span class="w"> </span><span class="na">color</span><span class="o">=</span><span class="p">{</span>
</span><span id="__span-18-66"><a id="__codelineno-18-66" name="__codelineno-18-66" href="#__codelineno-18-66"></a><span class="w"> </span><span class="nx">response</span><span class="p">.</span><span class="nx">governmentLevel</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">&#39;federal&#39;</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">&#39;blue&#39;</span><span class="w"> </span><span class="o">:</span>
</span><span id="__span-18-67"><a id="__codelineno-18-67" name="__codelineno-18-67" href="#__codelineno-18-67"></a><span class="w"> </span><span class="nx">response</span><span class="p">.</span><span class="nx">governmentLevel</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">&#39;provincial&#39;</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">&#39;purple&#39;</span><span class="w"> </span><span class="o">:</span>
</span><span id="__span-18-68"><a id="__codelineno-18-68" name="__codelineno-18-68" href="#__codelineno-18-68"></a><span class="w"> </span><span class="s1">&#39;green&#39;</span>
</span><span id="__span-18-69"><a id="__codelineno-18-69" name="__codelineno-18-69" href="#__codelineno-18-69"></a><span class="w"> </span><span class="p">}&gt;</span>
</span><span id="__span-18-70"><a id="__codelineno-18-70" name="__codelineno-18-70" href="#__codelineno-18-70"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">governmentLevel</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="mf">0</span><span class="p">).</span><span class="nx">toUpperCase</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">response</span><span class="p">.</span><span class="nx">governmentLevel</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mf">1</span><span class="p">)}</span>
</span><span id="__span-18-71"><a id="__codelineno-18-71" name="__codelineno-18-71" href="#__codelineno-18-71"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Tag</span><span class="p">&gt;</span>
</span><span id="__span-18-72"><a id="__codelineno-18-72" name="__codelineno-18-72" href="#__codelineno-18-72"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span><span id="__span-18-73"><a id="__codelineno-18-73" name="__codelineno-18-73" href="#__codelineno-18-73"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span><span id="__span-18-74"><a id="__codelineno-18-74" name="__codelineno-18-74" href="#__codelineno-18-74"></a>
</span><span id="__span-18-75"><a id="__codelineno-18-75" name="__codelineno-18-75" href="#__codelineno-18-75"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Upvote Button */</span><span class="p">}</span>
</span><span id="__span-18-76"><a id="__codelineno-18-76" name="__codelineno-18-76" href="#__codelineno-18-76"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Button</span>
</span><span id="__span-18-77"><a id="__codelineno-18-77" name="__codelineno-18-77" href="#__codelineno-18-77"></a><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">hasUpvoted</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">&#39;primary&#39;</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;default&#39;</span><span class="p">}</span>
</span><span id="__span-18-78"><a id="__codelineno-18-78" name="__codelineno-18-78" href="#__codelineno-18-78"></a><span class="w"> </span><span class="na">icon</span><span class="o">=</span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">hasUpvoted</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="p">&lt;</span><span class="nt">HeartFilled</span><span class="w"> </span><span class="p">/&gt;</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="p">&lt;</span><span class="nt">HeartOutlined</span><span class="w"> </span><span class="p">/&gt;}</span>
</span><span id="__span-18-79"><a id="__codelineno-18-79" name="__codelineno-18-79" href="#__codelineno-18-79"></a><span class="w"> </span><span class="na">onClick</span><span class="o">=</span><span class="p">{()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">handleUpvote</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">id</span><span class="p">)}</span>
</span><span id="__span-18-80"><a id="__codelineno-18-80" name="__codelineno-18-80" href="#__codelineno-18-80"></a><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span>
</span><span id="__span-18-81"><a id="__codelineno-18-81" name="__codelineno-18-81" href="#__codelineno-18-81"></a><span class="w"> </span><span class="nx">borderColor</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#eb2f96&#39;</span><span class="p">,</span>
</span><span id="__span-18-82"><a id="__codelineno-18-82" name="__codelineno-18-82" href="#__codelineno-18-82"></a><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="kt">response.hasUpvoted</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">&#39;white&#39;</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#eb2f96&#39;</span>
</span><span id="__span-18-83"><a id="__codelineno-18-83" name="__codelineno-18-83" href="#__codelineno-18-83"></a><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-18-84"><a id="__codelineno-18-84" name="__codelineno-18-84" href="#__codelineno-18-84"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-18-85"><a id="__codelineno-18-85" name="__codelineno-18-85" href="#__codelineno-18-85"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">upvoteCount</span><span class="p">}</span><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">upvoteCount</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">&#39;Upvote&#39;</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Upvotes&#39;</span><span class="p">}</span>
</span><span id="__span-18-86"><a id="__codelineno-18-86" name="__codelineno-18-86" href="#__codelineno-18-86"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Button</span><span class="p">&gt;</span>
</span><span id="__span-18-87"><a id="__codelineno-18-87" name="__codelineno-18-87" href="#__codelineno-18-87"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Card</span><span class="p">&gt;</span>
</span><span id="__span-18-88"><a id="__codelineno-18-88" name="__codelineno-18-88" href="#__codelineno-18-88"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Col</span><span class="p">&gt;</span>
</span><span id="__span-18-89"><a id="__codelineno-18-89" name="__codelineno-18-89" href="#__codelineno-18-89"></a><span class="w"> </span><span class="p">))}</span>
</span><span id="__span-18-90"><a id="__codelineno-18-90" name="__codelineno-18-90" href="#__codelineno-18-90"></a><span class="p">&lt;/</span><span class="nt">Row</span><span class="p">&gt;</span>
</span></code></pre></div>
<h3 id="submit-response-modal">Submit Response Modal<a class="headerlink" href="#submit-response-modal" title="Permanent link">&para;</a></h3>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="p">&lt;</span><span class="nt">Modal</span>
</span><span id="__span-19-2"><a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="w"> </span><span class="na">title</span><span class="o">=</span><span class="s">&quot;Submit Your Response&quot;</span>
</span><span id="__span-19-3"><a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="w"> </span><span class="na">open</span><span class="o">=</span><span class="p">{</span><span class="nx">submitModalVisible</span><span class="p">}</span>
</span><span id="__span-19-4"><a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="w"> </span><span class="na">onCancel</span><span class="o">=</span><span class="p">{()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-19-5"><a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a><span class="w"> </span><span class="nx">setSubmitModalVisible</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span id="__span-19-6"><a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a><span class="w"> </span><span class="nx">form</span><span class="p">.</span><span class="nx">resetFields</span><span class="p">();</span>
</span><span id="__span-19-7"><a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-19-8"><a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a><span class="w"> </span><span class="na">footer</span><span class="o">=</span><span class="p">{</span><span class="kc">null</span><span class="p">}</span>
</span><span id="__span-19-9"><a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a><span class="w"> </span><span class="na">width</span><span class="o">=</span><span class="p">{</span><span class="mf">600</span><span class="p">}</span>
</span><span id="__span-19-10"><a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a><span class="p">&gt;</span>
</span><span id="__span-19-11"><a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span>
</span><span id="__span-19-12"><a id="__codelineno-19-12" name="__codelineno-19-12" href="#__codelineno-19-12"></a><span class="w"> </span><span class="na">form</span><span class="o">=</span><span class="p">{</span><span class="nx">form</span><span class="p">}</span>
</span><span id="__span-19-13"><a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a><span class="w"> </span><span class="na">layout</span><span class="o">=</span><span class="s">&quot;vertical&quot;</span>
</span><span id="__span-19-14"><a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a><span class="w"> </span><span class="na">onFinish</span><span class="o">=</span><span class="p">{</span><span class="nx">handleSubmit</span><span class="p">}</span>
</span><span id="__span-19-15"><a id="__codelineno-19-15" name="__codelineno-19-15" href="#__codelineno-19-15"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-16"><a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span>
</span><span id="__span-19-17"><a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a><span class="w"> </span><span class="na">name</span><span class="o">=</span><span class="s">&quot;userName&quot;</span>
</span><span id="__span-19-18"><a id="__codelineno-19-18" name="__codelineno-19-18" href="#__codelineno-19-18"></a><span class="w"> </span><span class="na">label</span><span class="o">=</span><span class="s">&quot;Your Name&quot;</span>
</span><span id="__span-19-19"><a id="__codelineno-19-19" name="__codelineno-19-19" href="#__codelineno-19-19"></a><span class="w"> </span><span class="na">rules</span><span class="o">=</span><span class="p">{[</span>
</span><span id="__span-19-20"><a id="__codelineno-19-20" name="__codelineno-19-20" href="#__codelineno-19-20"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">required</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Please enter your name&#39;</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-19-21"><a id="__codelineno-19-21" name="__codelineno-19-21" href="#__codelineno-19-21"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">min</span><span class="o">:</span><span class="w"> </span><span class="kt">2</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Name must be at least 2 characters&#39;</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-19-22"><a id="__codelineno-19-22" name="__codelineno-19-22" href="#__codelineno-19-22"></a><span class="w"> </span><span class="p">]}</span>
</span><span id="__span-19-23"><a id="__codelineno-19-23" name="__codelineno-19-23" href="#__codelineno-19-23"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-24"><a id="__codelineno-19-24" name="__codelineno-19-24" href="#__codelineno-19-24"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Input</span><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span><span class="w"> </span><span class="na">placeholder</span><span class="o">=</span><span class="s">&quot;Jane Doe&quot;</span><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-19-25"><a id="__codelineno-19-25" name="__codelineno-19-25" href="#__codelineno-19-25"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-26"><a id="__codelineno-19-26" name="__codelineno-19-26" href="#__codelineno-19-26"></a>
</span><span id="__span-19-27"><a id="__codelineno-19-27" name="__codelineno-19-27" href="#__codelineno-19-27"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span>
</span><span id="__span-19-28"><a id="__codelineno-19-28" name="__codelineno-19-28" href="#__codelineno-19-28"></a><span class="w"> </span><span class="na">name</span><span class="o">=</span><span class="s">&quot;userEmail&quot;</span>
</span><span id="__span-19-29"><a id="__codelineno-19-29" name="__codelineno-19-29" href="#__codelineno-19-29"></a><span class="w"> </span><span class="na">label</span><span class="o">=</span><span class="s">&quot;Your Email&quot;</span>
</span><span id="__span-19-30"><a id="__codelineno-19-30" name="__codelineno-19-30" href="#__codelineno-19-30"></a><span class="w"> </span><span class="na">rules</span><span class="o">=</span><span class="p">{[</span>
</span><span id="__span-19-31"><a id="__codelineno-19-31" name="__codelineno-19-31" href="#__codelineno-19-31"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">required</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Please enter your email&#39;</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-19-32"><a id="__codelineno-19-32" name="__codelineno-19-32" href="#__codelineno-19-32"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kr">type</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;email&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Please enter a valid email&#39;</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-19-33"><a id="__codelineno-19-33" name="__codelineno-19-33" href="#__codelineno-19-33"></a><span class="w"> </span><span class="p">]}</span>
</span><span id="__span-19-34"><a id="__codelineno-19-34" name="__codelineno-19-34" href="#__codelineno-19-34"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-35"><a id="__codelineno-19-35" name="__codelineno-19-35" href="#__codelineno-19-35"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Input</span><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;email&quot;</span><span class="w"> </span><span class="na">placeholder</span><span class="o">=</span><span class="s">&quot;jane@example.com&quot;</span><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-19-36"><a id="__codelineno-19-36" name="__codelineno-19-36" href="#__codelineno-19-36"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-37"><a id="__codelineno-19-37" name="__codelineno-19-37" href="#__codelineno-19-37"></a>
</span><span id="__span-19-38"><a id="__codelineno-19-38" name="__codelineno-19-38" href="#__codelineno-19-38"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span>
</span><span id="__span-19-39"><a id="__codelineno-19-39" name="__codelineno-19-39" href="#__codelineno-19-39"></a><span class="w"> </span><span class="na">name</span><span class="o">=</span><span class="s">&quot;postalCode&quot;</span>
</span><span id="__span-19-40"><a id="__codelineno-19-40" name="__codelineno-19-40" href="#__codelineno-19-40"></a><span class="w"> </span><span class="na">label</span><span class="o">=</span><span class="s">&quot;Your Postal Code (Optional)&quot;</span>
</span><span id="__span-19-41"><a id="__codelineno-19-41" name="__codelineno-19-41" href="#__codelineno-19-41"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-42"><a id="__codelineno-19-42" name="__codelineno-19-42" href="#__codelineno-19-42"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Input</span>
</span><span id="__span-19-43"><a id="__codelineno-19-43" name="__codelineno-19-43" href="#__codelineno-19-43"></a><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span>
</span><span id="__span-19-44"><a id="__codelineno-19-44" name="__codelineno-19-44" href="#__codelineno-19-44"></a><span class="w"> </span><span class="na">placeholder</span><span class="o">=</span><span class="s">&quot;K1A 0B1&quot;</span>
</span><span id="__span-19-45"><a id="__codelineno-19-45" name="__codelineno-19-45" href="#__codelineno-19-45"></a><span class="w"> </span><span class="na">maxLength</span><span class="o">=</span><span class="p">{</span><span class="mf">7</span><span class="p">}</span>
</span><span id="__span-19-46"><a id="__codelineno-19-46" name="__codelineno-19-46" href="#__codelineno-19-46"></a><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">textTransform</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;uppercase&#39;</span><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-19-47"><a id="__codelineno-19-47" name="__codelineno-19-47" href="#__codelineno-19-47"></a><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-19-48"><a id="__codelineno-19-48" name="__codelineno-19-48" href="#__codelineno-19-48"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-49"><a id="__codelineno-19-49" name="__codelineno-19-49" href="#__codelineno-19-49"></a>
</span><span id="__span-19-50"><a id="__codelineno-19-50" name="__codelineno-19-50" href="#__codelineno-19-50"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span>
</span><span id="__span-19-51"><a id="__codelineno-19-51" name="__codelineno-19-51" href="#__codelineno-19-51"></a><span class="w"> </span><span class="na">name</span><span class="o">=</span><span class="s">&quot;representativeName&quot;</span>
</span><span id="__span-19-52"><a id="__codelineno-19-52" name="__codelineno-19-52" href="#__codelineno-19-52"></a><span class="w"> </span><span class="na">label</span><span class="o">=</span><span class="s">&quot;Representative You Contacted&quot;</span>
</span><span id="__span-19-53"><a id="__codelineno-19-53" name="__codelineno-19-53" href="#__codelineno-19-53"></a><span class="w"> </span><span class="na">rules</span><span class="o">=</span><span class="p">{[{</span><span class="w"> </span><span class="nx">required</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Please enter representative name&#39;</span><span class="w"> </span><span class="p">}]}</span>
</span><span id="__span-19-54"><a id="__codelineno-19-54" name="__codelineno-19-54" href="#__codelineno-19-54"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-55"><a id="__codelineno-19-55" name="__codelineno-19-55" href="#__codelineno-19-55"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Input</span><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span><span class="w"> </span><span class="na">placeholder</span><span class="o">=</span><span class="s">&quot;e.g., John Smith&quot;</span><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-19-56"><a id="__codelineno-19-56" name="__codelineno-19-56" href="#__codelineno-19-56"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-57"><a id="__codelineno-19-57" name="__codelineno-19-57" href="#__codelineno-19-57"></a>
</span><span id="__span-19-58"><a id="__codelineno-19-58" name="__codelineno-19-58" href="#__codelineno-19-58"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span>
</span><span id="__span-19-59"><a id="__codelineno-19-59" name="__codelineno-19-59" href="#__codelineno-19-59"></a><span class="w"> </span><span class="na">name</span><span class="o">=</span><span class="s">&quot;representativeDistrict&quot;</span>
</span><span id="__span-19-60"><a id="__codelineno-19-60" name="__codelineno-19-60" href="#__codelineno-19-60"></a><span class="w"> </span><span class="na">label</span><span class="o">=</span><span class="s">&quot;District/Riding (Optional)&quot;</span>
</span><span id="__span-19-61"><a id="__codelineno-19-61" name="__codelineno-19-61" href="#__codelineno-19-61"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-62"><a id="__codelineno-19-62" name="__codelineno-19-62" href="#__codelineno-19-62"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Input</span><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span><span class="w"> </span><span class="na">placeholder</span><span class="o">=</span><span class="s">&quot;e.g., Ottawa Centre&quot;</span><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-19-63"><a id="__codelineno-19-63" name="__codelineno-19-63" href="#__codelineno-19-63"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-64"><a id="__codelineno-19-64" name="__codelineno-19-64" href="#__codelineno-19-64"></a>
</span><span id="__span-19-65"><a id="__codelineno-19-65" name="__codelineno-19-65" href="#__codelineno-19-65"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span>
</span><span id="__span-19-66"><a id="__codelineno-19-66" name="__codelineno-19-66" href="#__codelineno-19-66"></a><span class="w"> </span><span class="na">name</span><span class="o">=</span><span class="s">&quot;governmentLevel&quot;</span>
</span><span id="__span-19-67"><a id="__codelineno-19-67" name="__codelineno-19-67" href="#__codelineno-19-67"></a><span class="w"> </span><span class="na">label</span><span class="o">=</span><span class="s">&quot;Government Level&quot;</span>
</span><span id="__span-19-68"><a id="__codelineno-19-68" name="__codelineno-19-68" href="#__codelineno-19-68"></a><span class="w"> </span><span class="na">rules</span><span class="o">=</span><span class="p">{[{</span><span class="w"> </span><span class="nx">required</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Please select government level&#39;</span><span class="w"> </span><span class="p">}]}</span>
</span><span id="__span-19-69"><a id="__codelineno-19-69" name="__codelineno-19-69" href="#__codelineno-19-69"></a><span class="w"> </span><span class="na">initialValue</span><span class="o">=</span><span class="s">&quot;federal&quot;</span>
</span><span id="__span-19-70"><a id="__codelineno-19-70" name="__codelineno-19-70" href="#__codelineno-19-70"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-71"><a id="__codelineno-19-71" name="__codelineno-19-71" href="#__codelineno-19-71"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Select</span><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span><span class="p">&gt;</span>
</span><span id="__span-19-72"><a id="__codelineno-19-72" name="__codelineno-19-72" href="#__codelineno-19-72"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;federal&quot;</span><span class="p">&gt;</span><span class="nx">Federal</span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-19-73"><a id="__codelineno-19-73" name="__codelineno-19-73" href="#__codelineno-19-73"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;provincial&quot;</span><span class="p">&gt;</span><span class="nx">Provincial</span><span class="o">/</span><span class="nx">Territorial</span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-19-74"><a id="__codelineno-19-74" name="__codelineno-19-74" href="#__codelineno-19-74"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Option</span><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="s">&quot;municipal&quot;</span><span class="p">&gt;</span><span class="nx">Municipal</span><span class="p">&lt;/</span><span class="nt">Option</span><span class="p">&gt;</span>
</span><span id="__span-19-75"><a id="__codelineno-19-75" name="__codelineno-19-75" href="#__codelineno-19-75"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Select</span><span class="p">&gt;</span>
</span><span id="__span-19-76"><a id="__codelineno-19-76" name="__codelineno-19-76" href="#__codelineno-19-76"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-77"><a id="__codelineno-19-77" name="__codelineno-19-77" href="#__codelineno-19-77"></a>
</span><span id="__span-19-78"><a id="__codelineno-19-78" name="__codelineno-19-78" href="#__codelineno-19-78"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span>
</span><span id="__span-19-79"><a id="__codelineno-19-79" name="__codelineno-19-79" href="#__codelineno-19-79"></a><span class="w"> </span><span class="na">name</span><span class="o">=</span><span class="s">&quot;comment&quot;</span>
</span><span id="__span-19-80"><a id="__codelineno-19-80" name="__codelineno-19-80" href="#__codelineno-19-80"></a><span class="w"> </span><span class="na">label</span><span class="o">=</span><span class="s">&quot;Your Comment&quot;</span>
</span><span id="__span-19-81"><a id="__codelineno-19-81" name="__codelineno-19-81" href="#__codelineno-19-81"></a><span class="w"> </span><span class="na">rules</span><span class="o">=</span><span class="p">{[</span>
</span><span id="__span-19-82"><a id="__codelineno-19-82" name="__codelineno-19-82" href="#__codelineno-19-82"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">required</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Please enter your comment&#39;</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-19-83"><a id="__codelineno-19-83" name="__codelineno-19-83" href="#__codelineno-19-83"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">min</span><span class="o">:</span><span class="w"> </span><span class="kt">10</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Comment must be at least 10 characters&#39;</span><span class="w"> </span><span class="p">},</span>
</span><span id="__span-19-84"><a id="__codelineno-19-84" name="__codelineno-19-84" href="#__codelineno-19-84"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">max</span><span class="o">:</span><span class="w"> </span><span class="kt">5000</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Comment must be less than 5000 characters&#39;</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-19-85"><a id="__codelineno-19-85" name="__codelineno-19-85" href="#__codelineno-19-85"></a><span class="w"> </span><span class="p">]}</span>
</span><span id="__span-19-86"><a id="__codelineno-19-86" name="__codelineno-19-86" href="#__codelineno-19-86"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-87"><a id="__codelineno-19-87" name="__codelineno-19-87" href="#__codelineno-19-87"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">TextArea</span>
</span><span id="__span-19-88"><a id="__codelineno-19-88" name="__codelineno-19-88" href="#__codelineno-19-88"></a><span class="w"> </span><span class="na">rows</span><span class="o">=</span><span class="p">{</span><span class="mf">5</span><span class="p">}</span>
</span><span id="__span-19-89"><a id="__codelineno-19-89" name="__codelineno-19-89" href="#__codelineno-19-89"></a><span class="w"> </span><span class="na">placeholder</span><span class="o">=</span><span class="s">&quot;Share your thoughts, the response you received, or why this issue matters to you...&quot;</span>
</span><span id="__span-19-90"><a id="__codelineno-19-90" name="__codelineno-19-90" href="#__codelineno-19-90"></a><span class="w"> </span><span class="na">showCount</span>
</span><span id="__span-19-91"><a id="__codelineno-19-91" name="__codelineno-19-91" href="#__codelineno-19-91"></a><span class="w"> </span><span class="na">maxLength</span><span class="o">=</span><span class="p">{</span><span class="mf">5000</span><span class="p">}</span>
</span><span id="__span-19-92"><a id="__codelineno-19-92" name="__codelineno-19-92" href="#__codelineno-19-92"></a><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-19-93"><a id="__codelineno-19-93" name="__codelineno-19-93" href="#__codelineno-19-93"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-94"><a id="__codelineno-19-94" name="__codelineno-19-94" href="#__codelineno-19-94"></a>
</span><span id="__span-19-95"><a id="__codelineno-19-95" name="__codelineno-19-95" href="#__codelineno-19-95"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span>
</span><span id="__span-19-96"><a id="__codelineno-19-96" name="__codelineno-19-96" href="#__codelineno-19-96"></a><span class="w"> </span><span class="na">name</span><span class="o">=</span><span class="s">&quot;sendCopy&quot;</span>
</span><span id="__span-19-97"><a id="__codelineno-19-97" name="__codelineno-19-97" href="#__codelineno-19-97"></a><span class="w"> </span><span class="na">valuePropName</span><span class="o">=</span><span class="s">&quot;checked&quot;</span>
</span><span id="__span-19-98"><a id="__codelineno-19-98" name="__codelineno-19-98" href="#__codelineno-19-98"></a><span class="w"> </span><span class="na">initialValue</span><span class="o">=</span><span class="p">{</span><span class="kc">true</span><span class="p">}</span>
</span><span id="__span-19-99"><a id="__codelineno-19-99" name="__codelineno-19-99" href="#__codelineno-19-99"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-19-100"><a id="__codelineno-19-100" name="__codelineno-19-100" href="#__codelineno-19-100"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Checkbox</span><span class="p">&gt;</span>
</span><span id="__span-19-101"><a id="__codelineno-19-101" name="__codelineno-19-101" href="#__codelineno-19-101"></a><span class="w"> </span><span class="nx">Email</span><span class="w"> </span><span class="nx">me</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="nx">copy</span><span class="w"> </span><span class="nx">and</span><span class="w"> </span><span class="nx">verification</span><span class="w"> </span><span class="nx">link</span>
</span><span id="__span-19-102"><a id="__codelineno-19-102" name="__codelineno-19-102" href="#__codelineno-19-102"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Checkbox</span><span class="p">&gt;</span>
</span><span id="__span-19-103"><a id="__codelineno-19-103" name="__codelineno-19-103" href="#__codelineno-19-103"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-104"><a id="__codelineno-19-104" name="__codelineno-19-104" href="#__codelineno-19-104"></a>
</span><span id="__span-19-105"><a id="__codelineno-19-105" name="__codelineno-19-105" href="#__codelineno-19-105"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-106"><a id="__codelineno-19-106" name="__codelineno-19-106" href="#__codelineno-19-106"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Space</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">width</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;100%&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">justifyContent</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;flex-end&#39;</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-19-107"><a id="__codelineno-19-107" name="__codelineno-19-107" href="#__codelineno-19-107"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Button</span><span class="w"> </span><span class="na">onClick</span><span class="o">=</span><span class="p">{()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-19-108"><a id="__codelineno-19-108" name="__codelineno-19-108" href="#__codelineno-19-108"></a><span class="w"> </span><span class="nx">setSubmitModalVisible</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span id="__span-19-109"><a id="__codelineno-19-109" name="__codelineno-19-109" href="#__codelineno-19-109"></a><span class="w"> </span><span class="nx">form</span><span class="p">.</span><span class="nx">resetFields</span><span class="p">();</span>
</span><span id="__span-19-110"><a id="__codelineno-19-110" name="__codelineno-19-110" href="#__codelineno-19-110"></a><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-19-111"><a id="__codelineno-19-111" name="__codelineno-19-111" href="#__codelineno-19-111"></a><span class="w"> </span><span class="nx">Cancel</span>
</span><span id="__span-19-112"><a id="__codelineno-19-112" name="__codelineno-19-112" href="#__codelineno-19-112"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Button</span><span class="p">&gt;</span>
</span><span id="__span-19-113"><a id="__codelineno-19-113" name="__codelineno-19-113" href="#__codelineno-19-113"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Button</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;primary&quot;</span><span class="w"> </span><span class="na">htmlType</span><span class="o">=</span><span class="s">&quot;submit&quot;</span><span class="w"> </span><span class="na">size</span><span class="o">=</span><span class="s">&quot;large&quot;</span><span class="p">&gt;</span>
</span><span id="__span-19-114"><a id="__codelineno-19-114" name="__codelineno-19-114" href="#__codelineno-19-114"></a><span class="w"> </span><span class="nx">Submit</span><span class="w"> </span><span class="nx">Response</span>
</span><span id="__span-19-115"><a id="__codelineno-19-115" name="__codelineno-19-115" href="#__codelineno-19-115"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Button</span><span class="p">&gt;</span>
</span><span id="__span-19-116"><a id="__codelineno-19-116" name="__codelineno-19-116" href="#__codelineno-19-116"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Space</span><span class="p">&gt;</span>
</span><span id="__span-19-117"><a id="__codelineno-19-117" name="__codelineno-19-117" href="#__codelineno-19-117"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">.</span><span class="na">Item</span><span class="p">&gt;</span>
</span><span id="__span-19-118"><a id="__codelineno-19-118" name="__codelineno-19-118" href="#__codelineno-19-118"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Form</span><span class="p">&gt;</span>
</span><span id="__span-19-119"><a id="__codelineno-19-119" name="__codelineno-19-119" href="#__codelineno-19-119"></a><span class="p">&lt;/</span><span class="nt">Modal</span><span class="p">&gt;</span>
</span></code></pre></div>
<h3 id="pagination">Pagination<a class="headerlink" href="#pagination" title="Permanent link">&para;</a></h3>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="p">{</span><span class="nx">total</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nx">pageSize</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span>
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">div</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">textAlign</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;center&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">marginTop</span><span class="o">:</span><span class="w"> </span><span class="kt">32</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Pagination</span>
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="w"> </span><span class="na">current</span><span class="o">=</span><span class="p">{</span><span class="nx">page</span><span class="p">}</span>
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a><span class="w"> </span><span class="na">total</span><span class="o">=</span><span class="p">{</span><span class="nx">total</span><span class="p">}</span>
</span><span id="__span-20-6"><a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a><span class="w"> </span><span class="na">pageSize</span><span class="o">=</span><span class="p">{</span><span class="nx">pageSize</span><span class="p">}</span>
</span><span id="__span-20-7"><a id="__codelineno-20-7" name="__codelineno-20-7" href="#__codelineno-20-7"></a><span class="w"> </span><span class="na">onChange</span><span class="o">=</span><span class="p">{(</span><span class="nx">newPage</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-20-8"><a id="__codelineno-20-8" name="__codelineno-20-8" href="#__codelineno-20-8"></a><span class="w"> </span><span class="nx">setPage</span><span class="p">(</span><span class="nx">newPage</span><span class="p">);</span>
</span><span id="__span-20-9"><a id="__codelineno-20-9" name="__codelineno-20-9" href="#__codelineno-20-9"></a><span class="w"> </span><span class="nb">window</span><span class="p">.</span><span class="nx">scrollTo</span><span class="p">({</span><span class="w"> </span><span class="nx">top</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">,</span><span class="w"> </span><span class="nx">behavior</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;smooth&#39;</span><span class="w"> </span><span class="p">});</span>
</span><span id="__span-20-10"><a id="__codelineno-20-10" name="__codelineno-20-10" href="#__codelineno-20-10"></a><span class="w"> </span><span class="p">}}</span>
</span><span id="__span-20-11"><a id="__codelineno-20-11" name="__codelineno-20-11" href="#__codelineno-20-11"></a><span class="w"> </span><span class="na">showSizeChanger</span><span class="o">=</span><span class="p">{</span><span class="kc">false</span><span class="p">}</span>
</span><span id="__span-20-12"><a id="__codelineno-20-12" name="__codelineno-20-12" href="#__codelineno-20-12"></a><span class="w"> </span><span class="na">showTotal</span><span class="o">=</span><span class="p">{(</span><span class="nx">total</span><span class="p">,</span><span class="w"> </span><span class="nx">range</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="sb">`</span><span class="si">${</span><span class="nx">range</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span><span class="si">}</span><span class="sb">-</span><span class="si">${</span><span class="nx">range</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span><span class="si">}</span><span class="sb"> of </span><span class="si">${</span><span class="nx">total</span><span class="si">}</span><span class="sb"> responses`</span><span class="p">}</span>
</span><span id="__span-20-13"><a id="__codelineno-20-13" name="__codelineno-20-13" href="#__codelineno-20-13"></a><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-20-14"><a id="__codelineno-20-14" name="__codelineno-20-14" href="#__codelineno-20-14"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span><span id="__span-20-15"><a id="__codelineno-20-15" name="__codelineno-20-15" href="#__codelineno-20-15"></a><span class="p">)}</span>
</span></code></pre></div>
<hr />
<h2 id="performance-considerations">Performance Considerations<a class="headerlink" href="#performance-considerations" title="Permanent link">&para;</a></h2>
<h3 id="1-parallel-data-fetching">1. Parallel Data Fetching<a class="headerlink" href="#1-parallel-data-fetching" title="Permanent link">&para;</a></h3>
<p>Campaign, stats, and responses fetched simultaneously:</p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">campaignRes</span><span class="p">,</span><span class="w"> </span><span class="nx">statsRes</span><span class="p">,</span><span class="w"> </span><span class="nx">responsesRes</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span>
</span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sb">`/api/public/campaigns/</span><span class="si">${</span><span class="nx">campaignId</span><span class="si">}</span><span class="sb">`</span><span class="p">),</span>
</span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sb">`/api/public/responses/campaigns/</span><span class="si">${</span><span class="nx">campaignId</span><span class="si">}</span><span class="sb">/stats`</span><span class="p">),</span>
</span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sb">`/api/public/responses/campaigns/</span><span class="si">${</span><span class="nx">campaignId</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">params</span><span class="w"> </span><span class="p">})</span>
</span><span id="__span-21-5"><a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a><span class="p">]);</span>
</span></code></pre></div>
<p><strong>Benefit</strong>: Reduces initial load time by ~60% vs sequential requests.</p>
<h3 id="2-optimistic-upvote-updates">2. Optimistic Upvote Updates<a class="headerlink" href="#2-optimistic-upvote-updates" title="Permanent link">&para;</a></h3>
<p>UI updates immediately before API confirmation:</p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="c1">// Update UI first</span>
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a><span class="nx">setResponses</span><span class="p">(</span><span class="nx">prev</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">prev</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">r</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-22-3"><a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">id</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">responseId</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-22-4"><a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">...</span><span class="nx">r</span><span class="p">,</span><span class="w"> </span><span class="nx">hasUpvoted</span><span class="o">:</span><span class="w"> </span><span class="o">!</span><span class="nx">r</span><span class="p">.</span><span class="nx">hasUpvoted</span><span class="p">,</span><span class="w"> </span><span class="nx">upvoteCount</span><span class="o">:</span><span class="w"> </span><span class="kt">r.upvoteCount</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="p">};</span>
</span><span id="__span-22-5"><a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-22-6"><a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">r</span><span class="p">;</span>
</span><span id="__span-22-7"><a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a><span class="p">}));</span>
</span><span id="__span-22-8"><a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-8"></a>
</span><span id="__span-22-9"><a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-9"></a><span class="c1">// Then API call</span>
</span><span id="__span-22-10"><a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-10"></a><span class="k">await</span><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="sb">`/api/public/responses/</span><span class="si">${</span><span class="nx">responseId</span><span class="si">}</span><span class="sb">/upvote`</span><span class="p">);</span>
</span></code></pre></div>
<p><strong>Benefit</strong>: Perceived performance improvement, instant feedback.</p>
<h3 id="3-server-side-filtering">3. Server-Side Filtering<a class="headerlink" href="#3-server-side-filtering" title="Permanent link">&para;</a></h3>
<p>All filtering/sorting done via API query params (not client-side):</p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="nx">params</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="w"> </span><span class="nx">sortBy</span><span class="p">,</span>
</span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="w"> </span><span class="nx">governmentLevel</span><span class="o">:</span><span class="w"> </span><span class="kt">governmentLevel</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">&#39;all&#39;</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nx">undefined</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">governmentLevel</span>
</span><span id="__span-23-4"><a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="p">}</span>
</span></code></pre></div>
<p><strong>Benefit</strong>: Scalable to thousands of responses, no client memory issues.</p>
<h3 id="4-pagination">4. Pagination<a class="headerlink" href="#4-pagination" title="Permanent link">&para;</a></h3>
<p>Limited to 20 responses per page:</p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">pageSize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">20</span><span class="p">;</span>
</span></code></pre></div>
<p><strong>Benefit</strong>: Reduces DOM nodes, faster render, better mobile performance.</p>
<h3 id="5-scroll-to-top-on-page-change">5. Scroll to Top on Page Change<a class="headerlink" href="#5-scroll-to-top-on-page-change" title="Permanent link">&para;</a></h3>
<p>Smooth scroll when pagination changes:</p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="nx">onChange</span><span class="o">=</span><span class="p">{(</span><span class="nx">newPage</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a><span class="w"> </span><span class="nx">setPage</span><span class="p">(</span><span class="nx">newPage</span><span class="p">);</span>
</span><span id="__span-25-3"><a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="w"> </span><span class="nb">window</span><span class="p">.</span><span class="nx">scrollTo</span><span class="p">({</span><span class="w"> </span><span class="nx">top</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">,</span><span class="w"> </span><span class="nx">behavior</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;smooth&#39;</span><span class="w"> </span><span class="p">});</span>
</span><span id="__span-25-4"><a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="p">}}</span>
</span></code></pre></div>
<p><strong>Benefit</strong>: Better UX, user doesn't miss new content.</p>
<hr />
<h2 id="responsive-design">Responsive Design<a class="headerlink" href="#responsive-design" title="Permanent link">&para;</a></h2>
<h3 id="breakpoint-behavior">Breakpoint Behavior<a class="headerlink" href="#breakpoint-behavior" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Breakpoint</th>
<th>Stats Columns</th>
<th>Response Cards</th>
<th>Filter Layout</th>
<th>Modal Width</th>
</tr>
</thead>
<tbody>
<tr>
<td>xs (0-575px)</td>
<td>1 column</td>
<td>1 column</td>
<td>Stacked</td>
<td>90% viewport</td>
</tr>
<tr>
<td>sm (576-767px)</td>
<td>3 columns</td>
<td>1 column</td>
<td>Stacked</td>
<td>90% viewport</td>
</tr>
<tr>
<td>md (768-991px)</td>
<td>3 columns</td>
<td>1 column</td>
<td>Side-by-side</td>
<td>600px</td>
</tr>
<tr>
<td>lg (992px+)</td>
<td>3 columns</td>
<td>1 column</td>
<td>Side-by-side</td>
<td>600px</td>
</tr>
</tbody>
</table>
<h3 id="mobile-adaptations">Mobile Adaptations<a class="headerlink" href="#mobile-adaptations" title="Permanent link">&para;</a></h3>
<p><strong>Statistics Cards:</strong>
- Stack vertically on xs (easier to scan)
- Show 3 columns on sm+ (compact display)
- Font size remains large (32px) for impact</p>
<p><strong>Response Cards:</strong>
- Always full-width (xs=24)
- Better readability on narrow screens
- Upvote button full-width on mobile (future enhancement)</p>
<p><strong>Sort/Filter Controls:</strong>
- Stack vertically on xs (full-width selects)
- Side-by-side on sm+ (50% width each)
- Labels above selects for clarity</p>
<p><strong>Submit Modal:</strong>
- Width adapts to viewport (90% on mobile, 600px desktop)
- Form fields always full-width
- TextArea shrinks to 3 rows on mobile (vs 5 desktop)</p>
<hr />
<h2 id="accessibility">Accessibility<a class="headerlink" href="#accessibility" title="Permanent link">&para;</a></h2>
<h3 id="keyboard-navigation">Keyboard Navigation<a class="headerlink" href="#keyboard-navigation" title="Permanent link">&para;</a></h3>
<p><strong>Response Cards:</strong>
- Upvote button focusable via Tab
- Enter/Space toggles upvote</p>
<p><strong>Sort/Filter Controls:</strong>
- Dropdowns keyboard navigable (Arrow keys + Enter)
- Focus visible on all select elements</p>
<p><strong>Pagination:</strong>
- Page numbers focusable
- Arrow keys navigate pages (native Ant Design)</p>
<h3 id="aria-labels">ARIA Labels<a class="headerlink" href="#aria-labels" title="Permanent link">&para;</a></h3>
<p><strong>Upvote Button:</strong>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="p">&lt;</span><span class="nt">Button</span>
</span><span id="__span-26-2"><a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a><span class="w"> </span><span class="na">aria-label</span><span class="o">=</span><span class="p">{</span><span class="sb">`Upvote response by </span><span class="si">${</span><span class="nx">response</span><span class="p">.</span><span class="nx">userName</span><span class="si">}</span><span class="sb">. Current upvotes: </span><span class="si">${</span><span class="nx">response</span><span class="p">.</span><span class="nx">upvoteCount</span><span class="si">}</span><span class="sb">`</span><span class="p">}</span>
</span><span id="__span-26-3"><a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a><span class="w"> </span><span class="na">onClick</span><span class="o">=</span><span class="p">{()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">handleUpvote</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">id</span><span class="p">)}</span>
</span><span id="__span-26-4"><a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="p">&gt;</span>
</span><span id="__span-26-5"><a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a><span class="w"> </span><span class="p">{</span><span class="nx">response</span><span class="p">.</span><span class="nx">upvoteCount</span><span class="p">}</span><span class="w"> </span><span class="nx">Upvotes</span>
</span><span id="__span-26-6"><a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a><span class="p">&lt;/</span><span class="nt">Button</span><span class="p">&gt;</span>
</span></code></pre></div></p>
<p><strong>Statistics Cards:</strong>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="p">&lt;</span><span class="nt">Statistic</span>
</span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a><span class="w"> </span><span class="na">title</span><span class="o">=</span><span class="s">&quot;Total Responses&quot;</span>
</span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a><span class="w"> </span><span class="na">value</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="p">.</span><span class="nx">totalResponses</span><span class="p">}</span>
</span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a><span class="w"> </span><span class="na">aria-label</span><span class="o">=</span><span class="p">{</span><span class="sb">`Total responses: </span><span class="si">${</span><span class="nx">stats</span><span class="p">.</span><span class="nx">totalResponses</span><span class="si">}</span><span class="sb">`</span><span class="p">}</span>
</span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a><span class="p">/&gt;</span>
</span></code></pre></div></p>
<p><strong>Modal:</strong>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="p">&lt;</span><span class="nt">Modal</span>
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a><span class="w"> </span><span class="na">title</span><span class="o">=</span><span class="s">&quot;Submit Your Response&quot;</span>
</span><span id="__span-28-3"><a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a><span class="w"> </span><span class="na">aria-labelledby</span><span class="o">=</span><span class="s">&quot;submit-response-title&quot;</span>
</span><span id="__span-28-4"><a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a><span class="w"> </span><span class="na">aria-describedby</span><span class="o">=</span><span class="s">&quot;submit-response-description&quot;</span>
</span><span id="__span-28-5"><a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-5"></a><span class="p">&gt;</span>
</span></code></pre></div></p>
<h3 id="screen-reader-support">Screen Reader Support<a class="headerlink" href="#screen-reader-support" title="Permanent link">&para;</a></h3>
<p><strong>Verification Badge:</strong>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="p">&lt;</span><span class="nt">Tag</span><span class="w"> </span><span class="na">color</span><span class="o">=</span><span class="s">&quot;green&quot;</span><span class="w"> </span><span class="na">icon</span><span class="o">=</span><span class="p">{&lt;</span><span class="nt">CheckCircleOutlined</span><span class="w"> </span><span class="p">/&gt;}&gt;</span>
</span><span id="__span-29-2"><a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">span</span><span class="w"> </span><span class="na">aria-label</span><span class="o">=</span><span class="s">&quot;Email verified&quot;</span><span class="p">&gt;</span><span class="nx">Verified</span><span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span><span id="__span-29-3"><a id="__codelineno-29-3" name="__codelineno-29-3" href="#__codelineno-29-3"></a><span class="p">&lt;/</span><span class="nt">Tag</span><span class="p">&gt;</span>
</span></code></pre></div></p>
<p><strong>Timestamp:</strong>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="p">&lt;</span><span class="nt">Text</span>
</span><span id="__span-30-2"><a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span>
</span><span id="__span-30-3"><a id="__codelineno-30-3" name="__codelineno-30-3" href="#__codelineno-30-3"></a><span class="w"> </span><span class="na">aria-label</span><span class="o">=</span><span class="p">{</span><span class="sb">`Posted </span><span class="si">${</span><span class="nx">dayjs</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">createdAt</span><span class="p">).</span><span class="nx">format</span><span class="p">(</span><span class="s1">&#39;MMMM D, YYYY at h:mm A&#39;</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span><span class="p">}</span>
</span><span id="__span-30-4"><a id="__codelineno-30-4" name="__codelineno-30-4" href="#__codelineno-30-4"></a><span class="p">&gt;</span>
</span><span id="__span-30-5"><a id="__codelineno-30-5" name="__codelineno-30-5" href="#__codelineno-30-5"></a><span class="w"> </span><span class="p">{</span><span class="nx">dayjs</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">createdAt</span><span class="p">).</span><span class="nx">fromNow</span><span class="p">()}</span>
</span><span id="__span-30-6"><a id="__codelineno-30-6" name="__codelineno-30-6" href="#__codelineno-30-6"></a><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span></code></pre></div></p>
<p><strong>Form Validation:</strong>
- Error messages announced automatically
- Required field indicators (<code>required</code> attribute)
- Help text linked via <code>aria-describedby</code></p>
<hr />
<h2 id="troubleshooting">Troubleshooting<a class="headerlink" href="#troubleshooting" title="Permanent link">&para;</a></h2>
<h3 id="issue-upvotes-not-persisting">Issue: Upvotes Not Persisting<a class="headerlink" href="#issue-upvotes-not-persisting" title="Permanent link">&para;</a></h3>
<p><strong>Symptoms:</strong>
- User clicks upvote, count increments
- Page refresh resets upvote
- Heart icon reverts to outline</p>
<p><strong>Causes:</strong>
1. API call failing silently
2. Session/cookie not persisting user ID
3. Optimistic update not reverting on error
4. Backend not tracking upvote source</p>
<p><strong>Solutions:</strong></p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">handleUpvote</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">(</span><span class="nx">responseId</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-2"><a id="__codelineno-31-2" name="__codelineno-31-2" href="#__codelineno-31-2"></a><span class="w"> </span><span class="c1">// Save previous state for rollback</span>
</span><span id="__span-31-3"><a id="__codelineno-31-3" name="__codelineno-31-3" href="#__codelineno-31-3"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">previousResponses</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[...</span><span class="nx">responses</span><span class="p">];</span>
</span><span id="__span-31-4"><a id="__codelineno-31-4" name="__codelineno-31-4" href="#__codelineno-31-4"></a>
</span><span id="__span-31-5"><a id="__codelineno-31-5" name="__codelineno-31-5" href="#__codelineno-31-5"></a><span class="w"> </span><span class="c1">// Optimistic update</span>
</span><span id="__span-31-6"><a id="__codelineno-31-6" name="__codelineno-31-6" href="#__codelineno-31-6"></a><span class="w"> </span><span class="nx">setResponses</span><span class="p">(</span><span class="nx">prev</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">prev</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">r</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-7"><a id="__codelineno-31-7" name="__codelineno-31-7" href="#__codelineno-31-7"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">id</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">responseId</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-8"><a id="__codelineno-31-8" name="__codelineno-31-8" href="#__codelineno-31-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-9"><a id="__codelineno-31-9" name="__codelineno-31-9" href="#__codelineno-31-9"></a><span class="w"> </span><span class="p">...</span><span class="nx">r</span><span class="p">,</span>
</span><span id="__span-31-10"><a id="__codelineno-31-10" name="__codelineno-31-10" href="#__codelineno-31-10"></a><span class="w"> </span><span class="nx">hasUpvoted</span><span class="o">:</span><span class="w"> </span><span class="o">!</span><span class="nx">r</span><span class="p">.</span><span class="nx">hasUpvoted</span><span class="p">,</span>
</span><span id="__span-31-11"><a id="__codelineno-31-11" name="__codelineno-31-11" href="#__codelineno-31-11"></a><span class="w"> </span><span class="nx">upvoteCount</span><span class="o">:</span><span class="w"> </span><span class="kt">r.upvoteCount</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nx">hasUpvoted</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="o">-</span><span class="nx">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">1</span><span class="p">)</span>
</span><span id="__span-31-12"><a id="__codelineno-31-12" name="__codelineno-31-12" href="#__codelineno-31-12"></a><span class="w"> </span><span class="p">};</span>
</span><span id="__span-31-13"><a id="__codelineno-31-13" name="__codelineno-31-13" href="#__codelineno-31-13"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-31-14"><a id="__codelineno-31-14" name="__codelineno-31-14" href="#__codelineno-31-14"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">r</span><span class="p">;</span>
</span><span id="__span-31-15"><a id="__codelineno-31-15" name="__codelineno-31-15" href="#__codelineno-31-15"></a><span class="w"> </span><span class="p">}));</span>
</span><span id="__span-31-16"><a id="__codelineno-31-16" name="__codelineno-31-16" href="#__codelineno-31-16"></a>
</span><span id="__span-31-17"><a id="__codelineno-31-17" name="__codelineno-31-17" href="#__codelineno-31-17"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-18"><a id="__codelineno-31-18" name="__codelineno-31-18" href="#__codelineno-31-18"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">response</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span>
</span><span id="__span-31-19"><a id="__codelineno-31-19" name="__codelineno-31-19" href="#__codelineno-31-19"></a><span class="w"> </span><span class="sb">`/api/public/responses/</span><span class="si">${</span><span class="nx">responseId</span><span class="si">}</span><span class="sb">/upvote`</span><span class="p">,</span>
</span><span id="__span-31-20"><a id="__codelineno-31-20" name="__codelineno-31-20" href="#__codelineno-31-20"></a><span class="w"> </span><span class="p">{},</span>
</span><span id="__span-31-21"><a id="__codelineno-31-21" name="__codelineno-31-21" href="#__codelineno-31-21"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">timeout</span><span class="o">:</span><span class="w"> </span><span class="kt">5000</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-31-22"><a id="__codelineno-31-22" name="__codelineno-31-22" href="#__codelineno-31-22"></a><span class="w"> </span><span class="p">);</span>
</span><span id="__span-31-23"><a id="__codelineno-31-23" name="__codelineno-31-23" href="#__codelineno-31-23"></a>
</span><span id="__span-31-24"><a id="__codelineno-31-24" name="__codelineno-31-24" href="#__codelineno-31-24"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Upvote response:&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
</span><span id="__span-31-25"><a id="__codelineno-31-25" name="__codelineno-31-25" href="#__codelineno-31-25"></a>
</span><span id="__span-31-26"><a id="__codelineno-31-26" name="__codelineno-31-26" href="#__codelineno-31-26"></a><span class="w"> </span><span class="c1">// Update with server count (authoritative)</span>
</span><span id="__span-31-27"><a id="__codelineno-31-27" name="__codelineno-31-27" href="#__codelineno-31-27"></a><span class="w"> </span><span class="nx">setResponses</span><span class="p">(</span><span class="nx">prev</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">prev</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">r</span><span class="w"> </span><span class="p">=&gt;</span>
</span><span id="__span-31-28"><a id="__codelineno-31-28" name="__codelineno-31-28" href="#__codelineno-31-28"></a><span class="w"> </span><span class="nx">r</span><span class="p">.</span><span class="nx">id</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">responseId</span>
</span><span id="__span-31-29"><a id="__codelineno-31-29" name="__codelineno-31-29" href="#__codelineno-31-29"></a><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-30"><a id="__codelineno-31-30" name="__codelineno-31-30" href="#__codelineno-31-30"></a><span class="w"> </span><span class="p">...</span><span class="nx">r</span><span class="p">,</span>
</span><span id="__span-31-31"><a id="__codelineno-31-31" name="__codelineno-31-31" href="#__codelineno-31-31"></a><span class="w"> </span><span class="nx">upvoteCount</span><span class="o">:</span><span class="w"> </span><span class="kt">response.data.upvoteCount</span><span class="p">,</span>
</span><span id="__span-31-32"><a id="__codelineno-31-32" name="__codelineno-31-32" href="#__codelineno-31-32"></a><span class="w"> </span><span class="nx">hasUpvoted</span><span class="o">:</span><span class="w"> </span><span class="kt">response.data.action</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">&#39;added&#39;</span>
</span><span id="__span-31-33"><a id="__codelineno-31-33" name="__codelineno-31-33" href="#__codelineno-31-33"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-31-34"><a id="__codelineno-31-34" name="__codelineno-31-34" href="#__codelineno-31-34"></a><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="nx">r</span>
</span><span id="__span-31-35"><a id="__codelineno-31-35" name="__codelineno-31-35" href="#__codelineno-31-35"></a><span class="w"> </span><span class="p">));</span>
</span><span id="__span-31-36"><a id="__codelineno-31-36" name="__codelineno-31-36" href="#__codelineno-31-36"></a>
</span><span id="__span-31-37"><a id="__codelineno-31-37" name="__codelineno-31-37" href="#__codelineno-31-37"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-38"><a id="__codelineno-31-38" name="__codelineno-31-38" href="#__codelineno-31-38"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Upvote failed:&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">error</span><span class="p">);</span>
</span><span id="__span-31-39"><a id="__codelineno-31-39" name="__codelineno-31-39" href="#__codelineno-31-39"></a>
</span><span id="__span-31-40"><a id="__codelineno-31-40" name="__codelineno-31-40" href="#__codelineno-31-40"></a><span class="w"> </span><span class="c1">// Revert to previous state</span>
</span><span id="__span-31-41"><a id="__codelineno-31-41" name="__codelineno-31-41" href="#__codelineno-31-41"></a><span class="w"> </span><span class="nx">setResponses</span><span class="p">(</span><span class="nx">previousResponses</span><span class="p">);</span>
</span><span id="__span-31-42"><a id="__codelineno-31-42" name="__codelineno-31-42" href="#__codelineno-31-42"></a>
</span><span id="__span-31-43"><a id="__codelineno-31-43" name="__codelineno-31-43" href="#__codelineno-31-43"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">&#39;ECONNABORTED&#39;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-44"><a id="__codelineno-31-44" name="__codelineno-31-44" href="#__codelineno-31-44"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Request timed out. Please try again.&#39;</span><span class="p">);</span>
</span><span id="__span-31-45"><a id="__codelineno-31-45" name="__codelineno-31-45" href="#__codelineno-31-45"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-31-46"><a id="__codelineno-31-46" name="__codelineno-31-46" href="#__codelineno-31-46"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Failed to upvote. Please try again.&#39;</span><span class="p">);</span>
</span><span id="__span-31-47"><a id="__codelineno-31-47" name="__codelineno-31-47" href="#__codelineno-31-47"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-31-48"><a id="__codelineno-31-48" name="__codelineno-31-48" href="#__codelineno-31-48"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-31-49"><a id="__codelineno-31-49" name="__codelineno-31-49" href="#__codelineno-31-49"></a><span class="p">};</span>
</span></code></pre></div>
<p><strong>Check backend upvote tracking:</strong>
<div class="language-sql highlight"><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="c1">-- Verify upvote records created</span>
</span><span id="__span-32-2"><a id="__codelineno-32-2" name="__codelineno-32-2" href="#__codelineno-32-2"></a><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="ss">&quot;ResponseUpvote&quot;</span>
</span><span id="__span-32-3"><a id="__codelineno-32-3" name="__codelineno-32-3" href="#__codelineno-32-3"></a><span class="k">WHERE</span><span class="w"> </span><span class="ss">&quot;responseId&quot;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;cm2abc123&#39;</span>
</span><span id="__span-32-4"><a id="__codelineno-32-4" name="__codelineno-32-4" href="#__codelineno-32-4"></a><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="ss">&quot;createdAt&quot;</span><span class="w"> </span><span class="k">DESC</span><span class="p">;</span>
</span></code></pre></div></p>
<h3 id="issue-statistics-not-updating-after-submission">Issue: Statistics Not Updating After Submission<a class="headerlink" href="#issue-statistics-not-updating-after-submission" title="Permanent link">&para;</a></h3>
<p><strong>Symptoms:</strong>
- User submits response
- Response appears in list
- Statistics cards show old counts</p>
<p><strong>Causes:</strong>
1. Stats fetched once on mount, never refreshed
2. New response not included in stats query
3. Cache invalidation not working</p>
<p><strong>Solutions:</strong></p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="c1">// Refetch stats after successful submission</span>
</span><span id="__span-33-2"><a id="__codelineno-33-2" name="__codelineno-33-2" href="#__codelineno-33-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">handleSubmit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">(</span><span class="nx">values</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-33-3"><a id="__codelineno-33-3" name="__codelineno-33-3" href="#__codelineno-33-3"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-33-4"><a id="__codelineno-33-4" name="__codelineno-33-4" href="#__codelineno-33-4"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">&#39;/api/public/responses&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">});</span>
</span><span id="__span-33-5"><a id="__codelineno-33-5" name="__codelineno-33-5" href="#__codelineno-33-5"></a>
</span><span id="__span-33-6"><a id="__codelineno-33-6" name="__codelineno-33-6" href="#__codelineno-33-6"></a><span class="w"> </span><span class="nx">Modal</span><span class="p">.</span><span class="nx">success</span><span class="p">({</span>
</span><span id="__span-33-7"><a id="__codelineno-33-7" name="__codelineno-33-7" href="#__codelineno-33-7"></a><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Response Submitted!&#39;</span><span class="p">,</span>
</span><span id="__span-33-8"><a id="__codelineno-33-8" name="__codelineno-33-8" href="#__codelineno-33-8"></a><span class="w"> </span><span class="nx">content</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;Please check your email to verify your response.&#39;</span><span class="p">,</span>
</span><span id="__span-33-9"><a id="__codelineno-33-9" name="__codelineno-33-9" href="#__codelineno-33-9"></a><span class="w"> </span><span class="p">});</span>
</span><span id="__span-33-10"><a id="__codelineno-33-10" name="__codelineno-33-10" href="#__codelineno-33-10"></a>
</span><span id="__span-33-11"><a id="__codelineno-33-11" name="__codelineno-33-11" href="#__codelineno-33-11"></a><span class="w"> </span><span class="nx">setSubmitModalVisible</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span id="__span-33-12"><a id="__codelineno-33-12" name="__codelineno-33-12" href="#__codelineno-33-12"></a><span class="w"> </span><span class="nx">form</span><span class="p">.</span><span class="nx">resetFields</span><span class="p">();</span>
</span><span id="__span-33-13"><a id="__codelineno-33-13" name="__codelineno-33-13" href="#__codelineno-33-13"></a>
</span><span id="__span-33-14"><a id="__codelineno-33-14" name="__codelineno-33-14" href="#__codelineno-33-14"></a><span class="w"> </span><span class="c1">// Refresh all data</span>
</span><span id="__span-33-15"><a id="__codelineno-33-15" name="__codelineno-33-15" href="#__codelineno-33-15"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">statsRes</span><span class="p">,</span><span class="w"> </span><span class="nx">responsesRes</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span>
</span><span id="__span-33-16"><a id="__codelineno-33-16" name="__codelineno-33-16" href="#__codelineno-33-16"></a><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sb">`/api/public/responses/campaigns/</span><span class="si">${</span><span class="nx">campaignId</span><span class="si">}</span><span class="sb">/stats`</span><span class="p">),</span>
</span><span id="__span-33-17"><a id="__codelineno-33-17" name="__codelineno-33-17" href="#__codelineno-33-17"></a><span class="w"> </span><span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sb">`/api/public/responses/campaigns/</span><span class="si">${</span><span class="nx">campaignId</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-33-18"><a id="__codelineno-33-18" name="__codelineno-33-18" href="#__codelineno-33-18"></a><span class="w"> </span><span class="nx">params</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">page</span><span class="o">:</span><span class="w"> </span><span class="kt">1</span><span class="p">,</span><span class="w"> </span><span class="nx">limit</span><span class="o">:</span><span class="w"> </span><span class="kt">pageSize</span><span class="p">,</span><span class="w"> </span><span class="nx">sortBy</span><span class="p">,</span><span class="w"> </span><span class="nx">governmentLevel</span><span class="w"> </span><span class="p">}</span>
</span><span id="__span-33-19"><a id="__codelineno-33-19" name="__codelineno-33-19" href="#__codelineno-33-19"></a><span class="w"> </span><span class="p">})</span>
</span><span id="__span-33-20"><a id="__codelineno-33-20" name="__codelineno-33-20" href="#__codelineno-33-20"></a><span class="w"> </span><span class="p">]);</span>
</span><span id="__span-33-21"><a id="__codelineno-33-21" name="__codelineno-33-21" href="#__codelineno-33-21"></a>
</span><span id="__span-33-22"><a id="__codelineno-33-22" name="__codelineno-33-22" href="#__codelineno-33-22"></a><span class="w"> </span><span class="nx">setStats</span><span class="p">(</span><span class="nx">statsRes</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
</span><span id="__span-33-23"><a id="__codelineno-33-23" name="__codelineno-33-23" href="#__codelineno-33-23"></a><span class="w"> </span><span class="nx">setResponses</span><span class="p">(</span><span class="nx">responsesRes</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">responses</span><span class="p">);</span>
</span><span id="__span-33-24"><a id="__codelineno-33-24" name="__codelineno-33-24" href="#__codelineno-33-24"></a><span class="w"> </span><span class="nx">setTotal</span><span class="p">(</span><span class="nx">responsesRes</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">total</span><span class="p">);</span>
</span><span id="__span-33-25"><a id="__codelineno-33-25" name="__codelineno-33-25" href="#__codelineno-33-25"></a><span class="w"> </span><span class="nx">setPage</span><span class="p">(</span><span class="mf">1</span><span class="p">);</span><span class="w"> </span><span class="c1">// Reset to first page</span>
</span><span id="__span-33-26"><a id="__codelineno-33-26" name="__codelineno-33-26" href="#__codelineno-33-26"></a>
</span><span id="__span-33-27"><a id="__codelineno-33-27" name="__codelineno-33-27" href="#__codelineno-33-27"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-33-28"><a id="__codelineno-33-28" name="__codelineno-33-28" href="#__codelineno-33-28"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="o">?</span><span class="p">.</span><span class="nx">data</span><span class="o">?</span><span class="p">.</span><span class="nx">message</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s1">&#39;Failed to submit response&#39;</span><span class="p">);</span>
</span><span id="__span-33-29"><a id="__codelineno-33-29" name="__codelineno-33-29" href="#__codelineno-33-29"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-33-30"><a id="__codelineno-33-30" name="__codelineno-33-30" href="#__codelineno-33-30"></a><span class="p">};</span>
</span></code></pre></div>
<h3 id="issue-verified-only-filter-shows-no-results">Issue: "Verified Only" Filter Shows No Results<a class="headerlink" href="#issue-verified-only-filter-shows-no-results" title="Permanent link">&para;</a></h3>
<p><strong>Symptoms:</strong>
- User selects "Verified Only" sort
- Grid shows empty state
- Total count remains high</p>
<p><strong>Causes:</strong>
1. No verified responses exist yet
2. API not filtering correctly
3. Frontend not passing correct param</p>
<p><strong>Solutions:</strong></p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="c1">// Add empty state for no verified responses</span>
</span><span id="__span-34-2"><a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a><span class="p">{</span><span class="o">!</span><span class="nx">loading</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">responses</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">sortBy</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s1">&#39;verified&#39;</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span>
</span><span id="__span-34-3"><a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Card</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">textAlign</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;center&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">padding</span><span class="o">:</span><span class="w"> </span><span class="kt">40</span><span class="w"> </span><span class="p">}}&gt;</span>
</span><span id="__span-34-4"><a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">CheckCircleOutlined</span><span class="w"> </span><span class="na">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">fontSize</span><span class="o">:</span><span class="w"> </span><span class="kt">64</span><span class="p">,</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;#999&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">16</span><span class="w"> </span><span class="p">}}</span><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-34-5"><a id="__codelineno-34-5" name="__codelineno-34-5" href="#__codelineno-34-5"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Title</span><span class="w"> </span><span class="na">level</span><span class="o">=</span><span class="p">{</span><span class="mf">3</span><span class="p">}</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span><span class="p">&gt;</span>
</span><span id="__span-34-6"><a id="__codelineno-34-6" name="__codelineno-34-6" href="#__codelineno-34-6"></a><span class="w"> </span><span class="nx">No</span><span class="w"> </span><span class="nx">Verified</span><span class="w"> </span><span class="nx">Responses</span><span class="w"> </span><span class="nx">Yet</span>
</span><span id="__span-34-7"><a id="__codelineno-34-7" name="__codelineno-34-7" href="#__codelineno-34-7"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Title</span><span class="p">&gt;</span>
</span><span id="__span-34-8"><a id="__codelineno-34-8" name="__codelineno-34-8" href="#__codelineno-34-8"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Paragraph</span><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;secondary&quot;</span><span class="p">&gt;</span>
</span><span id="__span-34-9"><a id="__codelineno-34-9" name="__codelineno-34-9" href="#__codelineno-34-9"></a><span class="w"> </span><span class="nx">Responses</span><span class="w"> </span><span class="nx">appear</span><span class="w"> </span><span class="nx">here</span><span class="w"> </span><span class="nx">after</span><span class="w"> </span><span class="nx">users</span><span class="w"> </span><span class="nx">verify</span><span class="w"> </span><span class="nx">their</span><span class="w"> </span><span class="nx">email</span><span class="w"> </span><span class="nx">address</span><span class="p">.</span>
</span><span id="__span-34-10"><a id="__codelineno-34-10" name="__codelineno-34-10" href="#__codelineno-34-10"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">br</span><span class="w"> </span><span class="p">/&gt;</span>
</span><span id="__span-34-11"><a id="__codelineno-34-11" name="__codelineno-34-11" href="#__codelineno-34-11"></a><span class="w"> </span><span class="nx">Try</span><span class="w"> </span><span class="nx">selecting</span><span class="w"> </span><span class="s2">&quot;Recent&quot;</span><span class="w"> </span><span class="nx">or</span><span class="w"> </span><span class="s2">&quot;Most Upvoted&quot;</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">see</span><span class="w"> </span><span class="nx">all</span><span class="w"> </span><span class="nx">responses</span><span class="p">.</span>
</span><span id="__span-34-12"><a id="__codelineno-34-12" name="__codelineno-34-12" href="#__codelineno-34-12"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Paragraph</span><span class="p">&gt;</span>
</span><span id="__span-34-13"><a id="__codelineno-34-13" name="__codelineno-34-13" href="#__codelineno-34-13"></a><span class="w"> </span><span class="p">&lt;</span><span class="nt">Button</span>
</span><span id="__span-34-14"><a id="__codelineno-34-14" name="__codelineno-34-14" href="#__codelineno-34-14"></a><span class="w"> </span><span class="na">type</span><span class="o">=</span><span class="s">&quot;primary&quot;</span>
</span><span id="__span-34-15"><a id="__codelineno-34-15" name="__codelineno-34-15" href="#__codelineno-34-15"></a><span class="w"> </span><span class="na">onClick</span><span class="o">=</span><span class="p">{()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">setSortBy</span><span class="p">(</span><span class="s1">&#39;recent&#39;</span><span class="p">)}</span>
</span><span id="__span-34-16"><a id="__codelineno-34-16" name="__codelineno-34-16" href="#__codelineno-34-16"></a><span class="w"> </span><span class="p">&gt;</span>
</span><span id="__span-34-17"><a id="__codelineno-34-17" name="__codelineno-34-17" href="#__codelineno-34-17"></a><span class="w"> </span><span class="nx">View</span><span class="w"> </span><span class="nx">All</span><span class="w"> </span><span class="nx">Responses</span>
</span><span id="__span-34-18"><a id="__codelineno-34-18" name="__codelineno-34-18" href="#__codelineno-34-18"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Button</span><span class="p">&gt;</span>
</span><span id="__span-34-19"><a id="__codelineno-34-19" name="__codelineno-34-19" href="#__codelineno-34-19"></a><span class="w"> </span><span class="p">&lt;/</span><span class="nt">Card</span><span class="p">&gt;</span>
</span><span id="__span-34-20"><a id="__codelineno-34-20" name="__codelineno-34-20" href="#__codelineno-34-20"></a><span class="p">)}</span>
</span><span id="__span-34-21"><a id="__codelineno-34-21" name="__codelineno-34-21" href="#__codelineno-34-21"></a>
</span><span id="__span-34-22"><a id="__codelineno-34-22" name="__codelineno-34-22" href="#__codelineno-34-22"></a><span class="c1">// Verify API param correctly passed</span>
</span><span id="__span-34-23"><a id="__codelineno-34-23" name="__codelineno-34-23" href="#__codelineno-34-23"></a><span class="nx">useEffect</span><span class="p">(()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-34-24"><a id="__codelineno-34-24" name="__codelineno-34-24" href="#__codelineno-34-24"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Fetching with params:&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-34-25"><a id="__codelineno-34-25" name="__codelineno-34-25" href="#__codelineno-34-25"></a><span class="w"> </span><span class="nx">page</span><span class="p">,</span>
</span><span id="__span-34-26"><a id="__codelineno-34-26" name="__codelineno-34-26" href="#__codelineno-34-26"></a><span class="w"> </span><span class="nx">limit</span><span class="o">:</span><span class="w"> </span><span class="kt">pageSize</span><span class="p">,</span>
</span><span id="__span-34-27"><a id="__codelineno-34-27" name="__codelineno-34-27" href="#__codelineno-34-27"></a><span class="w"> </span><span class="nx">sortBy</span><span class="p">,</span>
</span><span id="__span-34-28"><a id="__codelineno-34-28" name="__codelineno-34-28" href="#__codelineno-34-28"></a><span class="w"> </span><span class="nx">governmentLevel</span>
</span><span id="__span-34-29"><a id="__codelineno-34-29" name="__codelineno-34-29" href="#__codelineno-34-29"></a><span class="w"> </span><span class="p">});</span>
</span><span id="__span-34-30"><a id="__codelineno-34-30" name="__codelineno-34-30" href="#__codelineno-34-30"></a><span class="p">},</span><span class="w"> </span><span class="p">[</span><span class="nx">page</span><span class="p">,</span><span class="w"> </span><span class="nx">sortBy</span><span class="p">,</span><span class="w"> </span><span class="nx">governmentLevel</span><span class="p">]);</span>
</span></code></pre></div>
<p><strong>Check backend:</strong>
<div class="language-sql highlight"><pre><span></span><code><span id="__span-35-1"><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a><span class="c1">-- Count verified vs unverified</span>
</span><span id="__span-35-2"><a id="__codelineno-35-2" name="__codelineno-35-2" href="#__codelineno-35-2"></a><span class="k">SELECT</span><span class="w"> </span><span class="ss">&quot;isVerified&quot;</span><span class="p">,</span><span class="w"> </span><span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
</span><span id="__span-35-3"><a id="__codelineno-35-3" name="__codelineno-35-3" href="#__codelineno-35-3"></a><span class="k">FROM</span><span class="w"> </span><span class="ss">&quot;Response&quot;</span>
</span><span id="__span-35-4"><a id="__codelineno-35-4" name="__codelineno-35-4" href="#__codelineno-35-4"></a><span class="k">WHERE</span><span class="w"> </span><span class="ss">&quot;campaignId&quot;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;cm1abc123&#39;</span>
</span><span id="__span-35-5"><a id="__codelineno-35-5" name="__codelineno-35-5" href="#__codelineno-35-5"></a><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="ss">&quot;isVerified&quot;</span><span class="p">;</span>
</span></code></pre></div></p>
<h3 id="issue-pagination-showing-wrong-total">Issue: Pagination Showing Wrong Total<a class="headerlink" href="#issue-pagination-showing-wrong-total" title="Permanent link">&para;</a></h3>
<p><strong>Symptoms:</strong>
- Pagination shows "1-20 of 342"
- Only 50 total responses exist
- Total count doesn't match stats card</p>
<p><strong>Causes:</strong>
1. Stats query counting all campaigns
2. Responses query filtering by campaign correctly
3. Stats API endpoint broken</p>
<p><strong>Solutions:</strong></p>
<div class="language-tsx highlight"><pre><span></span><code><span id="__span-36-1"><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a><span class="c1">// Use responses total, not stats total, for pagination</span>
</span><span id="__span-36-2"><a id="__codelineno-36-2" name="__codelineno-36-2" href="#__codelineno-36-2"></a><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">responsesTotal</span><span class="p">,</span><span class="w"> </span><span class="nx">setResponsesTotal</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="mf">0</span><span class="p">);</span>
</span><span id="__span-36-3"><a id="__codelineno-36-3" name="__codelineno-36-3" href="#__codelineno-36-3"></a>
</span><span id="__span-36-4"><a id="__codelineno-36-4" name="__codelineno-36-4" href="#__codelineno-36-4"></a><span class="c1">// In fetch responses:</span>
</span><span id="__span-36-5"><a id="__codelineno-36-5" name="__codelineno-36-5" href="#__codelineno-36-5"></a><span class="nx">setResponsesTotal</span><span class="p">(</span><span class="nx">responsesRes</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">total</span><span class="p">);</span>
</span><span id="__span-36-6"><a id="__codelineno-36-6" name="__codelineno-36-6" href="#__codelineno-36-6"></a>
</span><span id="__span-36-7"><a id="__codelineno-36-7" name="__codelineno-36-7" href="#__codelineno-36-7"></a><span class="c1">// In pagination:</span>
</span><span id="__span-36-8"><a id="__codelineno-36-8" name="__codelineno-36-8" href="#__codelineno-36-8"></a><span class="p">&lt;</span><span class="nt">Pagination</span>
</span><span id="__span-36-9"><a id="__codelineno-36-9" name="__codelineno-36-9" href="#__codelineno-36-9"></a><span class="w"> </span><span class="na">current</span><span class="o">=</span><span class="p">{</span><span class="nx">page</span><span class="p">}</span>
</span><span id="__span-36-10"><a id="__codelineno-36-10" name="__codelineno-36-10" href="#__codelineno-36-10"></a><span class="w"> </span><span class="na">total</span><span class="o">=</span><span class="p">{</span><span class="nx">responsesTotal</span><span class="p">}</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="na">Not</span><span class="w"> </span><span class="na">stats.totalResponses</span>
</span><span id="__span-36-11"><a id="__codelineno-36-11" name="__codelineno-36-11" href="#__codelineno-36-11"></a><span class="w"> </span><span class="na">pageSize</span><span class="o">=</span><span class="p">{</span><span class="nx">pageSize</span><span class="p">}</span>
</span><span id="__span-36-12"><a id="__codelineno-36-12" name="__codelineno-36-12" href="#__codelineno-36-12"></a><span class="w"> </span><span class="na">onChange</span><span class="o">=</span><span class="p">{</span><span class="nx">setPage</span><span class="p">}</span>
</span><span id="__span-36-13"><a id="__codelineno-36-13" name="__codelineno-36-13" href="#__codelineno-36-13"></a><span class="p">/&gt;</span>
</span><span id="__span-36-14"><a id="__codelineno-36-14" name="__codelineno-36-14" href="#__codelineno-36-14"></a>
</span><span id="__span-36-15"><a id="__codelineno-36-15" name="__codelineno-36-15" href="#__codelineno-36-15"></a><span class="c1">// Add validation</span>
</span><span id="__span-36-16"><a id="__codelineno-36-16" name="__codelineno-36-16" href="#__codelineno-36-16"></a><span class="nx">useEffect</span><span class="p">(()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-36-17"><a id="__codelineno-36-17" name="__codelineno-36-17" href="#__codelineno-36-17"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">stats</span><span class="p">.</span><span class="nx">totalResponses</span><span class="w"> </span><span class="o">!==</span><span class="w"> </span><span class="nx">responsesTotal</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-36-18"><a id="__codelineno-36-18" name="__codelineno-36-18" href="#__codelineno-36-18"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span><span class="s1">&#39;Mismatch between stats and pagination totals:&#39;</span><span class="p">,</span><span class="w"> </span><span class="p">{</span>
</span><span id="__span-36-19"><a id="__codelineno-36-19" name="__codelineno-36-19" href="#__codelineno-36-19"></a><span class="w"> </span><span class="nx">stats</span><span class="o">:</span><span class="w"> </span><span class="kt">stats.totalResponses</span><span class="p">,</span>
</span><span id="__span-36-20"><a id="__codelineno-36-20" name="__codelineno-36-20" href="#__codelineno-36-20"></a><span class="w"> </span><span class="nx">pagination</span><span class="o">:</span><span class="w"> </span><span class="kt">responsesTotal</span>
</span><span id="__span-36-21"><a id="__codelineno-36-21" name="__codelineno-36-21" href="#__codelineno-36-21"></a><span class="w"> </span><span class="p">});</span>
</span><span id="__span-36-22"><a id="__codelineno-36-22" name="__codelineno-36-22" href="#__codelineno-36-22"></a><span class="w"> </span><span class="p">}</span>
</span><span id="__span-36-23"><a id="__codelineno-36-23" name="__codelineno-36-23" href="#__codelineno-36-23"></a><span class="p">},</span><span class="w"> </span><span class="p">[</span><span class="nx">stats</span><span class="p">.</span><span class="nx">totalResponses</span><span class="p">,</span><span class="w"> </span><span class="nx">responsesTotal</span><span class="p">]);</span>
</span></code></pre></div>
<hr />
<h2 id="related-documentation">Related Documentation<a class="headerlink" href="#related-documentation" title="Permanent link">&para;</a></h2>
<h3 id="public-pages">Public Pages<a class="headerlink" href="#public-pages" title="Permanent link">&para;</a></h3>
<ul>
<li><a href="../campaigns-list-page/">Campaigns List Page</a> - Campaign directory</li>
<li><a href="../campaign-page/">Campaign Detail Page</a> - Email sending workflow</li>
<li><a href="../map-page/">Map Page</a> - Public location mapping</li>
</ul>
<h3 id="admin-pages">Admin Pages<a class="headerlink" href="#admin-pages" title="Permanent link">&para;</a></h3>
<ul>
<li><a href="../../admin/responses-page/">Response Moderation</a> - Admin moderation tools</li>
<li><a href="../../admin/campaigns-page/">Campaigns Management</a> - Campaign configuration</li>
</ul>
<h3 id="components">Components<a class="headerlink" href="#components" title="Permanent link">&para;</a></h3>
<ul>
<li><a href="../../components/public-layout.md">PublicLayout</a> - Dark theme wrapper</li>
<li><a href="../../components/share-buttons.md">ShareButtons</a> - Social sharing</li>
</ul>
<h3 id="api-documentation">API Documentation<a class="headerlink" href="#api-documentation" title="Permanent link">&para;</a></h3>
<ul>
<li><a href="../../../api/modules/influence/responses-public-routes.md">Public Responses API</a></li>
<li><a href="../../../api/modules/influence/responses-upvote.md">Response Upvoting</a></li>
</ul>
<h3 id="architecture">Architecture<a class="headerlink" href="#architecture" title="Permanent link">&para;</a></h3>
<ul>
<li><a href="../../../architecture/response-verification.md">Response Verification System</a></li>
<li><a href="../../../architecture/email-templates.md">Email Templates</a></li>
</ul>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../campaign-page/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Campaign Detail">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Campaign Detail
</div>
</div>
</a>
<a href="../map-page/" class="md-footer__link md-footer__link--next" aria-label="Next: Map">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Map
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 The Bunker Operations <a href="#__consent">Change cookie settings</a>
</div>
</div>
<div class="md-social">
<a href="https://gitea.bnkops.com/admin" target="_blank" rel="noopener" title="Gitea Repository" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</a>
<a href="https://listmonk.bnkops.com/subscription/form" target="_blank" rel="noopener" title="Newsletter" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M536.4-26.3c9.8-3.5 20.6-1 28 6.3s9.8 18.2 6.3 28l-178 496.9c-5 13.9-18.1 23.1-32.8 23.1-14.2 0-27-8.6-32.3-21.7l-64.2-158c-4.5-11-2.5-23.6 5.2-32.6l94.5-112.4c5.1-6.1 4.7-15-.9-20.6s-14.6-6-20.6-.9l-112.4 94.3c-9.1 7.6-21.6 9.6-32.6 5.2L38.1 216.8c-13.1-5.3-21.7-18.1-21.7-32.3 0-14.7 9.2-27.8 23.1-32.8z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "../../../../..", "features": ["announce.dismiss", "content.action.edit", "content.action.view", "content.code.annotate", "content.code.copy", "content.tooltips", "navigation.expand", "navigation.footer", "navigation.indexes", "navigation.path", "navigation.prune", "navigation.sections", "navigation.tabs", "navigation.tabs.sticky", "navigation.top", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../../../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../../../../javascripts/home.js"></script>
<script src="../../../../../javascripts/github-widget.js"></script>
<script src="../../../../../javascripts/gitea-widget.js"></script>
<script src="../../../../../assets/js/env-config.js"></script>
<script src="../../../../../assets/js/video-player.js"></script>
</body>
</html>