fix: State dropdown and locked platform in schedule modal
- State Code → State dropdown with available states - Platform field locked to 'dutchie' (read-only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -308,6 +308,31 @@ router.get('/retry-stats', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Mark all proxies as active
|
||||
router.post('/activate-all', requireRole('superadmin', 'admin'), async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(`
|
||||
UPDATE proxies
|
||||
SET active = true,
|
||||
failure_count = 0,
|
||||
consecutive_403_count = 0
|
||||
WHERE active = false
|
||||
RETURNING id
|
||||
`);
|
||||
|
||||
const countResult = await pool.query(`SELECT COUNT(*) as total FROM proxies`);
|
||||
|
||||
res.json({
|
||||
message: `Activated ${result.rowCount} proxies`,
|
||||
activated: result.rowCount,
|
||||
total: parseInt(countResult.rows[0].total)
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error activating proxies:', error);
|
||||
res.status(500).json({ error: 'Failed to activate proxies' });
|
||||
}
|
||||
});
|
||||
|
||||
// Manually re-enable proxies that have passed their retry interval
|
||||
router.post('/reenable-failed', requireRole('superadmin', 'admin'), async (req, res) => {
|
||||
try {
|
||||
|
||||
2
cannaiq/dist/index.html
vendored
2
cannaiq/dist/index.html
vendored
@@ -7,7 +7,7 @@
|
||||
<title>CannaIQ - Cannabis Menu Intelligence Platform</title>
|
||||
<meta name="description" content="CannaIQ provides real-time cannabis dispensary menu data, product tracking, and analytics for dispensaries across Arizona." />
|
||||
<meta name="keywords" content="cannabis, dispensary, menu, products, analytics, Arizona" />
|
||||
<script type="module" crossorigin src="/assets/index-5TyJIiu6.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-onY4oipq.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B0KNyXCG.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -410,13 +410,21 @@ function ScheduleEditModal({ isOpen, schedule, onClose, onSave }: ScheduleEditMo
|
||||
const [intervalHours, setIntervalHours] = useState(4);
|
||||
const [priority, setPriority] = useState(0);
|
||||
const [stateCode, setStateCode] = useState('');
|
||||
const [platform, setPlatform] = useState('dutchie');
|
||||
const [platform] = useState('dutchie'); // Fixed to dutchie only
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [availableStates, setAvailableStates] = useState<string[]>([]);
|
||||
|
||||
const isNew = !schedule;
|
||||
const isImmutable = schedule?.is_immutable ?? false;
|
||||
|
||||
// Fetch available states on mount
|
||||
useEffect(() => {
|
||||
api.getOrchestratorStates().then(data => {
|
||||
setAvailableStates(data.states?.map((s: any) => s.state) || []);
|
||||
}).catch(console.error);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (schedule) {
|
||||
setName(schedule.name);
|
||||
@@ -426,7 +434,6 @@ function ScheduleEditModal({ isOpen, schedule, onClose, onSave }: ScheduleEditMo
|
||||
setIntervalHours(schedule.interval_hours);
|
||||
setPriority(schedule.priority);
|
||||
setStateCode(schedule.state_code || '');
|
||||
setPlatform(schedule.platform || 'dutchie');
|
||||
} else {
|
||||
// Reset for new schedule
|
||||
setName('');
|
||||
@@ -436,7 +443,6 @@ function ScheduleEditModal({ isOpen, schedule, onClose, onSave }: ScheduleEditMo
|
||||
setIntervalHours(4);
|
||||
setPriority(0);
|
||||
setStateCode('');
|
||||
setPlatform('dutchie');
|
||||
}
|
||||
setError(null);
|
||||
}, [schedule, isOpen]);
|
||||
@@ -587,30 +593,28 @@ function ScheduleEditModal({ isOpen, schedule, onClose, onSave }: ScheduleEditMo
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">State Code</label>
|
||||
<input
|
||||
type="text"
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">State</label>
|
||||
<select
|
||||
value={stateCode}
|
||||
onChange={(e) => setStateCode(e.target.value.toUpperCase())}
|
||||
placeholder="e.g., AZ"
|
||||
maxLength={2}
|
||||
onChange={(e) => setStateCode(e.target.value)}
|
||||
disabled={isImmutable}
|
||||
className={`w-full px-3 py-2 border border-gray-200 rounded-lg ${
|
||||
isImmutable ? 'bg-gray-100 text-gray-500 cursor-not-allowed' : ''
|
||||
}`}
|
||||
/>
|
||||
>
|
||||
<option value="">All States</option>
|
||||
{availableStates.map(state => (
|
||||
<option key={state} value={state}>{state}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Platform</label>
|
||||
<input
|
||||
type="text"
|
||||
value={platform}
|
||||
onChange={(e) => setPlatform(e.target.value)}
|
||||
placeholder="e.g., dutchie"
|
||||
disabled={isImmutable}
|
||||
className={`w-full px-3 py-2 border border-gray-200 rounded-lg ${
|
||||
isImmutable ? 'bg-gray-100 text-gray-500 cursor-not-allowed' : ''
|
||||
}`}
|
||||
disabled
|
||||
className="w-full px-3 py-2 border border-gray-200 rounded-lg bg-gray-100 text-gray-500 cursor-not-allowed"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user