Skip to content

Commit 589a1a1

Browse files
enkoclaude
andcommitted
refactor(frontend): Address review suggestions for friendListFilter
- Export FriendListFilterState interface for consumer type annotations - Extract buildSearchParams/parseSearchParams as standalone pure utility functions instead of store methods (cleaner API, no need to pass state back to the store) - Re-export new symbols from friends.ts barrel Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0dee0f5 commit 589a1a1

File tree

3 files changed

+61
-50
lines changed

3 files changed

+61
-50
lines changed

apps/frontend/src/lib/shortcuts/handlers/navigation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { get } from 'svelte/store';
22
import { goto } from '$app/navigation';
3-
import { friendListFilter } from '$lib/stores/friends';
3+
import { buildSearchParams, friendListFilter } from '$lib/stores/friends';
44
import { NAVIGATION_PATHS } from '../config.js';
55
import type { HandlerContext } from '../types.js';
66

@@ -13,7 +13,7 @@ export function handleNavigation(e: KeyboardEvent, ctx: HandlerContext): boolean
1313
if (e.key === 'f') {
1414
// Restore filter state from store when navigating to friends
1515
const filterState = get(friendListFilter);
16-
const params = friendListFilter.buildSearchParams(filterState);
16+
const params = buildSearchParams(filterState);
1717
const queryString = params.toString();
1818
goto(queryString ? `/friends?${queryString}` : '/friends');
1919
return true;
Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { derived, writable } from 'svelte/store';
22
import type { FacetFilters } from '$shared';
33

4-
interface FriendListFilterState {
4+
export interface FriendListFilterState {
55
query: string;
66
filters: FacetFilters;
77
}
@@ -32,53 +32,6 @@ function createFriendListFilterStore() {
3232
clear: () => {
3333
set(initialFilterState);
3434
},
35-
36-
buildSearchParams: (state: FriendListFilterState): URLSearchParams => {
37-
const params = new URLSearchParams();
38-
39-
if (state.query.trim()) {
40-
params.set('q', state.query.trim());
41-
}
42-
43-
for (const [key, values] of Object.entries(state.filters)) {
44-
if (values && values.length > 0) {
45-
params.set(key, values.join(','));
46-
}
47-
}
48-
49-
return params;
50-
},
51-
52-
parseSearchParams: (params: URLSearchParams): FriendListFilterState => {
53-
const query = params.get('q') ?? '';
54-
const filters: FacetFilters = {};
55-
56-
const stringArrayKeys = [
57-
'country',
58-
'city',
59-
'organization',
60-
'job_title',
61-
'department',
62-
'circles',
63-
] as const;
64-
for (const key of stringArrayKeys) {
65-
const value = params.get(key);
66-
if (value) {
67-
filters[key] = value.split(',');
68-
}
69-
}
70-
71-
const relationshipCategory = params.get('relationship_category');
72-
if (relationshipCategory) {
73-
filters.relationship_category = relationshipCategory.split(',') as (
74-
| 'family'
75-
| 'professional'
76-
| 'social'
77-
)[];
78-
}
79-
80-
return { query, filters };
81-
},
8235
};
8336
}
8437

@@ -92,3 +45,58 @@ export const hasFriendListFilters = derived(
9245
$filter.query.trim().length > 0 ||
9346
Object.values($filter.filters).some((arr) => arr && arr.length > 0),
9447
);
48+
49+
/**
50+
* Build URL search params from filter state.
51+
* Pure utility — does not read the store; pass a state snapshot.
52+
*/
53+
export function buildSearchParams(state: FriendListFilterState): URLSearchParams {
54+
const params = new URLSearchParams();
55+
56+
if (state.query.trim()) {
57+
params.set('q', state.query.trim());
58+
}
59+
60+
for (const [key, values] of Object.entries(state.filters)) {
61+
if (values && values.length > 0) {
62+
params.set(key, values.join(','));
63+
}
64+
}
65+
66+
return params;
67+
}
68+
69+
/**
70+
* Parse URL search params into filter state.
71+
* Pure utility — does not read the store.
72+
*/
73+
export function parseSearchParams(params: URLSearchParams): FriendListFilterState {
74+
const query = params.get('q') ?? '';
75+
const filters: FacetFilters = {};
76+
77+
const stringArrayKeys = [
78+
'country',
79+
'city',
80+
'organization',
81+
'job_title',
82+
'department',
83+
'circles',
84+
] as const;
85+
for (const key of stringArrayKeys) {
86+
const value = params.get(key);
87+
if (value) {
88+
filters[key] = value.split(',');
89+
}
90+
}
91+
92+
const relationshipCategory = params.get('relationship_category');
93+
if (relationshipCategory) {
94+
filters.relationship_category = relationshipCategory.split(',') as (
95+
| 'family'
96+
| 'professional'
97+
| 'social'
98+
)[];
99+
}
100+
101+
return { query, filters };
102+
}

apps/frontend/src/lib/stores/friends.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ import * as friendsApi from '../api/friends.js';
1212
import { createSubresourceOps } from './friendSubresources.js';
1313
import { storeAction } from './storeAction.js';
1414

15+
export type { FriendListFilterState } from './friendListFilter.js';
1516
// Re-export filter store so consumers can still import from '$lib/stores/friends'
1617
export {
18+
buildSearchParams,
1719
friendListFilter,
1820
friendListQuery,
1921
hasFriendListFilters,
22+
parseSearchParams,
2023
} from './friendListFilter.js';
2124

2225
export interface FriendsState {

0 commit comments

Comments
 (0)