site settigns

This commit is contained in:
alorig
2025-11-26 06:08:44 +05:00
parent 51bb2eafd0
commit 451594bd29
6 changed files with 2981 additions and 256 deletions

View File

@@ -66,17 +66,8 @@ export default function SiteList() {
// Site Management Modals
const [selectedSite, setSelectedSite] = useState<Site | null>(null);
const [showSiteModal, setShowSiteModal] = useState(false);
const [showSectorsModal, setShowSectorsModal] = useState(false);
const [isSaving, setIsSaving] = useState(false);
const [togglingSiteId, setTogglingSiteId] = useState<number | null>(null);
const [industries, setIndustries] = useState<Industry[]>([]);
const [selectedIndustry, setSelectedIndustry] = useState<string>('');
const [selectedSectors, setSelectedSectors] = useState<string[]>([]);
const [isSelectingSectors, setIsSelectingSectors] = useState(false);
const [userPreferences, setUserPreferences] = useState<{
selectedIndustry?: string;
selectedSectors?: string[];
} | null>(null);
// Form state for site creation/editing
const [formData, setFormData] = useState({
@@ -95,8 +86,6 @@ export default function SiteList() {
useEffect(() => {
loadSites();
loadIndustries();
loadUserPreferences();
}, []);
const loadUserPreferences = async () => {
@@ -155,33 +144,6 @@ export default function SiteList() {
}
};
const loadIndustries = async () => {
try {
const response = await fetchIndustries();
let allIndustries = response.industries || [];
// Filter to show only user's pre-selected industries/sectors from account preferences
try {
const { fetchAccountSetting } = await import('../../services/api');
const setting = await fetchAccountSetting('user_preferences');
const preferences = setting.config as { selectedIndustry?: string; selectedSectors?: string[] } | undefined;
if (preferences?.selectedIndustry) {
// Filter industries to only show the user's pre-selected industry
allIndustries = allIndustries.filter(i => i.slug === preferences.selectedIndustry);
}
} catch (error: any) {
// 404 means preferences don't exist yet - show all industries (expected for new users)
// 500 and other errors - show all industries (graceful degradation)
// Silently handle errors - user can still use the page
}
setIndustries(allIndustries);
} catch (error: any) {
console.error('Failed to load industries:', error);
}
};
const applyFilters = () => {
let filtered = [...sites];
@@ -638,15 +600,6 @@ export default function SiteList() {
</div>
<div className="flex items-center justify-between">
<div className="flex gap-2">
<Button
variant="outline"
size="sm"
onClick={() => handleSettings(site)}
title="Configure Sectors"
>
<GridIcon className="w-4 h-4 mr-1" />
<span className="text-xs">Sectors</span>
</Button>
<Button
variant="outline"
size="sm"
@@ -927,110 +880,6 @@ export default function SiteList() {
fields={getSiteFormFields()}
isLoading={isSaving}
/>
{/* Sectors Selection Modal */}
<FormModal
isOpen={showSectorsModal}
onClose={() => setShowSectorsModal(false)}
onSubmit={handleSelectSectors}
title={selectedSite ? `Configure Sectors for ${selectedSite.name}` : 'Configure Sectors'}
submitLabel={isSelectingSectors ? 'Saving...' : 'Save Sectors'}
cancelLabel="Cancel"
isLoading={isSelectingSectors}
className="max-w-2xl"
customBody={
<div className="space-y-6">
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Select Industry
</label>
<select
value={selectedIndustry}
onChange={(e) => {
setSelectedIndustry(e.target.value);
setSelectedSectors([]);
}}
className="h-9 w-full rounded-lg border border-gray-300 bg-transparent px-3 py-2 text-sm shadow-theme-xs text-gray-800 placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800"
>
<option value="">Select an industry...</option>
{industries.map((industry) => (
<option key={industry.slug} value={industry.slug}>
{industry.name}
</option>
))}
</select>
{selectedIndustry && (
<p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
{industries.find(i => i.slug === selectedIndustry)?.description}
</p>
)}
</div>
{selectedIndustry && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Select Sectors (max 5)
</label>
<div className="space-y-2 max-h-64 overflow-y-auto border border-gray-200 rounded-lg p-4 dark:border-gray-700">
{getIndustrySectors().map((sector) => (
<label
key={sector.slug}
className="flex items-start space-x-3 p-3 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800 cursor-pointer"
>
<input
type="checkbox"
checked={selectedSectors.includes(sector.slug)}
onChange={(e) => {
if (e.target.checked) {
if (selectedSectors.length >= 5) {
toast.error('Maximum 5 sectors allowed per site');
return;
}
setSelectedSectors([...selectedSectors, sector.slug]);
} else {
setSelectedSectors(selectedSectors.filter(s => s !== sector.slug));
}
}}
className="mt-1 h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
<div className="flex-1">
<div className="font-medium text-sm text-gray-900 dark:text-white">
{sector.name}
</div>
<div className="text-xs text-gray-500 dark:text-gray-400 mt-1">
{sector.description}
</div>
</div>
</label>
))}
</div>
<p className="mt-2 text-xs text-gray-500 dark:text-gray-400">
Selected: {selectedSectors.length} / 5 sectors
</p>
</div>
)}
</div>
}
customFooter={
<div className="flex justify-end gap-3 pt-4 border-t border-gray-200 dark:border-gray-700">
<Button
type="button"
variant="outline"
onClick={() => setShowSectorsModal(false)}
disabled={isSelectingSectors}
>
Cancel
</Button>
<Button
type="submit"
variant="primary"
disabled={!selectedIndustry || selectedSectors.length === 0 || isSelectingSectors}
>
{isSelectingSectors ? 'Saving...' : 'Save Sectors'}
</Button>
</div>
}
/>
</div>
);
}