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:
Vadym Samoilenko 2026-04-29 15:43:50 +01:00
parent ad67089b09
commit 0444e88178

View file

@ -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>