heymenn's picture
initial commit
4b1a31e
import React from 'react';
import { WORKING_GROUPS } from '../constants';
import { Search, Loader2 } from 'lucide-react';
interface FilterBarProps {
onFetch: (wg: string, meeting: string) => void;
isFetching: boolean;
}
const FilterBar: React.FC<FilterBarProps> = ({ onFetch, isFetching }) => {
const [selectedWg, setSelectedWg] = React.useState(WORKING_GROUPS[0]);
const [meetings, setMeetings] = React.useState<Record<string, string>>({});
const [selectedMeeting, setSelectedMeeting] = React.useState('');
const [isLoadingMeetings, setIsLoadingMeetings] = React.useState(false);
React.useEffect(() => {
const fetchMeetings = async () => {
setIsLoadingMeetings(true);
try {
const response = await fetch('https://organizedprogrammers-docxtract.hf.space/docs/get_meetings',
{ method: 'POST', body: JSON.stringify({ "working_group": selectedWg }), headers: { 'Content-Type': 'application/json' } });
if (response.ok) {
const data = await response.json();
if (data.meetings) {
setMeetings(data.meetings);
const firstMeetingValue = Object.values(data.meetings)[0] as string;
if (firstMeetingValue) {
setSelectedMeeting(firstMeetingValue);
}
}
} else {
console.error("Failed to fetch meetings");
}
} catch (error) {
console.error("Error fetching meetings:", error);
} finally {
setIsLoadingMeetings(false);
}
};
fetchMeetings();
}, [selectedWg]);
return (
<div className="bg-white p-6 rounded-xl shadow-sm border border-slate-200 mb-6">
<div className="grid grid-cols-1 md:grid-cols-12 gap-4 items-end">
<div className="md:col-span-3">
<label className="block text-sm font-medium text-slate-600 mb-1">Working Group</label>
<div className="relative">
<select
value={selectedWg}
onChange={(e) => setSelectedWg(e.target.value)}
className="w-full appearance-none bg-slate-50 border border-slate-300 text-slate-700 py-2.5 px-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
{WORKING_GROUPS.map(wg => <option key={wg} value={wg}>{wg}</option>)}
</select>
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-500">
<svg className="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" /></svg>
</div>
</div>
</div>
<div className="md:col-span-4">
<label className="block text-sm font-medium text-slate-600 mb-1">Meeting</label>
<div className="relative">
<select
value={selectedMeeting}
onChange={(e) => setSelectedMeeting(e.target.value)}
disabled={isLoadingMeetings}
className="w-full appearance-none bg-slate-50 border border-slate-300 text-slate-700 py-2.5 px-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50"
>
{isLoadingMeetings ? (
<option>Loading meetings...</option>
) : (
Object.entries(meetings).map(([displayName, value]) => (
<option key={value} value={value}>{displayName}</option>
))
)}
</select>
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-500">
<svg className="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" /></svg>
</div>
</div>
</div>
<div className="md:col-span-3">
<label className="block text-sm font-medium text-slate-600 mb-2">Doc Types</label>
<div className="flex space-x-4">
<label className="inline-flex items-center">
<input type="checkbox" className="form-checkbox text-blue-600 h-4 w-4 rounded border-slate-300" defaultChecked />
<span className="ml-2 text-slate-700">CR</span>
</label>
<label className="inline-flex items-center">
<input type="checkbox" className="form-checkbox text-blue-600 h-4 w-4 rounded border-slate-300" defaultChecked />
<span className="ml-2 text-slate-700">PCR</span>
</label>
</div>
</div>
<div className="md:col-span-2">
<button
onClick={() => onFetch(selectedWg, selectedMeeting)}
disabled={isFetching}
className="w-full flex items-center justify-center bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2.5 px-4 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
{isFetching ? (
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
) : (
<Search className="w-4 h-4 mr-2" />
)}
Fetch Docs
</button>
</div>
</div>
</div>
);
};
export default FilterBar;