milestone 23 s3: convert features/blocklists/SourceStatusSection.tsx to stylex
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import * as stylex from "@stylexjs/stylex";
|
||||
import { formatTime } from "@/lib/format";
|
||||
import type { SourceStatus } from "@/lib/types";
|
||||
import { tdClass, thClass } from "@/ui/classes";
|
||||
import { styles as shared } from "@/ui/styles";
|
||||
import { colors } from "@/ui/tokens.stylex";
|
||||
|
||||
function formatAttempt(unixSeconds: number): string {
|
||||
return unixSeconds === 0 ? "never" : formatTime(unixSeconds);
|
||||
@@ -11,61 +13,108 @@ interface SourceStatusSectionProps {
|
||||
namesById: ReadonlyMap<number, string>;
|
||||
}
|
||||
|
||||
const styles = stylex.create({
|
||||
section: {
|
||||
marginTop: "2rem",
|
||||
},
|
||||
heading: {
|
||||
fontSize: "1.125rem",
|
||||
lineHeight: "1.75rem",
|
||||
fontWeight: 500,
|
||||
},
|
||||
note: {
|
||||
marginTop: "0.5rem",
|
||||
color: colors.textMuted,
|
||||
},
|
||||
tableWrap: {
|
||||
marginTop: "0.5rem",
|
||||
overflowX: "auto",
|
||||
},
|
||||
table: {
|
||||
width: "100%",
|
||||
minWidth: "max-content",
|
||||
borderCollapse: "collapse",
|
||||
fontSize: "0.875rem",
|
||||
lineHeight: "1.25rem",
|
||||
},
|
||||
name: {
|
||||
fontWeight: 500,
|
||||
},
|
||||
url: {
|
||||
marginTop: "0.125rem",
|
||||
display: "block",
|
||||
maxWidth: "16rem",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
fontSize: "0.75rem",
|
||||
lineHeight: "1rem",
|
||||
color: colors.textMuted,
|
||||
},
|
||||
/** Green has no token: a loaded source is the only success state in the app. */
|
||||
loaded: {
|
||||
color: {
|
||||
default: "oklch(52.7% 0.154 150.069)",
|
||||
"@media (prefers-color-scheme: dark)": "oklch(79.2% 0.209 151.711)",
|
||||
},
|
||||
},
|
||||
failed: {
|
||||
color: colors.danger,
|
||||
},
|
||||
absent: {
|
||||
color: colors.textMuted,
|
||||
},
|
||||
});
|
||||
|
||||
export default function SourceStatusSection({ sources, namesById }: SourceStatusSectionProps) {
|
||||
return (
|
||||
<section className="mt-8">
|
||||
<h2 className="text-lg font-medium">Source status</h2>
|
||||
<section {...stylex.props(styles.section)}>
|
||||
<h2 {...stylex.props(styles.heading)}>Source status</h2>
|
||||
{sources === null ? (
|
||||
<p className="mt-2 text-zinc-500">
|
||||
<p {...stylex.props(styles.note)}>
|
||||
No status snapshot yet — run “Update now” to fetch status for every enabled source.
|
||||
</p>
|
||||
) : sources.length === 0 ? (
|
||||
<p className="mt-2 text-zinc-500">The last update ran against no enabled sources.</p>
|
||||
<p {...stylex.props(styles.note)}>The last update ran against no enabled sources.</p>
|
||||
) : (
|
||||
<div className="mt-2 overflow-x-auto">
|
||||
<table className="w-full min-w-max border-collapse text-sm">
|
||||
<div {...stylex.props(styles.tableWrap)}>
|
||||
<table {...stylex.props(styles.table)}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className={thClass}>Source</th>
|
||||
<th className={thClass}>State</th>
|
||||
<th className={thClass}>Last attempt</th>
|
||||
<th className={thClass}>Last success</th>
|
||||
<th className={thClass}>Domains</th>
|
||||
<th className={thClass}>Wildcards</th>
|
||||
<th className={thClass}>Skipped regex</th>
|
||||
<th className={thClass}>Last error</th>
|
||||
<th {...stylex.props(shared.th)}>Source</th>
|
||||
<th {...stylex.props(shared.th)}>State</th>
|
||||
<th {...stylex.props(shared.th)}>Last attempt</th>
|
||||
<th {...stylex.props(shared.th)}>Last success</th>
|
||||
<th {...stylex.props(shared.th)}>Domains</th>
|
||||
<th {...stylex.props(shared.th)}>Wildcards</th>
|
||||
<th {...stylex.props(shared.th)}>Skipped regex</th>
|
||||
<th {...stylex.props(shared.th)}>Last error</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{sources.map((source) => (
|
||||
<tr key={source.id}>
|
||||
<td className={tdClass}>
|
||||
<span className="font-medium">{namesById.get(source.id) ?? source.url}</span>
|
||||
<span className="mt-0.5 block max-w-64 truncate text-xs text-zinc-500">
|
||||
{source.url}
|
||||
<td {...stylex.props(shared.td)}>
|
||||
<span {...stylex.props(styles.name)}>
|
||||
{namesById.get(source.id) ?? source.url}
|
||||
</span>
|
||||
<span {...stylex.props(styles.url)}>{source.url}</span>
|
||||
</td>
|
||||
<td className={tdClass}>
|
||||
<span
|
||||
className={
|
||||
source.loaded
|
||||
? "text-green-700 dark:text-green-400"
|
||||
: "text-red-600 dark:text-red-400"
|
||||
}
|
||||
>
|
||||
<td {...stylex.props(shared.td)}>
|
||||
<span {...stylex.props(source.loaded ? styles.loaded : styles.failed)}>
|
||||
{source.state}
|
||||
</span>
|
||||
</td>
|
||||
<td className={tdClass}>{formatAttempt(source.last_attempt)}</td>
|
||||
<td className={tdClass}>{formatAttempt(source.last_success)}</td>
|
||||
<td className={`${tdClass} tabular-nums`}>{source.domains}</td>
|
||||
<td className={`${tdClass} tabular-nums`}>{source.wildcards}</td>
|
||||
<td className={`${tdClass} tabular-nums`}>{source.skipped_regex}</td>
|
||||
<td className={tdClass}>
|
||||
<td {...stylex.props(shared.td)}>{formatAttempt(source.last_attempt)}</td>
|
||||
<td {...stylex.props(shared.td)}>{formatAttempt(source.last_success)}</td>
|
||||
<td {...stylex.props(shared.td, shared.tabularNums)}>{source.domains}</td>
|
||||
<td {...stylex.props(shared.td, shared.tabularNums)}>{source.wildcards}</td>
|
||||
<td {...stylex.props(shared.td, shared.tabularNums)}>{source.skipped_regex}</td>
|
||||
<td {...stylex.props(shared.td)}>
|
||||
{source.last_error === "" ? (
|
||||
<span className="text-zinc-400">—</span>
|
||||
<span {...stylex.props(styles.absent)}>—</span>
|
||||
) : (
|
||||
<span className="text-red-600 dark:text-red-400">{source.last_error}</span>
|
||||
<span {...stylex.props(styles.failed)}>{source.last_error}</span>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user