Spaces:
Running
Running
Rajeev Ranjan Pandey commited on
Commit ·
c327c35
1
Parent(s): e078b1d
Final cleanup for alignment and model selection
Browse files
frontend/src/components/SummarizerWidget.jsx
CHANGED
|
@@ -118,18 +118,6 @@ export default function SummarizerWidget({
|
|
| 118 |
|
| 119 |
return (
|
| 120 |
<div className="w-full">
|
| 121 |
-
<div className="mb-6 space-y-4">
|
| 122 |
-
<span className="inline-flex items-center gap-2 rounded-full border border-orange-200 bg-orange-50 px-4 py-1.5 text-xs font-semibold uppercase tracking-widest text-orange-600 dark:border-orange-500/40 dark:bg-orange-500/10 dark:text-orange-400">
|
| 123 |
-
<span className="h-1.5 w-1.5 rounded-full bg-orange-500"></span> AI-powered traffic intelligence
|
| 124 |
-
</span>
|
| 125 |
-
<h1 className="text-4xl md:text-5xl font-black tracking-tight text-slate-900 dark:text-white leading-tight">
|
| 126 |
-
Turn Traffic Chaos <br /> <span className="text-transparent bg-clip-text bg-gradient-to-r from-orange-500 to-orange-600 dark:from-orange-400 dark:to-orange-500">into Clarity</span>
|
| 127 |
-
</h1>
|
| 128 |
-
<p className="text-sm md:text-base text-slate-600 dark:text-slate-400 max-w-2xl font-medium">
|
| 129 |
-
Paste raw incident reports and instantly get AI-distilled summaries from state-of-the-art models. Check the split-view output above.
|
| 130 |
-
</p>
|
| 131 |
-
</div>
|
| 132 |
-
|
| 133 |
<div className="rounded-[24px] border border-slate-200 bg-white/70 shadow-2xl backdrop-blur-xl dark:border-slate-800 dark:bg-[#0d1326]/60">
|
| 134 |
|
| 135 |
{/* Input and Output Split Area */}
|
|
|
|
| 118 |
|
| 119 |
return (
|
| 120 |
<div className="w-full">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
<div className="rounded-[24px] border border-slate-200 bg-white/70 shadow-2xl backdrop-blur-xl dark:border-slate-800 dark:bg-[#0d1326]/60">
|
| 122 |
|
| 123 |
{/* Input and Output Split Area */}
|
frontend/src/pages/Home.jsx
CHANGED
|
@@ -21,13 +21,17 @@ export default function Home() {
|
|
| 21 |
const [samples, setSamples] = useState([]);
|
| 22 |
const [loading, setLoading] = useState(false);
|
| 23 |
|
| 24 |
-
// Refs
|
|
|
|
| 25 |
const textRef = useRef(text);
|
| 26 |
const maxLengthRef = useRef(maxLength);
|
| 27 |
const datasetTrackRef = useRef(datasetTrack);
|
|
|
|
|
|
|
| 28 |
useEffect(() => { textRef.current = text; }, [text]);
|
| 29 |
useEffect(() => { maxLengthRef.current = maxLength; }, [maxLength]);
|
| 30 |
useEffect(() => { datasetTrackRef.current = datasetTrack; }, [datasetTrack]);
|
|
|
|
| 31 |
|
| 32 |
useEffect(() => {
|
| 33 |
if (isDark) {
|
|
@@ -54,18 +58,21 @@ export default function Home() {
|
|
| 54 |
return () => { active = false; };
|
| 55 |
}, [datasetTrack]);
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
|
|
|
| 59 |
const currentText = textRef.current;
|
| 60 |
-
const currentLength =
|
| 61 |
const currentTrack = datasetTrackRef.current;
|
| 62 |
-
|
|
|
|
|
|
|
| 63 |
setLoading(true);
|
| 64 |
setSummary("");
|
| 65 |
try {
|
| 66 |
const data = await summarizeText({
|
| 67 |
text: currentText,
|
| 68 |
-
model_choice:
|
| 69 |
max_length: currentLength,
|
| 70 |
dataset_track: currentTrack
|
| 71 |
});
|
|
@@ -77,13 +84,13 @@ export default function Home() {
|
|
| 77 |
}
|
| 78 |
};
|
| 79 |
|
| 80 |
-
//
|
| 81 |
const handleSummarize = (overrideLength = null) => {
|
| 82 |
if (overrideLength !== null) setMaxLength(overrideLength);
|
| 83 |
-
runSummarize(
|
| 84 |
};
|
| 85 |
|
| 86 |
-
//
|
| 87 |
const handleModelSelect = (modelId) => {
|
| 88 |
setModelChoice(modelId);
|
| 89 |
runSummarize(modelId);
|
|
@@ -91,58 +98,76 @@ export default function Home() {
|
|
| 91 |
|
| 92 |
return (
|
| 93 |
<div className="min-h-screen bg-slate-50 text-slate-900 transition-colors duration-300 dark:bg-[#0B1021] dark:text-slate-200 pb-16">
|
| 94 |
-
|
| 95 |
-
{/*
|
| 96 |
<header className="flex h-16 items-center justify-between px-6 border-b border-slate-200 dark:border-slate-800 bg-white/50 dark:bg-[#0B1021]/50 backdrop-blur-md sticky top-0 z-40">
|
| 97 |
<div className="flex items-center gap-2">
|
| 98 |
-
|
| 99 |
-
|
| 100 |
</div>
|
| 101 |
-
<button
|
| 102 |
-
|
| 103 |
-
|
| 104 |
>
|
| 105 |
{isDark ? <Sun size={18} /> : <Moon size={18} />}
|
| 106 |
</button>
|
| 107 |
</header>
|
| 108 |
|
| 109 |
-
<div className="mx-auto max-w-[1500px] px-4 pt-
|
| 110 |
-
|
| 111 |
-
{/*
|
| 112 |
-
<div className="xl:
|
| 113 |
-
<
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
</div>
|
| 125 |
|
| 126 |
-
{/*
|
| 127 |
-
<div className="
|
| 128 |
-
|
| 129 |
-
{/*
|
| 130 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
|
| 132 |
-
{/*
|
| 133 |
-
<div className="
|
| 134 |
-
<div className="
|
| 135 |
-
<
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
<
|
|
|
|
|
|
|
| 140 |
</div>
|
|
|
|
|
|
|
| 141 |
</div>
|
| 142 |
|
| 143 |
-
{/* Batch Upload */}
|
| 144 |
-
<BatchUpload />
|
| 145 |
-
|
| 146 |
</div>
|
| 147 |
</div>
|
| 148 |
</div>
|
|
|
|
| 21 |
const [samples, setSamples] = useState([]);
|
| 22 |
const [loading, setLoading] = useState(false);
|
| 23 |
|
| 24 |
+
// Refs ensure that the latest state values are available to the async runSummarize function,
|
| 25 |
+
// preventing "stale closures" where the function uses old scale values.
|
| 26 |
const textRef = useRef(text);
|
| 27 |
const maxLengthRef = useRef(maxLength);
|
| 28 |
const datasetTrackRef = useRef(datasetTrack);
|
| 29 |
+
const modelChoiceRef = useRef(modelChoice);
|
| 30 |
+
|
| 31 |
useEffect(() => { textRef.current = text; }, [text]);
|
| 32 |
useEffect(() => { maxLengthRef.current = maxLength; }, [maxLength]);
|
| 33 |
useEffect(() => { datasetTrackRef.current = datasetTrack; }, [datasetTrack]);
|
| 34 |
+
useEffect(() => { modelChoiceRef.current = modelChoice; }, [modelChoice]);
|
| 35 |
|
| 36 |
useEffect(() => {
|
| 37 |
if (isDark) {
|
|
|
|
| 58 |
return () => { active = false; };
|
| 59 |
}, [datasetTrack]);
|
| 60 |
|
| 61 |
+
const runSummarize = async (targetModelId) => {
|
| 62 |
+
// Determine which model to use: either the passed one (for direct clicks) or the state (for slider/button)
|
| 63 |
+
const modelToUse = targetModelId || modelChoiceRef.current;
|
| 64 |
const currentText = textRef.current;
|
| 65 |
+
const currentLength = maxLengthRef.current;
|
| 66 |
const currentTrack = datasetTrackRef.current;
|
| 67 |
+
|
| 68 |
+
if (!currentText || currentText.trim().length < 10) return;
|
| 69 |
+
|
| 70 |
setLoading(true);
|
| 71 |
setSummary("");
|
| 72 |
try {
|
| 73 |
const data = await summarizeText({
|
| 74 |
text: currentText,
|
| 75 |
+
model_choice: modelToUse,
|
| 76 |
max_length: currentLength,
|
| 77 |
dataset_track: currentTrack
|
| 78 |
});
|
|
|
|
| 84 |
}
|
| 85 |
};
|
| 86 |
|
| 87 |
+
// Main button trigger
|
| 88 |
const handleSummarize = (overrideLength = null) => {
|
| 89 |
if (overrideLength !== null) setMaxLength(overrideLength);
|
| 90 |
+
runSummarize();
|
| 91 |
};
|
| 92 |
|
| 93 |
+
// Model selection trigger
|
| 94 |
const handleModelSelect = (modelId) => {
|
| 95 |
setModelChoice(modelId);
|
| 96 |
runSummarize(modelId);
|
|
|
|
| 98 |
|
| 99 |
return (
|
| 100 |
<div className="min-h-screen bg-slate-50 text-slate-900 transition-colors duration-300 dark:bg-[#0B1021] dark:text-slate-200 pb-16">
|
| 101 |
+
|
| 102 |
+
{/* Navbar */}
|
| 103 |
<header className="flex h-16 items-center justify-between px-6 border-b border-slate-200 dark:border-slate-800 bg-white/50 dark:bg-[#0B1021]/50 backdrop-blur-md sticky top-0 z-40">
|
| 104 |
<div className="flex items-center gap-2">
|
| 105 |
+
<div className="h-6 w-6 rounded border-2 border-orange-500 bg-orange-100 dark:bg-orange-500/20"></div>
|
| 106 |
+
<span className="font-black text-lg tracking-tight uppercase">Traffic<span className="text-orange-500 font-normal">AI</span></span>
|
| 107 |
</div>
|
| 108 |
+
<button
|
| 109 |
+
onClick={() => setIsDark(!isDark)}
|
| 110 |
+
className="p-2 rounded-full bg-slate-100 hover:bg-slate-200 text-slate-600 transition dark:bg-slate-800 dark:hover:bg-slate-700 dark:text-slate-400"
|
| 111 |
>
|
| 112 |
{isDark ? <Sun size={18} /> : <Moon size={18} />}
|
| 113 |
</button>
|
| 114 |
</header>
|
| 115 |
|
| 116 |
+
<div className="mx-auto max-w-[1500px] px-4 pt-8">
|
| 117 |
+
|
| 118 |
+
{/* Row 1: Top Aligned Hero and Dataset Toggle */}
|
| 119 |
+
<div className="grid grid-cols-1 xl:grid-cols-12 gap-8 lg:gap-12 items-end mb-8">
|
| 120 |
+
<div className="xl:col-span-8 xl:pl-4">
|
| 121 |
+
<div className="space-y-4">
|
| 122 |
+
<span className="inline-flex items-center gap-2 rounded-full border border-orange-200 bg-orange-50 px-4 py-1.5 text-xs font-semibold uppercase tracking-widest text-orange-600 dark:border-orange-500/40 dark:bg-orange-500/10 dark:text-orange-400">
|
| 123 |
+
<span className="h-1.5 w-1.5 rounded-full bg-orange-500"></span> AI Traffic Summarization
|
| 124 |
+
</span>
|
| 125 |
+
<h1 className="text-4xl md:text-5xl font-black tracking-tight text-slate-900 dark:text-white leading-tight">
|
| 126 |
+
Turn Traffic Chaos <br /> <span className="text-transparent bg-clip-text bg-gradient-to-r from-orange-500 to-orange-600 dark:from-orange-400 dark:to-orange-500">into Clarity</span>
|
| 127 |
+
</h1>
|
| 128 |
+
<p className="text-sm md:text-base text-slate-600 dark:text-slate-400 max-w-2xl font-medium">
|
| 129 |
+
Select a model below to generate instant summaries. The Dataset Preview on the right allows you to quickly load existing incident data.
|
| 130 |
+
</p>
|
| 131 |
+
</div>
|
| 132 |
+
</div>
|
| 133 |
+
<div className="xl:col-span-4 xl:pr-4 flex flex-col justify-end">
|
| 134 |
+
<DatasetToggle value={datasetTrack} onChange={setDatasetTrack} />
|
| 135 |
+
</div>
|
| 136 |
</div>
|
| 137 |
|
| 138 |
+
{/* Row 2: Parallel Grid of Cards */}
|
| 139 |
+
<div className="grid grid-cols-1 xl:grid-cols-12 gap-8 lg:gap-12 items-start">
|
| 140 |
+
|
| 141 |
+
{/* Main Summarizer Section */}
|
| 142 |
+
<div className="xl:col-span-8 flex flex-col xl:pl-4">
|
| 143 |
+
<SummarizerWidget
|
| 144 |
+
text={text}
|
| 145 |
+
setText={setText}
|
| 146 |
+
maxLength={maxLength}
|
| 147 |
+
setMaxLength={setMaxLength}
|
| 148 |
+
modelChoice={modelChoice}
|
| 149 |
+
setModelChoice={handleModelSelect}
|
| 150 |
+
onSummarize={handleSummarize}
|
| 151 |
+
loading={loading}
|
| 152 |
+
summary={summary}
|
| 153 |
+
/>
|
| 154 |
+
</div>
|
| 155 |
|
| 156 |
+
{/* Right Sidebar Section */}
|
| 157 |
+
<div className="xl:col-span-4 flex flex-col xl:pr-4 gap-8">
|
| 158 |
+
<div className="rounded-[24px] border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-800 dark:bg-[#0d1326] dark:shadow-xl relative overflow-hidden">
|
| 159 |
+
<div className="mb-6">
|
| 160 |
+
<h2 className="text-xl font-bold text-slate-900 dark:text-white">Dataset Preview</h2>
|
| 161 |
+
<p className="text-sm text-slate-500 dark:text-slate-400 mt-1">Select a sample to load it into the editor</p>
|
| 162 |
+
</div>
|
| 163 |
+
<div className="overflow-y-auto max-h-[600px] pr-2 -mr-2 space-y-4 custom-scroll">
|
| 164 |
+
<SampleGallery items={samples} onPick={setText} />
|
| 165 |
+
</div>
|
| 166 |
</div>
|
| 167 |
+
|
| 168 |
+
<BatchUpload />
|
| 169 |
</div>
|
| 170 |
|
|
|
|
|
|
|
|
|
|
| 171 |
</div>
|
| 172 |
</div>
|
| 173 |
</div>
|