CLARITY®

Overview

News

Analysis

72%

72%

Passing Probability

Passing Probability

+1.2

+1.2

Sentiment Delta

Sentiment Delta

68% Pos

68% Pos

Public Sentiment

Public Sentiment

The CLARITY Act aims to set clear rules for digital assets in the United States, giving users and innovators certainty.

The CLARITY Act aims to set clear rules for digital assets in the United States, giving users and innovators certainty.

With bipartisan support, the Act offers fair rules and market transparency for all.

With bipartisan support, the Act offers fair rules and market transparency for all.

Live Social Feed

See the latest thoughts and Twitter commentary about the CLARITY Act, updated in real-time from policy experts, lawmakers, and the #CLARITYAct community.

import * as React from "react"
import { addPropertyControls, ControlType } from "framer"

type Tweet = {
    id: string
    text: string
    created_at: string
    url: string
    author: {
        name: string
        username: string
        profile_image_url?: string
    }
    public_metrics?: {
        like_count?: number
        repost_count?: number
        reply_count?: number
        quote_count?: number
    }
}

type Props = {
    endpoint: string
    title: string
    maxItems: number
    refreshHours: number
    cardRadius: number
    gap: number
    background: string
    cardBackground: string
    textColor: string
    mutedColor: string
    borderColor: string
}

function timeAgo(dateString: string) {
    const then = new Date(dateString).getTime()
    const now = Date.now()
    const diff = Math.max(0, now - then)

    const minute = 60 * 1000
    const hour = 60 * minute
    const day = 24 * hour

    if (diff < hour) return `${Math.floor(diff / minute) || 1}m ago`
    if (diff < day) return `${Math.floor(diff / hour)}h ago`
    return `${Math.floor(diff / day)}d ago`
}

export default function ClarityXFeed(props: Props) {
    const {
        endpoint,
        title,
        maxItems,
        refreshHours,
        cardRadius,
        gap,
        background,
        cardBackground,
        textColor,
        mutedColor,
        borderColor,
    } = props

    const [tweets, setTweets] = React.useState<Tweet[]>([])
    const [loading, setLoading] = React.useState(true)
    const [error, setError] = React.useState<string | null>(null)

    const fetchTweets = React.useCallback(async () => {
        if (!endpoint) {
            setError("Missing API endpoint.")
            setLoading(false)
            return
        }

        try {
            setLoading(true)
            setError(null)

            const url = new URL(endpoint)
            url.searchParams.set("limit", String(maxItems))

            const res = await fetch(url.toString(), {
                method: "GET",
                headers: { Accept: "application/json" },
                cache: "no-store",
            })

            if (!res.ok) {
                throw new Error(`Request failed: ${res.status}`)
            }

            const data = await res.json()
            setTweets(Array.isArray(data?.tweets) ? data.tweets : [])
        } catch (err: any) {
            setError(err?.message || "Failed to load posts.")
        } finally {
            setLoading(false)
        }
    }, [endpoint, maxItems])

    React.useEffect(() => {
        fetchTweets()

        const intervalMs = Math.max(1, refreshHours) * 60 * 60 * 1000
        const id = window.setInterval(fetchTweets, intervalMs)

        return () => window.clearInterval(id)
    }, [fetchTweets, refreshHours])

    return (
        <div
            style={{
                width: "100%",
                height: "100%",
                overflow: "auto",
                background,
                color: textColor,
                fontFamily:
                    'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
                padding: 16,
                boxSizing: "border-box",
            }}
        >
            <div
                style={{
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "space-between",
                    marginBottom: 12,
                }}
            >
                <div
                    style={{
                        fontSize: 18,
                        fontWeight: 700,
                        lineHeight: 1.2,
                    }}
                >
                    {title}
                </div>
                <div
                    style={{
                        fontSize: 12,
                        color: mutedColor,
                    }}
                >
                    Refreshes every {refreshHours}h
                </div>
            </div>

            {loading && (
                <div
                    style={{
                        fontSize: 14,
                        color: mutedColor,
                        padding: 12,
                    }}
                >
                    Loading latest posts…
                </div>
            )}

            {error && !loading && (
                <div
                    style={{
                        fontSize: 14,
                        color: "#b91c1c",
                        background: "#fef2f2",
                        border: "1px solid #fecaca",
                        borderRadius: 12,
                        padding: 12,
                    }}
                >
                    {error}
                </div>
            )}

            {!loading && !error && tweets.length === 0 && (
                <div
                    style={{
                        fontSize: 14,
                        color: mutedColor,
                        padding: 12,
                    }}
                >
                    No matching posts found.
                </div>
            )}

            <div
                style={{
                    display: "grid",
                    gap,
                }}
            >
                {tweets.map((tweet) => (
                    <a
                        key={tweet.id}
                        href={tweet.url}
                        target="_blank"
                        rel="noreferrer"
                        style={{
                            textDecoration: "none",
                            color: "inherit",
                        }}
                    >
                        <div
                            style={{
                                background: cardBackground,
                                border: `1px solid ${borderColor}`,
                                borderRadius: cardRadius,
                                padding: 14,
                                display: "grid",
                                gap: 10,
                                boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
                            }}
                        >
                            <div
                                style={{
                                    display: "flex",
                                    alignItems: "center",
                                    gap: 10,
                                }}
                            >
                                {tweet.author.profile_image_url ? (
                                    <img
                                        src={tweet.author.profile_image_url}
                                        alt={tweet.author.name}
                                        style={{
                                            width: 40,
                                            height: 40,
                                            borderRadius: "999px",
                                            objectFit: "cover",
                                            flexShrink: 0,
                                        }}
                                    />
                                ) : (
                                    <div
                                        style={{
                                            width: 40,
                                            height: 40,
                                            borderRadius: "999px",
                                            background: "#e5e7eb",
                                            flexShrink: 0,
                                        }}
                                    />
                                )}

                                <div style={{ minWidth: 0 }}>
                                    <div
                                        style={{
                                            fontSize: 14,
                                            fontWeight: 600,
                                            whiteSpace: "nowrap",
                                            overflow: "hidden",
                                            textOverflow: "ellipsis",
                                        }}
                                    >
                                        {tweet.author.name}
                                    </div>
                                    <div
                                        style={{
                                            fontSize: 12,
                                            color: mutedColor,
                                            whiteSpace: "nowrap",
                                            overflow: "hidden",
                                            textOverflow: "ellipsis",
                                        }}
                                    >
                                        @{tweet.author.username} · {timeAgo(tweet.created_at)}
                                    </div>
                                </div>
                            </div>

                            <div
                                style={{
                                    fontSize: 14,
                                    lineHeight: 1.5,
                                    whiteSpace: "pre-wrap",
                                    overflowWrap: "anywhere",
                                }}
                            >
                                {tweet.text}
                            </div>

                            <div
                                style={{
                                    display: "flex",
                                    gap: 14,
                                    flexWrap: "wrap",
                                    fontSize: 12,
                                    color: mutedColor,
                                }}
                            >
                                <span>❤️ {tweet.public_metrics?.like_count ?? 0}</span>
                                <span>🔁 {tweet.public_metrics?.repost_count ?? 0}</span>
                                <span>💬 {tweet.public_metrics?.reply_count ?? 0}</span>
                                <span>{tweet.public_metrics?.quote_count ?? 0}</span>
                            </div>
                        </div>
                    </a>
                ))}
            </div>
        </div>
    )
}

ClarityXFeed.defaultProps = {
    title: "Latest X Posts on CLARITY",
    endpoint: "https://YOUR-DOMAIN.com/api/clarity-posts",
    maxItems: 8,
    refreshHours: 12,
    cardRadius: 16,
    gap: 12,
    background: "#ffffff",
    cardBackground: "#ffffff",
    textColor: "#111827",
    mutedColor: "#6b7280",
    borderColor: "#e5e7eb",
}

addPropertyControls(ClarityXFeed, {
    endpoint: { type: ControlType.String, title: "Endpoint" },
    title: { type: ControlType.String, title: "Title" },
    maxItems: {
        type: ControlType.Number,
        title: "Items",
        min: 1,
        max: 20,
        step: 1,
    },
    refreshHours: {
        type: ControlType.Number,
        title: "Refresh",
        min: 1,
        max: 24,
        step: 1,
    },
    cardRadius: {
        type: ControlType.Number,
        title: "Radius",
        min: 0,
        max: 40,
        step: 1,
    },
    gap: {
        type: ControlType.Number,
        title: "Gap",
        min: 0,
        max: 40,
        step: 1,
    },
    background: { type: ControlType.Color, title: "BG" },
    cardBackground: { type: ControlType.Color, title: "Card BG" },
    textColor: { type: ControlType.Color, title: "Text" },
    mutedColor: { type: ControlType.Color, title: "Muted" },
    borderColor: { type: ControlType.Color, title: "Border" },
})