This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

chore: url card stories

+199 -2
+195
src/webapp/features/cards/components/urlCard/UrlCard.stories.tsx
··· 1 + import type { Meta, StoryObj } from '@storybook/nextjs-vite'; 2 + import { CollectionAccessType } from '@semble/types'; 3 + import type { Collection } from '@semble/types'; 4 + import UrlCard from './UrlCard'; 5 + import UrlCardSkeleton from './Skeleton.UrlCard'; 6 + import { AuthContext } from '@/hooks/useAuth'; 7 + import type { AuthContextType } from '@/hooks/useAuth'; 8 + 9 + const mockAuthUser = { 10 + id: 'did:plc:mock123', 11 + name: 'Test User', 12 + handle: 'test.user', 13 + avatarUrl: 'https://i.pravatar.cc/150?u=testuser', 14 + }; 15 + 16 + const mockAuthValue: AuthContextType = { 17 + user: mockAuthUser as any, 18 + isAuthenticated: true, 19 + isLoading: false, 20 + refreshAuth: async () => {}, 21 + logout: async () => {}, 22 + }; 23 + 24 + const cardAuthor = { 25 + id: 'did:plc:author456', 26 + name: 'Jane Researcher', 27 + handle: 'jane.researcher', 28 + avatarUrl: 'https://i.pravatar.cc/150?u=jane', 29 + description: 'Science writer and open-access advocate.', 30 + followerCount: 214, 31 + followingCount: 63, 32 + }; 33 + 34 + const collectionAuthor = { 35 + id: 'did:plc:colauthor789', 36 + name: 'Alex Curator', 37 + handle: 'alex.curator', 38 + avatarUrl: 'https://i.pravatar.cc/150?u=alex', 39 + }; 40 + 41 + const baseCollection: Collection = { 42 + id: 'col-story-001', 43 + uri: 'at://did:plc:colauthor789/app.semble.collection/3juzt2xkr5c2a', 44 + name: 'Web Development Resources', 45 + author: collectionAuthor, 46 + description: 'A curated set of useful web development articles and tools.', 47 + accessType: CollectionAccessType.CLOSED, 48 + cardCount: 24, 49 + createdAt: '2024-09-15T12:00:00.000Z', 50 + updatedAt: '2025-06-20T09:30:00.000Z', 51 + isFollowing: false, 52 + followerCount: 42, 53 + }; 54 + 55 + const baseCardContent = { 56 + url: 'https://example.com/understanding-design-tokens', 57 + title: 'Understanding Design Tokens: A Practical Guide', 58 + description: 59 + 'Design tokens are the atoms of a design system — small, named entities that store visual-design decisions such as color, typography, and spacing.', 60 + imageUrl: 'https://picsum.photos/seed/urlcard1/400/225', 61 + siteName: 'Example Blog', 62 + type: 'article', 63 + retrievedAt: '2025-06-01T10:00:00.000Z', 64 + }; 65 + 66 + const meta: Meta<typeof UrlCard> = { 67 + title: 'Features/Cards/UrlCard', 68 + component: UrlCard, 69 + decorators: [ 70 + (Story) => ( 71 + <AuthContext.Provider value={mockAuthValue}> 72 + <div style={{ maxWidth: 400 }}> 73 + <Story /> 74 + </div> 75 + </AuthContext.Provider> 76 + ), 77 + ], 78 + args: { 79 + id: 'card-default-001', 80 + url: 'https://example.com/understanding-design-tokens', 81 + uri: 'at://did:plc:author456/app.semble.card/3k1abc', 82 + cardContent: baseCardContent, 83 + urlLibraryCount: 5, 84 + urlIsInLibrary: false, 85 + urlConnectionCount: 2, 86 + urlIsConnected: false, 87 + showAuthor: false, 88 + }, 89 + }; 90 + 91 + export default meta; 92 + 93 + type Story = StoryObj<typeof UrlCard>; 94 + 95 + export const Default: Story = {}; 96 + 97 + export const WithContributor: Story = { 98 + args: { 99 + id: 'card-author-002', 100 + showAuthor: true, 101 + cardAuthor: cardAuthor, 102 + authorHandle: cardAuthor.handle, 103 + }, 104 + }; 105 + 106 + export const WithNote: Story = { 107 + args: { 108 + id: 'card-note-003', 109 + note: { 110 + id: 'note-001', 111 + text: 'This is an excellent primer on design tokens. Highly recommend reading the section on naming conventions — it changed how I structure my own token files.', 112 + }, 113 + }, 114 + }; 115 + 116 + export const InLibrary: Story = { 117 + args: { 118 + id: 'card-library-004', 119 + urlIsInLibrary: true, 120 + urlLibraryCount: 37, 121 + cardContent: { 122 + ...baseCardContent, 123 + url: 'https://example.com/state-of-css-2025', 124 + title: 'State of CSS 2025 Survey Results', 125 + description: 126 + 'An overview of the most popular CSS features, frameworks, and tools according to thousands of developers worldwide.', 127 + imageUrl: 'https://picsum.photos/seed/urlcard2/400/225', 128 + siteName: 'State of CSS', 129 + }, 130 + }, 131 + }; 132 + 133 + export const Connected: Story = { 134 + args: { 135 + id: 'card-connected-005', 136 + urlIsConnected: true, 137 + urlConnectionCount: 12, 138 + cardContent: { 139 + ...baseCardContent, 140 + url: 'https://example.com/react-server-components', 141 + title: 'React Server Components Explained', 142 + description: 143 + 'A deep dive into how React Server Components work under the hood, when to use them, and common pitfalls to avoid.', 144 + imageUrl: 'https://picsum.photos/seed/urlcard3/400/225', 145 + siteName: 'React Blog', 146 + }, 147 + }, 148 + }; 149 + 150 + export const WithCollection: Story = { 151 + args: { 152 + id: 'card-collection-006', 153 + currentCollection: baseCollection, 154 + cardContent: { 155 + ...baseCardContent, 156 + url: 'https://example.com/responsive-layout-patterns', 157 + title: 'Modern Responsive Layout Patterns', 158 + description: 159 + 'Move beyond media queries. Learn how to build truly fluid layouts using CSS Grid, Container Queries, and clamp().', 160 + imageUrl: 'https://picsum.photos/seed/urlcard4/400/225', 161 + siteName: 'CSS Tricks', 162 + }, 163 + }, 164 + }; 165 + 166 + export const HighCounts: Story = { 167 + args: { 168 + id: 'card-highcounts-007', 169 + urlLibraryCount: 2847, 170 + urlIsInLibrary: true, 171 + urlConnectionCount: 593, 172 + urlIsConnected: true, 173 + showAuthor: true, 174 + cardAuthor: cardAuthor, 175 + authorHandle: cardAuthor.handle, 176 + cardContent: { 177 + ...baseCardContent, 178 + url: 'https://example.com/attention-is-all-you-need', 179 + title: 'Attention Is All You Need', 180 + description: 181 + 'The dominant sequence transduction models are based on complex recurrent or convolutional neural networks that include an encoder and a decoder.', 182 + imageUrl: 'https://picsum.photos/seed/urlcard5/400/225', 183 + siteName: 'arXiv', 184 + author: 'Vaswani et al.', 185 + }, 186 + note: { 187 + id: 'note-002', 188 + text: 'The foundational transformer paper. Still worth re-reading every few months.', 189 + }, 190 + }, 191 + }; 192 + 193 + export const Skeleton: Story = { 194 + render: () => <UrlCardSkeleton />, 195 + };
+4 -2
src/webapp/hooks/useAuth.tsx
··· 19 19 import { shouldCaptureAnalytics } from '@/features/analytics/utils'; 20 20 import { ENABLE_AUTH_LOGGING } from '@/lib/auth/constants'; 21 21 22 - interface AuthContextType { 22 + export interface AuthContextType { 23 23 user: GetProfileResponse | null; 24 24 isAuthenticated: boolean; 25 25 isLoading: boolean; ··· 27 27 logout: () => Promise<void>; 28 28 } 29 29 30 - const AuthContext = createContext<AuthContextType | undefined>(undefined); 30 + export const AuthContext = createContext<AuthContextType | undefined>( 31 + undefined, 32 + ); 31 33 32 34 export const AuthProvider = ({ children }: { children: ReactNode }) => { 33 35 const router = useRouter();