stadtwerke/innungsapp/apps/admin/app/dashboard/stellen/neu/page.tsx

183 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { trpc } from '@/lib/trpc-client'
import { getTrpcErrorMessage } from '@/lib/trpc-error'
import Link from 'next/link'
export default function StelleNeuPage() {
const router = useRouter()
const { data: members } = trpc.members.list.useQuery({})
const createMutation = trpc.stellen.createForMember.useMutation({
onSuccess: () => router.push('/dashboard/stellen'),
})
const [form, setForm] = useState({
memberId: '',
sparte: '',
stellenAnz: 1,
verguetung: '',
lehrjahr: '',
beschreibung: '',
kontaktEmail: '',
kontaktName: '',
})
function handleSubmit(e: React.FormEvent) {
e.preventDefault()
if (!form.memberId) return
createMutation.mutate({
...form,
stellenAnz: Number(form.stellenAnz),
verguetung: form.verguetung || undefined,
lehrjahr: form.lehrjahr || undefined,
beschreibung: form.beschreibung || undefined,
kontaktName: form.kontaktName || undefined,
})
}
const inputClass =
'w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent'
return (
<div className="max-w-2xl space-y-6">
<div className="flex items-center gap-3">
<Link href="/dashboard/stellen" className="text-xs text-gray-400 hover:text-gray-600 uppercase tracking-wide">
Zurück
</Link>
<span className="text-gray-200">/</span>
<h1 className="text-2xl font-bold text-gray-900">Stelle anlegen</h1>
</div>
<form onSubmit={handleSubmit} className="bg-white rounded-lg border p-6 space-y-6">
{/* Betrieb */}
<div>
<p className="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3">Betrieb</p>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Mitglied / Betrieb *</label>
<select
required
value={form.memberId}
onChange={(e) => {
const selected = members?.find((m) => m.id === e.target.value)
setForm({ ...form, memberId: e.target.value, sparte: selected?.sparte ?? form.sparte })
}}
className={inputClass}
>
<option value="">Mitglied auswählen...</option>
{members?.map((m) => (
<option key={m.id} value={m.id}>
{m.betrieb} {m.name}
</option>
))}
</select>
</div>
</div>
{/* Stellendetails */}
<div className="border-t pt-5">
<p className="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3">Stellendetails</p>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Sparte *</label>
<input
required
value={form.sparte}
onChange={(e) => setForm({ ...form, sparte: e.target.value })}
placeholder="z.B. Elektrotechnik"
className={inputClass}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Anzahl Stellen</label>
<input
type="number"
min={1}
value={form.stellenAnz}
onChange={(e) => setForm({ ...form, stellenAnz: Number(e.target.value) })}
className={inputClass}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Lehrjahr</label>
<input
value={form.lehrjahr}
onChange={(e) => setForm({ ...form, lehrjahr: e.target.value })}
placeholder="z.B. 1. Lehrjahr"
className={inputClass}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Vergütung</label>
<input
value={form.verguetung}
onChange={(e) => setForm({ ...form, verguetung: e.target.value })}
placeholder="z.B. 650 € / Monat"
className={inputClass}
/>
</div>
<div className="col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">Beschreibung</label>
<textarea
rows={3}
value={form.beschreibung}
onChange={(e) => setForm({ ...form, beschreibung: e.target.value })}
placeholder="Aufgaben, Anforderungen, ..."
className={inputClass}
/>
</div>
</div>
</div>
{/* Kontakt */}
<div className="border-t pt-5">
<p className="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3">Kontakt</p>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Kontakt-E-Mail *</label>
<input
type="email"
required
value={form.kontaktEmail}
onChange={(e) => setForm({ ...form, kontaktEmail: e.target.value })}
placeholder="bewerbung@betrieb.de"
className={inputClass}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Ansprechpartner</label>
<input
value={form.kontaktName}
onChange={(e) => setForm({ ...form, kontaktName: e.target.value })}
placeholder="Max Mustermann"
className={inputClass}
/>
</div>
</div>
</div>
{createMutation.error && (
<p className="text-sm text-red-600 bg-red-50 px-4 py-2 rounded-lg">
{getTrpcErrorMessage(createMutation.error)}
</p>
)}
<div className="flex gap-3 pt-2 border-t">
<button
type="submit"
disabled={createMutation.isPending || !form.memberId}
className="bg-brand-500 text-white px-6 py-2 rounded-lg text-sm font-medium hover:bg-brand-600 disabled:opacity-60 transition-colors"
>
{createMutation.isPending ? 'Wird gespeichert...' : 'Stelle anlegen'}
</button>
<Link href="/dashboard/stellen" className="px-6 py-2 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-100 transition-colors">
Abbrechen
</Link>
</div>
</form>
</div>
)
}