feat: make client and project required when creating a job
- Both fields now show a validation error on submit if not selected - Labels updated to show required asterisk - Section always visible regardless of client list length Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ad67089b09
commit
0444e88178
1 changed files with 41 additions and 25 deletions
|
|
@ -126,6 +126,15 @@ export function NewJob() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!selectedClientId) {
|
||||
toast.toastOnly.error('Please select a client');
|
||||
return;
|
||||
}
|
||||
if (!selectedProjectId) {
|
||||
toast.toastOnly.error('Please select a project');
|
||||
return;
|
||||
}
|
||||
|
||||
const jobData: JobCreateRequest = {
|
||||
title: data.title,
|
||||
requested_outputs: {
|
||||
|
|
@ -208,6 +217,15 @@ export function NewJob() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!selectedClientId) {
|
||||
toast.toastOnly.error('Please select a client');
|
||||
return;
|
||||
}
|
||||
if (!selectedProjectId) {
|
||||
toast.toastOnly.error('Please select a project');
|
||||
return;
|
||||
}
|
||||
|
||||
await multiUpload.startUpload({
|
||||
requestedOutputs: {
|
||||
captions_vtt: data.captions_vtt,
|
||||
|
|
@ -699,40 +717,38 @@ export function NewJob() {
|
|||
)}
|
||||
|
||||
{/* Project */}
|
||||
{clients.length > 0 && (
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Client <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
value={selectedClientId}
|
||||
onChange={e => { setSelectedClientId(e.target.value); setSelectedProjectId(''); }}
|
||||
className={`w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${!selectedClientId ? 'border-gray-300' : 'border-gray-300'}`}
|
||||
disabled={isUploading}
|
||||
>
|
||||
<option value="">— Select client —</option>
|
||||
{clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
{selectedClientId && (
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Client <span className="text-gray-400 font-normal">(optional)</span>
|
||||
Project <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
value={selectedClientId}
|
||||
onChange={e => { setSelectedClientId(e.target.value); setSelectedProjectId(''); }}
|
||||
value={selectedProjectId}
|
||||
onChange={e => setSelectedProjectId(e.target.value)}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
disabled={isUploading}
|
||||
>
|
||||
<option value="">— No client —</option>
|
||||
{clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
|
||||
<option value="">— Select project —</option>
|
||||
{projects.filter(p => p.is_active).map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
{selectedClientId && (
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Project <span className="text-gray-400 font-normal">(optional)</span>
|
||||
</label>
|
||||
<select
|
||||
value={selectedProjectId}
|
||||
onChange={e => setSelectedProjectId(e.target.value)}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
disabled={isUploading}
|
||||
>
|
||||
<option value="">— No project —</option>
|
||||
{projects.filter(p => p.is_active).map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Brand Context */}
|
||||
<div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue