Filter detected sellers from conversations
This commit is contained in:
1 parent
d5ebdec076
commit
92c54feedc
14 files changed
+97
-7
No files matched your search
@@ -213,6 +213,7 @@ export function ConversationDetail({ conversationId, onClose }: ConversationDeta
|
||||
<span className="conversation-eyebrow">Conversation</span>
|
||||
<h2><RedditUsernameLink username={conversation.username} /></h2>
|
||||
<AccountOwnerBadge owner={conversation.owner} />
|
||||
{conversation.sellerDetected ? <span className="conversation-seller-marker">Seller</span> : null}
|
||||
{conversation.unread ? <span className="conversation-badge">Unread</span> : null}
|
||||
</div>
|
||||
<button aria-label="Close conversation" onClick={onClose} type="button">Close</button>
|
||||
|
||||
@@ -8,6 +8,7 @@ export function ConversationRoute() {
|
||||
const filterValue = searchParams.get('filter');
|
||||
const filters: ConversationFilters = {
|
||||
search: searchParams.get('q') ?? '',
|
||||
showSellers: searchParams.get('showSellers') === 'true',
|
||||
filter:
|
||||
filterValue === 'unread'
|
||||
|| filterValue === 'awaiting-reply'
|
||||
@@ -29,6 +30,7 @@ export function ConversationRoute() {
|
||||
const params = new URLSearchParams(searchParams);
|
||||
if (next.search) params.set('q', next.search); else params.delete('q');
|
||||
if (next.filter !== 'all') params.set('filter', next.filter); else params.delete('filter');
|
||||
if (next.showSellers) params.set('showSellers', 'true'); else params.delete('showSellers');
|
||||
setSearchParams(params, { replace: true });
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ export type ConversationFilter = 'all' | 'unread' | 'awaiting-reply' | 'received
|
||||
export interface ConversationFilters {
|
||||
search: string;
|
||||
filter: ConversationFilter;
|
||||
showSellers: boolean;
|
||||
}
|
||||
|
||||
export interface ConversationsPageProps {
|
||||
@@ -41,7 +42,7 @@ function ConversationListItem({ conversation, isSelected, now, onSelect }: {
|
||||
return (
|
||||
<li className={isSelected ? 'conversation-list-item is-selected' : 'conversation-list-item'}>
|
||||
<button
|
||||
aria-label={`${redditUsernameLabel(conversation.username)}, ${state}${conversation.hasReceivedImages ? ', Image received' : ''}`}
|
||||
aria-label={`${redditUsernameLabel(conversation.username)}, ${state}${conversation.sellerDetected ? ', Seller' : ''}${conversation.hasReceivedImages ? ', Image received' : ''}`}
|
||||
aria-pressed={isSelected}
|
||||
className="conversation-list-target"
|
||||
onClick={onSelect}
|
||||
@@ -57,6 +58,7 @@ function ConversationListItem({ conversation, isSelected, now, onSelect }: {
|
||||
</span>
|
||||
</span>
|
||||
<AccountOwnerBadge owner={conversation.owner} />
|
||||
{conversation.sellerDetected ? <span className="conversation-seller-marker">Seller</span> : null}
|
||||
{conversation.hasReceivedImages ? <span className="conversation-image-marker">Image received</span> : null}
|
||||
<span>{conversation.lastMessageSnippet || 'No message preview'}</span>
|
||||
</li>
|
||||
@@ -66,7 +68,7 @@ function ConversationListItem({ conversation, isSelected, now, onSelect }: {
|
||||
export function ConversationsPage({ selectedConversationId, onSelectedConversationChange, filters, onFiltersChange }: ConversationsPageProps) {
|
||||
const conversationsQuery = useConversationsQuery();
|
||||
const [internalSelectedId, setInternalSelectedId] = useState<string | null>(null);
|
||||
const [localFilters, setLocalFilters] = useState<ConversationFilters>({ search: '', filter: 'all' });
|
||||
const [localFilters, setLocalFilters] = useState<ConversationFilters>({ search: '', filter: 'all', showSellers: false });
|
||||
const [isStartingConversation, setIsStartingConversation] = useState(false);
|
||||
const [now, setNow] = useState(() => Date.now());
|
||||
const activeConversationId = selectedConversationId !== undefined ? selectedConversationId : internalSelectedId;
|
||||
@@ -89,7 +91,9 @@ export function ConversationsPage({ selectedConversationId, onSelectedConversati
|
||||
const matchesSearch = normalizedSearch.length === 0
|
||||
|| conversation.username.toLowerCase().includes(normalizedSearch)
|
||||
|| conversation.lastMessageSnippet.toLowerCase().includes(normalizedSearch);
|
||||
return matchesSearch && matchesFilter(conversation, activeFilters.filter);
|
||||
return matchesSearch
|
||||
&& matchesFilter(conversation, activeFilters.filter)
|
||||
&& (activeFilters.showSellers || conversation.sellerDetected !== true);
|
||||
})
|
||||
.sort((left, right) => right.lastMessageTime - left.lastMessageTime);
|
||||
}, [activeFilters, conversationsQuery.data]);
|
||||
@@ -142,6 +146,14 @@ export function ConversationsPage({ selectedConversationId, onSelectedConversati
|
||||
<option value="awaiting-reply">Awaiting reply</option>
|
||||
<option value="received-images">Received images</option>
|
||||
</select>
|
||||
<label className="conversation-seller-toggle">
|
||||
<input
|
||||
checked={activeFilters.showSellers}
|
||||
onChange={(event) => updateFilters({ ...activeFilters, showSellers: event.target.checked })}
|
||||
type="checkbox"
|
||||
/>
|
||||
Show sellers
|
||||
</label>
|
||||
</div>
|
||||
{conversationsQuery.isPending ? (
|
||||
<div aria-label="Loading conversations" className="conversation-list-state" role="status">Loading conversations…</div>
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
.conversation-workspace { display: grid; gap: .75rem; }
|
||||
.conversation-master, .conversation-detail-panel { min-width: 0; background: var(--surface); border: 1px solid var(--border); border-radius: .9rem; overflow: hidden; }
|
||||
.conversation-toolbar { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem; padding: .75rem; border-bottom: 1px solid var(--border); }
|
||||
.conversation-seller-toggle { grid-column: 1 / -1; display: inline-flex; align-items: center; gap: .45rem; color: var(--muted); font-size: .78rem; font-weight: 700; }
|
||||
.conversation-seller-toggle input { width: auto; accent-color: var(--accent); }
|
||||
.conversation-list { display: grid; gap: .35rem; max-height: 46rem; padding: .5rem; margin: 0; overflow: auto; list-style: none; }
|
||||
.conversation-list-item { position: relative; display: grid; gap: .4rem; width: 100%; padding: .8rem; text-align: left; background: transparent; border: 1px solid transparent; border-radius: .6rem; }
|
||||
.conversation-list-item:hover { background: var(--surface-raised); }
|
||||
@@ -46,6 +48,7 @@
|
||||
.conversation-list-meta { display: flex; align-items: center; gap: .45rem; }
|
||||
.conversation-list-meta time { color: var(--muted); font-size: .7rem; white-space: nowrap; }
|
||||
.conversation-image-marker { justify-self: start; padding: .18rem .45rem; color: #d8e8ff !important; background: #18324d; border: 1px solid #315d85; border-radius: 999px; font-size: .68rem !important; font-weight: 750; }
|
||||
.conversation-seller-marker { display: inline-flex; justify-self: start; padding: .18rem .45rem; margin-right: .35rem; color: #ffd6d0 !important; background: #4b1e1a; border: 1px solid #874139; border-radius: 999px; font-size: .68rem !important; font-weight: 800; }
|
||||
.conversation-list-state, .conversation-detail-state { display: grid; place-items: center; align-content: center; gap: .5rem; min-height: 16rem; padding: 1.5rem; color: var(--muted); text-align: center; }
|
||||
.conversation-list-state strong, .conversation-detail-state strong { color: #e9f1ec; }
|
||||
.conversation-detail { min-height: 32rem; }
|
||||
|
||||
Reference in new issue
Block a user