cookie-har-analyzer / frontend /src /components /AdvancedOptions.tsx
Hamza4100's picture
Upload 54 files
5aaf491 verified
Raw History Blame Contribute Delete
5.25 kB
import { useState } from 'react';
import { ChevronDown, ChevronUp, Settings2 } from 'lucide-react';
import { AnalysisOptions } from '../types';
interface AdvancedOptionsProps {
options: AnalysisOptions;
onChange: (opts: Partial<AnalysisOptions>) => void;
}
function Toggle({
id,
label,
description,
checked,
onChange,
}: {
id: string;
label: string;
description?: string;
checked: boolean;
onChange: (v: boolean) => void;
}) {
return (
<label
htmlFor={id}
className="flex items-start gap-3 cursor-pointer group"
>
<div className="relative flex-shrink-0 mt-0.5">
<input
type="checkbox"
id={id}
checked={checked}
onChange={e => onChange(e.target.checked)}
className="sr-only"
/>
<div
className={`w-9 h-5 rounded-full border transition-all duration-200 ${
checked
? 'bg-blue-600 border-blue-500'
: 'bg-white/5 border-white/15 group-hover:border-white/25'
}`}
>
<div
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white shadow transition-all duration-200 ${
checked ? 'translate-x-4' : 'translate-x-0.5'
}`}
/>
</div>
</div>
<div>
<p className="text-sm font-medium text-gray-200">{label}</p>
{description && <p className="text-xs text-gray-500 mt-0.5">{description}</p>}
</div>
</label>
);
}
function NumberInput({
id,
label,
value,
min,
max,
onChange,
}: {
id: string;
label: string;
value: number;
min: number;
max: number;
onChange: (v: number) => void;
}) {
return (
<div className="flex items-center justify-between gap-4">
<label htmlFor={id} className="text-sm text-gray-300 flex-1">{label}</label>
<input
type="number"
id={id}
value={value}
min={min}
max={max}
onChange={e => onChange(Number(e.target.value))}
className="w-20 input-field text-center py-1"
/>
</div>
);
}
export function AdvancedOptions({ options, onChange }: AdvancedOptionsProps) {
const [open, setOpen] = useState(false);
return (
<div className="card overflow-hidden">
<button
id="advanced-options-toggle"
className="w-full flex items-center justify-between px-4 py-3 text-left hover:bg-white/[0.02] transition-colors"
onClick={() => setOpen(o => !o)}
>
<span className="flex items-center gap-2 text-sm font-medium text-gray-300">
<Settings2 className="w-4 h-4 text-gray-500" />
Advanced Options
</span>
{open ? (
<ChevronUp className="w-4 h-4 text-gray-500" />
) : (
<ChevronDown className="w-4 h-4 text-gray-500" />
)}
</button>
{open && (
<div className="px-4 pb-4 divider border-t pt-4 space-y-4 animate-fade-in">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<Toggle
id="opt-case-sensitive"
label="Case-sensitive matching"
description="Disable to also find case-insensitive matches"
checked={options.case_sensitive}
onChange={v => onChange({ case_sensitive: v })}
/>
<Toggle
id="opt-url-decoded"
label="Search URL-decoded values"
description="Matches percent-encoded representations"
checked={options.search_url_decoded}
onChange={v => onChange({ search_url_decoded: v })}
/>
<Toggle
id="opt-include-req-bodies"
label="Include request bodies"
description="Search POST/PUT body content"
checked={options.include_request_bodies}
onChange={v => onChange({ include_request_bodies: v })}
/>
<Toggle
id="opt-include-resp-bodies"
label="Include response bodies"
description="Search response content (slower for large HAR)"
checked={options.include_response_bodies}
onChange={v => onChange({ include_response_bodies: v })}
/>
</div>
<div className="space-y-3 pt-2 border-t border-white/[0.06]">
<NumberInput
id="opt-min-snippet"
label="Minimum snippet length"
value={options.min_snippet_length}
min={2}
max={20}
onChange={v => onChange({ min_snippet_length: v })}
/>
<NumberInput
id="opt-max-results"
label="Max results per cookie"
value={options.max_results_per_cookie}
min={10}
max={1000}
onChange={v => onChange({ max_results_per_cookie: v })}
/>
<NumberInput
id="opt-context-chars"
label="Context window (chars)"
value={options.context_chars}
min={20}
max={300}
onChange={v => onChange({ context_chars: v })}
/>
</div>
</div>
)}
</div>
);
}