diff --git a/web/components/home/home.tsx b/web/components/home/home.tsx index a07d49bd..fa90561e 100644 --- a/web/components/home/home.tsx +++ b/web/components/home/home.tsx @@ -1,6 +1,8 @@ +import {AdjustmentsHorizontalIcon, EyeIcon, UsersIcon} from '@heroicons/react/24/outline' import {discordLink, githubRepo} from 'common/constants' import Link from 'next/link' -import {useEffect, useRef} from 'react' +import {ComponentType, ReactNode, SVGProps, useEffect, useRef} from 'react' +import {FaDiscord, FaGithub} from 'react-icons/fa' import {Col} from 'web/components/layout/col' import {Row} from 'web/components/layout/row' import {SignUpButton} from 'web/components/nav/sidebar' @@ -9,8 +11,10 @@ import {useT} from 'web/lib/locale' // ─── Types ──────────────────────────────────────────────────────────────────── +type IconType = ComponentType> + interface FeatureCardProps { - icon: string + icon: IconType title: string text: string } @@ -31,18 +35,18 @@ function EyebrowBadge({children}: {children: React.ReactNode}) { ) } -function FeatureCard({icon, title, text}: FeatureCardProps) { +function FeatureCard({icon: Icon, title, text}: FeatureCardProps) { return (
-
- {icon} +
+

{title}

{text}

@@ -99,7 +103,7 @@ function OpenSourceStrip({ }: { title: string description: string - badges: {label: string; url: string; primary?: boolean}[] + badges: {label: string; url: string; primary?: boolean; icon?: ReactNode}[] }) { return (
@@ -113,14 +117,15 @@ function OpenSourceStrip({ href={b.url} key={b.label} className={` - px-4 py-2 rounded-lg text-sm font-semibold border transition-all duration-150 + inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold border transition-all duration-150 ${ b.primary - ? 'bg-primary-500 text-white border-[#C17F3E] hover:bg-primary-600' + ? 'bg-primary-500 text-white border-primary-500 hover:bg-primary-600' : 'bg-primary-500/30 text-white/75 border-primary-500/30 hover:bg-primary-500/50' } `} > + {b.icon} {b.label} ))} @@ -191,7 +196,7 @@ export function LoggedOutHome() { const features: FeatureCardProps[] = [ { - icon: '🔍', + icon: EyeIcon, title: t('home.feature1.title', 'Radically Transparent'), text: t( 'home.feature1.text', @@ -199,7 +204,7 @@ export function LoggedOutHome() { ), }, { - icon: '🎯', + icon: AdjustmentsHorizontalIcon, title: t('home.feature2.title', 'Built for Depth'), text: t( 'home.feature2.text', @@ -207,7 +212,7 @@ export function LoggedOutHome() { ), }, { - icon: '🌍', + icon: UsersIcon, title: t('home.feature3.title', 'Community Owned'), text: t( 'home.feature3.text', @@ -217,8 +222,16 @@ export function LoggedOutHome() { ] const openSourceBadges = [ - {label: t('home.strip.github', '⭐ GitHub'), url: githubRepo}, - {label: t('home.strip.discord', '📖 Discord'), url: discordLink}, + { + label: t('home.strip.github', 'GitHub'), + url: githubRepo, + icon: , + }, + { + label: t('home.strip.discord', 'Discord'), + url: discordLink, + icon: , + }, {label: t('home.strip.join', 'Join Now →'), url: '/register', primary: true}, ] diff --git a/web/pages/about.tsx b/web/pages/about.tsx index 4ba1ad86..d259892d 100644 --- a/web/pages/about.tsx +++ b/web/pages/about.tsx @@ -1,8 +1,22 @@ +import { + BellIcon, + ChatBubbleLeftRightIcon, + CodeBracketIcon, + FlagIcon, + GiftIcon, + GlobeAltIcon, + HeartIcon, + LightBulbIcon, + MagnifyingGlassIcon, + MegaphoneIcon, + ScaleIcon, + SparklesIcon, +} from '@heroicons/react/24/outline' import clsx from 'clsx' import {discordLink, formLink, githubRepo} from 'common/constants' import {DEPLOYED_WEB_URL} from 'common/envs/constants' import Link from 'next/link' -import {ReactNode} from 'react' +import {ComponentType, ReactNode, SVGProps} from 'react' import {CopyLinkOrShareButton, ShareProfileOnXButton} from 'web/components/buttons/copy-link-button' import {GeneralButton} from 'web/components/buttons/general-button' import {Row} from 'web/components/layout/row' @@ -12,14 +26,16 @@ import {useT} from 'web/lib/locale' // ─── Types ──────────────────────────────────────────────────────────────────── +type IconType = ComponentType> + interface FeatureCardProps { - icon: string + icon: IconType title: string text: ReactNode } interface HelpCardProps { - icon: string + icon: IconType title: string text: ReactNode buttonLabel: string @@ -30,7 +46,7 @@ interface HelpCardProps { // ─── Feature Card ───────────────────────────────────────────────────────────── -function FeatureCard({icon, title, text}: FeatureCardProps) { +function FeatureCard({icon: Icon, title, text}: FeatureCardProps) { return (
-
- {icon} +
+

{title}

{text}

@@ -52,7 +68,7 @@ function FeatureCard({icon, title, text}: FeatureCardProps) { // ─── Full-width Feature Card ────────────────────────────────────────────────── -function FeatureCardWide({icon, title, text}: FeatureCardProps) { +function FeatureCardWide({icon: Icon, title, text}: FeatureCardProps) { return (
-
- {icon} +
+

{title}

@@ -77,7 +93,15 @@ function FeatureCardWide({icon, title, text}: FeatureCardProps) { // ─── Help Card ──────────────────────────────────────────────────────────────── -function HelpCard({icon, title, text, buttonLabel, buttonUrl, buttonPrimary, id}: HelpCardProps) { +function HelpCard({ + icon: Icon, + title, + text, + buttonLabel, + buttonUrl, + buttonPrimary, + id, +}: HelpCardProps) { return (
- {icon} +
+

{title} @@ -134,7 +158,10 @@ function ShareStrip({title, text}: {title: string; text: string}) { return (
-

📣 {title}

+

+ + {title} +

{text}

@@ -178,7 +205,7 @@ export default function About() { const features: (FeatureCardProps & {wide?: boolean})[] = [ { - icon: '🔍', + icon: MagnifyingGlassIcon, title: t('about.block.keyword.title', 'Keyword Search the Database'), text: t( 'about.block.keyword.text', @@ -186,7 +213,7 @@ export default function About() { ), }, { - icon: '🔔', + icon: BellIcon, title: t('about.block.notify.title', 'Get Notified About Searches'), text: t( 'about.block.notify.text', @@ -194,17 +221,17 @@ export default function About() { ), }, { - icon: '🎭', + icon: SparklesIcon, title: t('about.block.personality.title', 'Personality-Centered'), text: t('about.block.personality.text', 'Values and interests first, photos are secondary.'), }, { - icon: '🎁', + icon: GiftIcon, title: t('about.block.free.title', 'Completely Free'), text: t('about.block.free.text', 'Subscription-free. Paywall-free. Ad-free.'), }, { - icon: '🗳️', + icon: ScaleIcon, title: t('about.block.democratic.title', 'Democratic'), text: ( @@ -224,7 +251,7 @@ export default function About() { ), }, { - icon: '🎯', + icon: FlagIcon, title: t('about.block.mission.title', 'One Mission'), text: t( 'about.block.mission.text', @@ -232,7 +259,7 @@ export default function About() { ), }, { - icon: '🌍', + icon: GlobeAltIcon, title: t('about.block.vision.title', 'Vision'), text: t( 'about.block.vision.text', @@ -244,7 +271,7 @@ export default function About() { const helpCards: HelpCardProps[] = [ { - icon: '💡', + icon: LightBulbIcon, id: 'give-suggestions-or-contribute', title: t('about.suggestions.title', 'Give Suggestions or Contribute'), text: t( @@ -256,7 +283,7 @@ export default function About() { // buttonPrimary: true, }, { - icon: '💻', + icon: CodeBracketIcon, id: 'share', title: t('about.dev.title', 'Develop the App'), text: t( @@ -267,7 +294,7 @@ export default function About() { buttonUrl: githubRepo, }, { - icon: '💬', + icon: ChatBubbleLeftRightIcon, id: 'join-chats', title: t('about.join.title', 'Join the Community'), text: t( @@ -278,7 +305,7 @@ export default function About() { buttonUrl: discordLink, }, { - icon: '❤️', + icon: HeartIcon, id: 'donate', title: t('about.donate.title', 'Donate'), text: t( diff --git a/web/pages/organization.tsx b/web/pages/organization.tsx index d77292a0..282fe32e 100644 --- a/web/pages/organization.tsx +++ b/web/pages/organization.tsx @@ -1,4 +1,10 @@ -import {ReactNode} from 'react' +import { + ChartBarIcon, + InformationCircleIcon, + LifebuoyIcon, + ShieldCheckIcon, +} from '@heroicons/react/24/outline' +import {ComponentType, ReactNode, SVGProps} from 'react' import {GeneralButton} from 'web/components/buttons/general-button' import {PageBase} from 'web/components/page-base' import {SEO} from 'web/components/SEO' @@ -6,6 +12,8 @@ import {useT} from 'web/lib/locale' // ─── Types ──────────────────────────────────────────────────────────────────── +type IconType = ComponentType> + interface LinkItem { url: string label: string @@ -13,7 +21,7 @@ interface LinkItem { } interface SectionCardProps { - icon: string + icon: IconType title: string description: string links: LinkItem[] @@ -21,7 +29,7 @@ interface SectionCardProps { // ─── Section Card ───────────────────────────────────────────────────────────── -function SectionCard({icon, title, description, links}: SectionCardProps) { +function SectionCard({icon: Icon, title, description, links}: SectionCardProps) { return (
{/* Icon */} -
- {icon} +
+
{/* Title & description */} @@ -88,7 +96,7 @@ export default function Organization() { const sections: SectionCardProps[] = [ { - icon: 'ℹ️', + icon: InformationCircleIcon, title: t('organization.about.title', 'About us'), description: t( 'organization.about.desc', @@ -100,7 +108,7 @@ export default function Organization() { ], }, { - icon: '📊', + icon: ChartBarIcon, title: t('organization.proof.title', 'Proof & transparency'), description: t( 'organization.proof.desc', @@ -113,7 +121,7 @@ export default function Organization() { ], }, { - icon: '💬', + icon: LifebuoyIcon, title: t('organization.contactSection.title', 'Contact & support'), description: t( 'organization.contactSection.desc', @@ -125,7 +133,7 @@ export default function Organization() { ], }, { - icon: '🔒', + icon: ShieldCheckIcon, title: t('organization.trust.title', 'Trust & legal'), description: t( 'organization.trust.desc', diff --git a/web/pages/social.tsx b/web/pages/social.tsx index 3620ae10..58cc7237 100644 --- a/web/pages/social.tsx +++ b/web/pages/social.tsx @@ -1,3 +1,4 @@ +import {CodeBracketIcon, EnvelopeIcon, MegaphoneIcon, UsersIcon} from '@heroicons/react/24/outline' import { discordLink, githubRepo, @@ -6,22 +7,26 @@ import { supportEmail, xLink, } from 'common/constants' -import {ReactNode} from 'react' +import {ComponentType, ReactNode, SVGProps} from 'react' +import {FaDiscord, FaGithub, FaInstagram, FaReddit} from 'react-icons/fa' +import {FaXTwitter} from 'react-icons/fa6' import {PageBase} from 'web/components/page-base' import {SEO} from 'web/components/SEO' import {useT} from 'web/lib/locale' // ─── Types ────────────── ────────────────────────────────────────────────────── +type IconType = ComponentType> + interface SocialLink { url: string label: string - icon: string + icon: ReactNode primary?: boolean } interface SectionCardProps { - icon: string + icon: IconType title: string description: string links: SocialLink[] @@ -47,7 +52,7 @@ function SocialLinkButton({url, label, icon, primary}: SocialLink) { } `} > - {icon && {icon}} + {icon && {icon}} {label} ) @@ -55,7 +60,7 @@ function SocialLinkButton({url, label, icon, primary}: SocialLink) { // ─── Section Card ───────────────────────────────────────────────────────────── -function SectionCard({icon, title, description, links}: SectionCardProps) { +function SectionCard({icon: Icon, title, description, links}: SectionCardProps) { return (
{/* Icon */} -
- {icon} +
+
{/* Title & description */} @@ -113,48 +118,73 @@ export default function Social() { const sections: SectionCardProps[] = [ { - icon: '💬', + icon: UsersIcon, title: t('social.community.title', 'Community'), description: t( 'social.community.desc', 'Join our community chats and shape the platform with us.', ), links: [ - {url: discordLink, label: t('social.discord', 'Discord'), icon: '🎮', primary: true}, - {url: redditLink, label: t('social.reddit', 'Reddit'), icon: ''}, + { + url: discordLink, + label: t('social.discord', 'Discord'), + icon: , + primary: true, + }, + { + url: redditLink, + label: t('social.reddit', 'Reddit'), + icon: , + }, // {url: stoatLink, label: t('social.stoat', 'Revolt / Stoat'), icon: '💬'}, ], }, { - icon: '📣', + icon: MegaphoneIcon, title: t('social.follow.title', 'Follow & Updates'), description: t( 'social.follow.desc', 'Stay informed about announcements, releases, and news.', ), links: [ - {url: xLink, label: t('social.x', 'X / Twitter'), icon: '𝕏', primary: true}, - {url: instagramLink, label: t('social.instagram', 'Instagram'), icon: '📸'}, + { + url: xLink, + label: t('social.x', 'X / Twitter'), + icon: , + primary: true, + }, + { + url: instagramLink, + label: t('social.instagram', 'Instagram'), + icon: , + }, ], }, { - icon: '💻', + icon: CodeBracketIcon, title: t('social.dev.title', 'Development'), description: t( 'social.dev.desc', 'Explore our source code, open issues, or contribute a PR.', ), - links: [{url: githubRepo, label: t('social.github', 'GitHub'), icon: '⭐', primary: true}], + links: [ + { + url: githubRepo, + label: t('social.github', 'GitHub'), + icon: , + primary: true, + }, + ], }, { - icon: '✉️', + icon: EnvelopeIcon, title: t('social.contact.title', 'Contact'), description: t('social.contact.desc', 'Reach out to us directly for inquiries or support.'), links: [ { url: `mailto:${supportEmail}`, label: `${t('social.email_button', 'Email us')}`, - icon: '📧', + icon: , primary: true, }, ],