Sifa professional network frontend (Next.js, React, TailwindCSS)
sifa.id/
1export interface LocationValue {
2 city?: string;
3 region?: string;
4 country: string;
5 countryCode?: string;
6 postalCode?: string;
7 geonameId?: number;
8}
9
10export interface SkillRef {
11 uri: string;
12 cid: string;
13}
14
15export interface ProfilePosition {
16 rkey: string;
17 company: string;
18 title: string;
19 description?: string;
20 startedAt: string;
21 endedAt?: string;
22 location?: LocationValue | null;
23 skills?: SkillRef[];
24 linkedSkills?: ProfileSkill[];
25 primary?: boolean;
26}
27
28export interface ProfileEducation {
29 rkey: string;
30 institution: string;
31 degree?: string;
32 fieldOfStudy?: string;
33 startedAt?: string;
34 endedAt?: string;
35}
36
37export interface ProfileSkill {
38 rkey: string;
39 name: string;
40 category?: string;
41 endorsementCount?: number; // keep for internal logic, never display
42 endorsed?: boolean; // true if at least one confirmed mutual endorsement
43 activityBacked?: boolean; // true if backed by verified external accounts or community activity
44}
45
46export interface SkillSuggestion {
47 canonicalName: string;
48 slug: string;
49 category: string;
50}
51
52export interface Endorsement {
53 endorserDid: string;
54 endorserHandle: string;
55 endorserDisplayName?: string;
56 endorserAvatar?: string;
57 comment?: string;
58 relationshipContext?: string;
59 createdAt: string;
60}
61
62export interface EndorsementData {
63 skillRkey: string;
64 comment?: string;
65 relationshipContext?: string;
66}
67
68export interface ProfileCertification {
69 rkey: string;
70 name: string;
71 issuingOrg: string;
72 issueDate?: string;
73 expiryDate?: string;
74 credentialUrl?: string;
75}
76
77export interface ProfileProject {
78 rkey: string;
79 name: string;
80 description?: string;
81 url?: string;
82 startDate?: string;
83 endDate?: string;
84}
85
86export interface ProfilePublication {
87 rkey: string;
88 title: string;
89 publisher?: string;
90 date?: string;
91 url?: string;
92 description?: string;
93}
94
95export interface ProfileVolunteering {
96 rkey: string;
97 organization: string;
98 role?: string;
99 cause?: string;
100 startDate?: string;
101 endDate?: string;
102 description?: string;
103}
104
105export interface ProfileHonor {
106 rkey: string;
107 title: string;
108 issuer?: string;
109 date?: string;
110 description?: string;
111}
112
113export interface ProfileLanguage {
114 rkey: string;
115 language: string;
116 proficiency?:
117 | 'elementary'
118 | 'limited_working'
119 | 'professional_working'
120 | 'full_professional'
121 | 'native';
122}
123
124export interface ProfileCourse {
125 rkey: string;
126 name: string;
127 institution?: string;
128 number?: string;
129}
130
131export interface TrustStat {
132 key: string;
133 label: string;
134 value: number;
135}
136
137export interface ActiveApp {
138 id: string;
139 name: string;
140 category: string;
141 recentCount: number;
142 latestRecordAt?: string | null;
143}
144
145export interface VerifiedAccount {
146 platform: string;
147 identifier: string;
148 url?: string;
149}
150
151export interface ExternalAccount {
152 rkey: string;
153 platform: string;
154 url: string;
155 label?: string;
156 feedUrl?: string;
157 primary?: boolean;
158 verifiable: boolean;
159 verified: boolean;
160 verifiedVia?: string | null;
161 source?: 'sifa' | 'keytrace';
162 keytraceVerified?: boolean;
163 keytraceClaim?: {
164 rkey: string;
165 claimedAt: string;
166 };
167}
168
169export interface FeedItem {
170 title: string;
171 excerpt: string;
172 url: string;
173 timestamp: string;
174 source: string;
175}
176
177export interface PdsProviderInfo {
178 name: string;
179 host: string;
180}
181
182export interface Profile {
183 did: string;
184 handle: string;
185 displayName?: string;
186 avatar?: string;
187 pronouns?: string;
188 headline?: string;
189 about?: string;
190 // Override system
191 hasHeadlineOverride?: boolean;
192 hasAboutOverride?: boolean;
193 hasDisplayNameOverride?: boolean;
194 hasAvatarUrlOverride?: boolean;
195 source?: {
196 headline?: string;
197 about?: string;
198 displayName?: string;
199 avatarUrl?: string;
200 };
201 location?: LocationValue | null;
202 website?: string;
203 openTo?: string[];
204 preferredWorkplace?: string[];
205 pdsProvider?: PdsProviderInfo | null;
206 claimed: boolean;
207 isOwnProfile?: boolean;
208 isFollowing?: boolean;
209 createdAt?: string;
210
211 // Trust stats (externally validated, top 3 dynamic)
212 trustStats?: TrustStat[];
213
214 // Verified accounts (Keytrace)
215 verifiedAccounts?: VerifiedAccount[];
216
217 // Active apps (cross-app activity)
218 activeApps?: ActiveApp[];
219
220 // Social graph counts
221 followersCount: number;
222 followingCount: number;
223 connectionsCount: number;
224 atprotoFollowersCount?: number;
225
226 // Professional history
227 positions: ProfilePosition[];
228 education: ProfileEducation[];
229 skills: ProfileSkill[];
230 certifications?: ProfileCertification[];
231 projects?: ProfileProject[];
232 publications?: ProfilePublication[];
233 volunteering?: ProfileVolunteering[];
234 honors?: ProfileHonor[];
235 languages?: ProfileLanguage[];
236 courses?: ProfileCourse[];
237 externalAccounts?: ExternalAccount[];
238}