refactor(frontend): move stylings out of logic into centralized file

This commit is contained in:
2026-03-03 20:28:23 +00:00
parent e2ac4495fd
commit bd0e1a9050
21 changed files with 652 additions and 320 deletions

View File

@@ -91,36 +91,24 @@ const AppLayout = () => {
};
return (
<div
style={{
minHeight: "100vh",
background: "#f6f7fb",
fontFamily: styles.page.fontFamily,
color: "#111827",
}}
>
<div style={{ ...styles.container, padding: "16px 24px 0" }}>
<div style={styles.appShell}>
<div style={{ ...styles.container, ...styles.appHeaderWrap }}>
<div style={{ ...styles.card, ...styles.headerBar }}>
<div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
<span style={{ margin: 0, color: "#111827", fontSize: 18, fontWeight: 700 }}>
<div style={styles.appHeaderBrandRow}>
<span style={styles.appTitle}>
Ethnograph View
</span>
<span
style={{
padding: "4px 10px",
borderRadius: 999,
fontSize: 12,
fontWeight: 700,
fontFamily: styles.page.fontFamily,
background: isSignedIn ? "#dcfce7" : "#fee2e2",
color: isSignedIn ? "#166534" : "#991b1b",
...styles.authStatusBadge,
...(isSignedIn ? styles.authStatusSignedIn : styles.authStatusSignedOut),
}}
>
{isSignedIn ? `Signed in: ${getUserLabel(currentUser)}` : "Not signed in"}
</span>
</div>
<div style={{ ...styles.controls, flexWrap: "wrap" }}>
<div style={styles.controlsWrapped}>
<button
type="button"
style={location.pathname === "/upload" ? styles.buttonPrimary : styles.buttonSecondary}

View File

@@ -1,4 +1,7 @@
import type { CSSProperties } from "react";
import StatsStyling from "../styles/stats_styling";
const styles = StatsStyling;
const Card = (props: {
label: string;
@@ -8,45 +11,17 @@ const Card = (props: {
style?: CSSProperties
}) => {
return (
<div style={{
background: "rgba(255,255,255,0.85)",
border: "1px solid rgba(15,23,42,0.08)",
borderRadius: 16,
padding: 14,
boxShadow: "0 12px 30px rgba(15,23,42,0.06)",
minHeight: 88,
...props.style
}}>
<div style={ {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
gap: 10,
}}>
<div style={{
fontSize: 12,
fontWeight: 700,
color: "rgba(15, 23, 42, 0.65)",
letterSpacing: "0.02em",
textTransform: "uppercase"
}}>
<div style={{ ...styles.cardBase, ...props.style }}>
<div style={styles.cardTopRow}>
<div style={styles.cardLabel}>
{props.label}
</div>
{props.rightSlot ? <div>{props.rightSlot}</div> : null}
</div>
<div style={{
fontSize: 22,
fontWeight: 850,
marginTop: 6,
letterSpacing: "-0.02em",
}}>{props.value}</div>
{props.sublabel ? <div style={{
marginTop: 6,
fontSize: 12,
color: "rgba(15, 23, 42, 0.55)",
}}>{props.sublabel}</div> : null}
<div style={styles.cardValue}>{props.value}</div>
{props.sublabel ? <div style={styles.cardSubLabel}>{props.sublabel}</div> : null}
</div>
);
}
export default Card;
export default Card;

View File

@@ -66,11 +66,11 @@ const EmotionalStats = ({contentData}: EmotionalStatsProps) => {
<div style={{ ...styles.container, ...styles.card, marginTop: 16 }}>
<h2 style={styles.sectionTitle}>Average Emotion by Topic</h2>
<p style={styles.sectionSubtitle}>Read confidence together with sample size. Topics with fewer than {lowSampleThreshold} events are usually noisy and less reliable.</p>
<div style={{ display: "flex", flexWrap: "wrap", gap: 10, fontSize: 13, color: "#4b5563", marginTop: 6 }}>
<span><strong style={{ color: "#111827" }}>Topics:</strong> {strongestPerTopic.length}</span>
<span><strong style={{ color: "#111827" }}>Median Sample:</strong> {medianSampleSize} events</span>
<span><strong style={{ color: "#111827" }}>Low Sample (&lt;{lowSampleThreshold}):</strong> {lowSampleTopics}</span>
<span><strong style={{ color: "#111827" }}>Stable Sample ({stableSampleThreshold}+):</strong> {stableSampleTopics}</span>
<div style={styles.emotionalSummaryRow}>
<span><strong style={{ color: "#24292f" }}>Topics:</strong> {strongestPerTopic.length}</span>
<span><strong style={{ color: "#24292f" }}>Median Sample:</strong> {medianSampleSize} events</span>
<span><strong style={{ color: "#24292f" }}>Low Sample (&lt;{lowSampleThreshold}):</strong> {lowSampleTopics}</span>
<span><strong style={{ color: "#24292f" }}>Stable Sample ({stableSampleThreshold}+):</strong> {stableSampleTopics}</span>
</div>
<p style={{ ...styles.sectionSubtitle, marginTop: 10, marginBottom: 0 }}>
Confidence reflects how strongly one emotion leads within a topic, not model accuracy. Use larger samples for stronger conclusions.
@@ -81,19 +81,19 @@ const EmotionalStats = ({contentData}: EmotionalStatsProps) => {
{strongestPerTopic.map((topic) => (
<div key={topic.topic} style={{ ...styles.card, gridColumn: "span 4" }}>
<h3 style={{ ...styles.sectionTitle, marginBottom: 6 }}>{topic.topic}</h3>
<div style={{ fontSize: 12, fontWeight: 700, color: "#6b7280", letterSpacing: "0.02em", textTransform: "uppercase" }}>
<div style={styles.emotionalTopicLabel}>
Top Emotion
</div>
<div style={{ fontSize: 24, fontWeight: 800, marginTop: 4, lineHeight: 1.2 }}>
<div style={styles.emotionalTopicValue}>
{formatEmotion(topic.emotion)}
</div>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 10, fontSize: 13, color: "#6b7280" }}>
<div style={styles.emotionalMetricRow}>
<span>Confidence</span>
<span style={{ fontWeight: 700, color: "#111827" }}>{topic.value.toFixed(3)}</span>
<span style={styles.emotionalMetricValue}>{topic.value.toFixed(3)}</span>
</div>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 4, fontSize: 13, color: "#6b7280" }}>
<div style={styles.emotionalMetricRowCompact}>
<span>Sample Size</span>
<span style={{ fontWeight: 700, color: "#111827" }}>{topic.count} events</span>
<span style={styles.emotionalMetricValue}>{topic.count} events</span>
</div>
</div>
))}

View File

@@ -13,26 +13,11 @@ type Props = {
export default function UserModal({ open, onClose, userData, username }: Props) {
return (
<Dialog open={open} onClose={onClose} style={{ position: "relative", zIndex: 50 }}>
<div
style={{
position: "fixed",
inset: 0,
background: "rgba(0,0,0,0.45)",
}}
/>
<Dialog open={open} onClose={onClose} style={styles.modalRoot}>
<div style={styles.modalBackdrop} />
<div
style={{
position: "fixed",
inset: 0,
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: 16,
}}
>
<DialogPanel style={{ ...styles.card, width: "min(520px, 95vw)" }}>
<div style={styles.modalContainer}>
<DialogPanel style={{ ...styles.card, ...styles.modalPanel }}>
<div style={styles.headerBar}>
<div>
<DialogTitle style={styles.sectionTitle}>{username}</DialogTitle>