Sifa professional network frontend (Next.js, React, TailwindCSS)
sifa.id/
1import type { ComponentType } from 'react';
2import {
3 Butterfly,
4 GithubLogo,
5 LinkedinLogo,
6 YoutubeLogo,
7 TwitterLogo,
8 InstagramLogo,
9 Globe,
10 RssSimple,
11 MastodonLogo,
12 LinkSimple,
13} from '@phosphor-icons/react';
14import type { IconWeight } from '@phosphor-icons/react';
15import { SubstackIcon } from './substack-icon';
16
17interface PlatformInfo {
18 label: string;
19 icon: ComponentType<{ size?: number; weight?: IconWeight; className?: string }>;
20}
21
22const PLATFORM_MAP: Record<string, PlatformInfo> = {
23 bluesky: { label: 'Bluesky', icon: Butterfly },
24 github: { label: 'GitHub', icon: GithubLogo },
25 linkedin: { label: 'LinkedIn', icon: LinkedinLogo },
26 youtube: { label: 'YouTube', icon: YoutubeLogo },
27 twitter: { label: 'X (Twitter)', icon: TwitterLogo },
28 instagram: { label: 'Instagram', icon: InstagramLogo },
29 substack: { label: 'Substack', icon: SubstackIcon },
30 tangled: { label: 'Tangled', icon: LinkSimple },
31 dns: { label: 'Domain', icon: Globe },
32 website: { label: 'Website', icon: Globe },
33 rss: { label: 'RSS', icon: RssSimple },
34 fediverse: { label: 'Fediverse', icon: MastodonLogo },
35};
36
37export function getPlatformInfo(platform: string): PlatformInfo {
38 return PLATFORM_MAP[platform] ?? PLATFORM_MAP.website!;
39}
40
41export function isKnownPlatform(platform: string): boolean {
42 return platform in PLATFORM_MAP;
43}
44
45/** Platforms available in the "Add Links" dropdown (excludes Bluesky — auto-derived from AT Protocol identity). */
46export const PLATFORM_OPTIONS = Object.entries(PLATFORM_MAP)
47 .filter(([value]) => value !== 'bluesky')
48 .map(([value, info]) => ({
49 value,
50 label: info.label,
51 }));
52
53/**
54 * Build a favicon URL for a given site URL using Google's public favicon service.
55 * Returns `null` if the URL cannot be parsed.
56 */
57export function getFaviconUrl(siteUrl: string): string | null {
58 try {
59 const { hostname } = new URL(siteUrl);
60 return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(hostname)}&sz=32`;
61 } catch {
62 return null;
63 }
64}