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 so async callbacks always see the latest values (avoids stale closures)
 
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
- // Single source of truth for summarization — reads from refs to avoid stale state
58
- const runSummarize = async (modelId, overrideLength = null) => {
 
59
  const currentText = textRef.current;
60
- const currentLength = overrideLength !== null ? overrideLength : maxLengthRef.current;
61
  const currentTrack = datasetTrackRef.current;
62
- if (!currentText) return;
 
 
63
  setLoading(true);
64
  setSummary("");
65
  try {
66
  const data = await summarizeText({
67
  text: currentText,
68
- model_choice: modelId,
69
  max_length: currentLength,
70
  dataset_track: currentTrack
71
  });
@@ -77,13 +84,13 @@ export default function Home() {
77
  }
78
  };
79
 
80
- // Called by Summarize Now button and slider release
81
  const handleSummarize = (overrideLength = null) => {
82
  if (overrideLength !== null) setMaxLength(overrideLength);
83
- runSummarize(modelChoice, overrideLength);
84
  };
85
 
86
- // Called when user clicks a model card — immediately re-runs with that model
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
- {/* Header */}
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
- <div className="h-6 w-6 rounded border-2 border-orange-500 bg-orange-100 dark:bg-orange-500/20"></div>
99
- <span className="font-black text-lg tracking-tight">TRAFFIC<span className="text-orange-500 font-normal">AI</span></span>
100
  </div>
101
- <button
102
- onClick={() => setIsDark(!isDark)}
103
- 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"
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-5 grid grid-cols-1 xl:grid-cols-12 gap-8 lg:gap-12 items-start">
110
-
111
- {/* Left Column */}
112
- <div className="xl:col-span-8 flex flex-col xl:pl-4">
113
- <SummarizerWidget
114
- text={text}
115
- setText={setText}
116
- maxLength={maxLength}
117
- setMaxLength={setMaxLength}
118
- modelChoice={modelChoice}
119
- setModelChoice={handleModelSelect}
120
- onSummarize={handleSummarize}
121
- loading={loading}
122
- summary={summary}
123
- />
 
 
 
 
 
124
  </div>
125
 
126
- {/* Right Sidebar */}
127
- <div className="xl:col-span-4 flex flex-col xl:pr-4 pt-5 gap-5">
128
-
129
- {/* Dataset Track Toggle — always at top */}
130
- <DatasetToggle value={datasetTrack} onChange={setDatasetTrack} />
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
- {/* Dataset Preview no artificial spacer, sits right below toggle */}
133
- <div className="rounded-[24px] border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-800 dark:bg-[#0d1326] dark:shadow-xl overflow-hidden">
134
- <div className="mb-5">
135
- <h2 className="text-xl font-bold text-slate-900 dark:text-white">Dataset Preview</h2>
136
- <p className="text-sm text-slate-500 dark:text-slate-400 mt-1">Select a sample to load it into the editor</p>
137
- </div>
138
- <div className="overflow-y-auto max-h-[560px] pr-1 space-y-4 custom-scroll">
139
- <SampleGallery items={samples} onPick={setText} />
 
 
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>