Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b4e2315
the table view
BGL-PV Aug 4, 2026
41920af
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 1, 2026
4e1ad24
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 2, 2026
9136627
implementing the api data
BGL-PV Sep 5, 2026
71d54c8
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 5, 2026
f89e027
implmenting edit mode
BGL-PV Sep 6, 2026
37d4a3e
abstracting
BGL-PV Sep 6, 2026
13f970e
performance optimizations
BGL-PV Sep 7, 2026
2d45b64
adding matching functionality
BGL-PV Sep 7, 2026
d4e121e
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 9, 2026
14dc455
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 10, 2026
2115b17
updating to use new contract
BGL-PV Sep 10, 2026
af16b99
Fixing account page
BGL-PV Sep 10, 2026
1965159
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 13, 2026
c1e9a83
membership panel implementation
BGL-PV Sep 13, 2026
d88e3cc
update use fetch
BGL-PV Sep 13, 2026
d5d200d
removing dumb comments t to remind me to do stuff i dont want to add now
BGL-PV Sep 13, 2026
4498cf6
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 15, 2026
50d0897
moving membership moved to volunteer dashboard
BGL-PV Sep 16, 2026
657bb59
d
BGL-PV Sep 16, 2026
5148956
table description
BGL-PV Sep 16, 2026
5e99956
better naming scheme for example
BGL-PV Sep 16, 2026
061476a
removing expirement
BGL-PV Sep 16, 2026
6ac792c
lint
BGL-PV Sep 16, 2026
712b3f6
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 17, 2026
221ea43
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 17, 2026
b80c8c5
implementing shit
BGL-PV Sep 17, 2026
20dfc67
push
BGL-PV Sep 17, 2026
341335d
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 17, 2026
40605de
update
BGL-PV Sep 17, 2026
dfcbf85
additional fixes
BGL-PV Sep 18, 2026
d16b4c6
implmenting a ton of new shit
BGL-PV Sep 18, 2026
3f69e63
lint
BGL-PV Sep 18, 2026
e0abaf7
Merge branch 'dev' into membership-card-panel
BGL-PV Sep 19, 2026
c9ba98e
implementing the depricated admin panel
BGL-PV Sep 19, 2026
124d620
bito that took forever
BGL-PV Sep 19, 2026
bb5887c
bito
BGL-PV Sep 19, 2026
04c2472
dot separator no longer utf8
zoe2276 Sep 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/app/account/account.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@
display: flex;
flex-flow: column nowrap;
align-items: stretch;
overflow-x: auto;

padding: 0 1rem 1rem 1rem;
}
Expand Down
100 changes: 45 additions & 55 deletions src/app/account/sections/AccountContributionsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import styles from '@/app/account/account.module.css'
import formStyles from '@/components/common/forms/Form.module.css'
import formFieldStyles from '@/components/common/forms/FormField.module.css'
import { Table, Column } from '@/components/common/table'
import { cn } from '@/util'
import { ActBlueContribution, User } from 'pv-contracts/data'
import React, { ChangeEvent, useState } from 'react'
Expand Down Expand Up @@ -62,64 +63,53 @@ const getRecurrenceType = (
: 'monthly'
}

type ContributionLineitem = ContributionsTableProps['lineitems'][number]

const contributionColumns: Column<ContributionLineitem>[] = [
{
key: 'recurring',
header: 'Recurring',
width: '8.5rem',
render: (row) => (
<RecurrenceTag type={getRecurrenceType(row.contribution)} />
),
},
{
key: 'form',
header: 'Contribution Form',
render: (row) =>
formatContributionForm(row.contribution.contributionForm),
},
{
key: 'orderNumber',
header: 'Order Number',
width: '9rem',
render: (row) => row.contribution.orderNumber,
},
{
key: 'amount',
header: 'Amount',
width: '7rem',
render: (row) => `$${row.amount.toFixed(2)}`,
},
{
key: 'date',
header: 'Date',
width: '11rem',
render: (row) => row.paidAt.toLocaleDateString(),
},
]

const ContributionsTable = ({ lineitems }: ContributionsTableProps) => {
return (
<div className={styles.contributionsTableContainer}>
<div className={styles.contributionsList}>
<div className={styles.contributionsListHeader}>
<span>Recurring</span>
<span>Contribution Form</span>
<span>Order Number</span>
<span>Amount</span>
<span>Date</span>
</div>

{lineitems.map(
({ contribution, lineitemId, amount, paidAt }) => {
return (
<div
key={`${contribution.uniqueIdentifier}-${lineitemId}`}
className={styles.contributionsListRow}
>
<span
className={styles.contributionsListCell}
data-label="Recurring"
>
<RecurrenceTag
type={getRecurrenceType(contribution)}
/>
</span>
<span
className={styles.contributionsListCell}
data-label="Contribution Form"
>
{formatContributionForm(
contribution.contributionForm
)}
</span>
<span
className={styles.contributionsListCell}
data-label="Order Number"
>
{contribution.orderNumber}
</span>
<span
className={styles.contributionsListCell}
data-label="Amount"
>
${amount.toFixed(2)}
</span>
<span
className={styles.contributionsListCell}
data-label="Date"
>
{paidAt.toLocaleDateString()}
</span>
</div>
)
}
)}
</div>
<Table
columns={contributionColumns}
data={lineitems}
rowKey={(row) =>
`${row.contribution.uniqueIdentifier}-${row.lineitemId}`
}
/>
</div>
)
}
Expand Down
13 changes: 7 additions & 6 deletions src/app/account/sections/AccountDetailsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,13 @@ export function AccountDetailsSection({
MembershipDeliverableStatus,
string
> = {
[MembershipDeliverableStatus.NotEligible]: 'Not Eligible',
[MembershipDeliverableStatus.NotStarted]: 'Not Started',
[MembershipDeliverableStatus.Printed]: 'Printed',
[MembershipDeliverableStatus.InTransit]: 'In Transit',
[MembershipDeliverableStatus.Recieved]: 'Received',
[MembershipDeliverableStatus.Returned]: 'Returned (Update Address)',
[MembershipDeliverableStatus.NotEligible]: 'Requested To Cancel',
[MembershipDeliverableStatus.NotStarted]: 'Not Shipped Yet',
[MembershipDeliverableStatus.Printed]: 'Not Shipped Yet',
[MembershipDeliverableStatus.InTransit]:
Comment thread
BGL-PV marked this conversation as resolved.
'Delivery Failed - Fix Address',
[MembershipDeliverableStatus.Recieved]: 'Card Shipped',
[MembershipDeliverableStatus.Returned]: 'Delivery Failed - Fix Address',
}

const normalizeEmail = (value?: string | null) =>
Expand Down
4 changes: 2 additions & 2 deletions src/app/endorsements/components/FilterButtonRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
type SectionGroupingMode,
type SectionSortOrder,
} from '../endorsements.types'
import { cn } from '@/util'
import { cn, DOT_SEPARATOR } from '@/util'
import { AnimatePresence, LayoutGroup, motion } from 'motion/react'
import {
type FocusEvent,
Expand Down Expand Up @@ -839,7 +839,7 @@ function TagsDropdownGroup<T extends string>({
? getOptionLabel(requiredSection.options, requiredSection.value)
: null
const selectedLabel = selectedRequiredLabel
? `${selectedTagLabel} · ${selectedRequiredLabel}`
? `${selectedTagLabel} ${DOT_SEPARATOR} ${selectedRequiredLabel}`
: selectedTagLabel

const handleRequiredSectionPress = (optionValue: string) => {
Expand Down
4 changes: 3 additions & 1 deletion src/app/volunteer_dashboard/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface VolunteerDashboardUnselectedDetailProps {
userCount?: number
donorCount?: number
contributionCount?: number
membershipCount?: number
roleCount?: number
permissionCount?: number
positionCount?: number
Expand All @@ -49,6 +50,7 @@ export function renderVolunteerDashboardUnselectedDetail({
userCount,
donorCount,
contributionCount,
membershipCount,
roleCount,
permissionCount,
positionCount,
Expand Down Expand Up @@ -130,7 +132,7 @@ export function renderVolunteerDashboardUnselectedDetail({
description="Dues Paying Membership switchboard."
href="/volunteer_dashboard/panels/membership"
icon={FaMoneyCheckDollar}
tag={{ count: 92 }}
tag={{ count: membershipCount }}
buttonType="card"
resetPanelHistoryOnClick
/>
Expand Down
15 changes: 14 additions & 1 deletion src/app/volunteer_dashboard/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
zRole,
zUser,
} from 'pv-contracts/data'
import { MembershipSearchRequest } from 'pv-contracts/requests'
import { zMembershipsResponsePacket } from 'pv-contracts/responses'
import { Suspense, useEffect, useRef, useState } from 'react'
import type { ReactNode } from 'react'
import { FaDonate, FaUserShield, FaUserTag, FaUsers } from 'react-icons/fa'
Expand Down Expand Up @@ -51,6 +53,11 @@ interface DashboardPanelConfigItem {
groupChildren?: DashboardGroupChildConfigItem[]
}

const membershipCountSearch: MembershipSearchRequest = {
limit: 1,
isMember: true,
}

export default function Layout({ children }: { children: ReactNode }) {
return (
<Suspense fallback={null}>
Expand Down Expand Up @@ -83,6 +90,11 @@ function LayoutContent({ children }: { children: ReactNode }) {
zActBlueDonationPacket,
{ search: { limit: 0 } }
)
const memberships = usePaginatedSearch(
'/actblue/memberships',
zMembershipsResponsePacket,
{ search: membershipCountSearch }
)
const positionHierarchy = useQuery({
queryKey: ['positionHierarchy'],
queryFn: positionQueries.getPositionHierarchy,
Expand Down Expand Up @@ -137,7 +149,7 @@ function LayoutContent({ children }: { children: ReactNode }) {
label: 'Membership',
href: '/volunteer_dashboard/panels/membership',
icon: FaMoneyCheckDollar,
// count: insert,
count: memberships.query.data?.count,
},
],
},
Expand Down Expand Up @@ -321,6 +333,7 @@ function LayoutContent({ children }: { children: ReactNode }) {
userCount: users.query.data?.count,
donorCount: donors.query.data?.count,
contributionCount: contributions.query.data?.count,
membershipCount: memberships.query.data?.count,
roleCount: roles.query.data?.count,
permissionCount: permissions.query.data?.count,
positionCount,
Expand Down
6 changes: 3 additions & 3 deletions src/app/volunteer_dashboard/page.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
align-items: center;
justify-content: center;
font-size: clamp(1.65rem, 2.6vw, 2.3rem);
font-weight: 750;
font-weight: 700;
letter-spacing: -0.03em;
line-height: 1.08;
color: rgba(9, 34, 58, 0.96);
Expand All @@ -144,7 +144,7 @@
.unselectedProfileName {
margin: 0;
font-size: clamp(1.65rem, 2.6vw, 2.3rem);
font-weight: 750;
font-weight: 700;
letter-spacing: -0.03em;
line-height: 1.08;
color: rgba(9, 34, 58, 0.96);
Expand Down Expand Up @@ -176,7 +176,7 @@
.unselectedProfileHandle {
margin: 0;
font-size: 0.98rem;
font-weight: 540;
font-weight: 500;
letter-spacing: -0.01em;
color: rgba(15, 23, 42, 0.55);
animation: nameIn 0.79s cubic-bezier(0.25, 0.46, 0.45, 0.94) 3.275s both;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { TabBar, TabSpec } from '@/components/common/tab_bar/TabBar'
import { HStack, Spacer, VStack, ZStack } from '@/components/layout'
import { stateOptions } from '@/models'
import { cn, parseErrorMessage } from '@/util'
import { cn, DOT_SEPARATOR, parseErrorMessage } from '@/util'
import { Endorsement, EndorsementType, InitiativeType } from 'pv-contracts/data'
import { ChangeEvent, useState } from 'react'
import { FaCamera } from 'react-icons/fa'
Expand Down Expand Up @@ -135,7 +135,8 @@ export function EndorsementBanner({
endorsement.jurisdiction,
]
.filter(Boolean)
.join(' · ') || 'No state selected'}
.join(` ${DOT_SEPARATOR} `) ||
'No state selected'}
</h2>
{uploadError && (
<span className={styles.uploadError}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import styles from './endorsementFilters.module.css'
import { FilterTag } from '@/app/volunteer_dashboard/layout/FilterTags'
import { DropdownOverlay, DropdownOverlayButton } from '@/components/common'
import { stateOptions } from '@/models'
import { DOT_SEPARATOR } from '@/util'
import {
ElectionStatus,
Endorsement,
Expand Down Expand Up @@ -181,7 +182,7 @@ function optionDropdown<T>(
label="Filter by"
onClose={closeDropdown}
narrowLayoutMode="trigger"
style={{ left: 0, right: 'auto' }}
align="start"
body={
<div className={styles.filterMenu}>
<DropdownOverlayButton
Expand Down Expand Up @@ -260,7 +261,7 @@ export function useEndorsementFilters(endorsements: Endorsement[]) {
selectedIncumbentLabel,
]
.filter(Boolean)
.join(' · ') || 'More'
.join(` ${DOT_SEPARATOR} `) || 'More'

let selectedFilterIcon = <FaCog />
if (selectedState) selectedFilterIcon = <FaMapMarkerAlt />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@
}

.panelBreadcrumb {
font-weight: 650;
font-weight: 600;
color: rgba(15, 23, 42, 0.55);
}

Expand Down
9 changes: 5 additions & 4 deletions src/app/volunteer_dashboard/panels/fundraising/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ export default function Page() {
isAwaitingDraftEndDate,
statsQuery,
allTimeStatsQuery,
membershipCountQuery,
contributionCountQuery,
setStartDate,
setEndDate,
setCommittedPreset,
Expand Down Expand Up @@ -710,8 +712,7 @@ export default function Page() {
href="/volunteer_dashboard/panels/contributions"
icon={FaMoneyBills}
tag={{
count: allTimeStatsQuery.data
?.totalContributionCount,
count: contributionCountQuery.data?.count,
}}
buttonType="card"
trackPanelHistory
Expand All @@ -722,9 +723,9 @@ export default function Page() {
description="Dues Paying Membership switchboard."
href="/volunteer_dashboard/panels/membership"
icon={FaMoneyCheckDollar}
// tag={{ count: 92 }} will be added once membership stats are available.
tag={{ count: membershipCountQuery.data?.count }}
buttonType="card"
resetPanelHistoryOnClick
trackPanelHistory
/>
</div>
</div>
Expand Down
Loading
Loading