mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
fix(admin): use feature interest composite key
This commit is contained in:
1 parent
a6233d0175
commit
53a48ab6d5
3 files changed
+14
-7
No files matched your search
@@ -1,16 +1,20 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { formatFeatureName, toRecentFeatureInterest } from './featureInterests';
|
||||
import { featureInterestKey, formatFeatureName, toRecentFeatureInterest } from './featureInterests';
|
||||
|
||||
describe('toRecentFeatureInterest', () => {
|
||||
it('preserves the standalone API feature field for dashboard rendering', () => {
|
||||
const interest = toRecentFeatureInterest({
|
||||
id: 'interest-1',
|
||||
user_id: 'user-1',
|
||||
feature: 'better_chat',
|
||||
created_at: '2026-09-05T12:00:00.000Z',
|
||||
});
|
||||
|
||||
expect(interest.feature).toBe('better_chat');
|
||||
expect(interest).toEqual({
|
||||
user_id: 'user-1',
|
||||
feature: 'better_chat',
|
||||
created_at: '2026-09-05T12:00:00.000Z',
|
||||
});
|
||||
expect(formatFeatureName(interest.feature)).toBe('Better Chat');
|
||||
expect(featureInterestKey(interest)).toBe('user-1:better_chat');
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,4 @@
|
||||
export interface FeatureInterestRow {
|
||||
id: string;
|
||||
user_id: string;
|
||||
feature: string;
|
||||
created_at: string;
|
||||
@@ -16,13 +15,16 @@ export interface RecentFeatureInterest extends FeatureInterestRow {
|
||||
|
||||
export function toRecentFeatureInterest(row: FeatureInterestRow): RecentFeatureInterest {
|
||||
return {
|
||||
id: row.id,
|
||||
user_id: row.user_id,
|
||||
feature: row.feature,
|
||||
created_at: row.created_at,
|
||||
};
|
||||
}
|
||||
|
||||
export function featureInterestKey(row: Pick<FeatureInterestRow, 'user_id' | 'feature'>): string {
|
||||
return `${row.user_id}:${row.feature}`;
|
||||
}
|
||||
|
||||
export function formatFeatureName(feature: string): string {
|
||||
return feature
|
||||
.split('_')
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useRealtimeSubscription } from '@/hooks/useRealtimeSubscription';
|
||||
import { RealtimeStatusIndicator } from '@/components/RealtimeStatusIndicator';
|
||||
import {
|
||||
formatFeatureName,
|
||||
featureInterestKey,
|
||||
toRecentFeatureInterest,
|
||||
type FeatureInterestRow,
|
||||
type RecentFeatureInterest,
|
||||
@@ -80,7 +81,7 @@ export function DashboardPage() {
|
||||
? adminData.from('feature_interests').select('created_at, user_id').gte('created_at', startDate.toISOString()).lte('created_at', endDate.toISOString())
|
||||
: Promise.resolve({ data: [] }),
|
||||
canViewUsers
|
||||
? adminData.from<FeatureInterestRow>('feature_interests').select('id, user_id, feature, created_at').order('created_at', { ascending: false }).limit(10)
|
||||
? adminData.from<FeatureInterestRow>('feature_interests').select('user_id, feature, created_at').order('created_at', { ascending: false }).limit(10)
|
||||
: Promise.resolve({ data: [] }),
|
||||
]);
|
||||
|
||||
@@ -566,7 +567,7 @@ export function DashboardPage() {
|
||||
.toUpperCase();
|
||||
|
||||
return (
|
||||
<div key={item.id} className="flex items-center justify-between gap-4 rounded-xl bg-white/5 p-3">
|
||||
<div key={featureInterestKey(item)} className="flex items-center justify-between gap-4 rounded-xl bg-white/5 p-3">
|
||||
<div className="flex items-center gap-3 min-w-0">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src={item.profile?.avatar_url || undefined} />
|
||||
|
||||
Reference in new issue
Block a user