Commit workspace changes
This commit is contained in:
101
resources/js/Pages/Studio/StudioGroupRecruitment.jsx
Normal file
101
resources/js/Pages/Studio/StudioGroupRecruitment.jsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import React from 'react'
|
||||
import { useForm, usePage } from '@inertiajs/react'
|
||||
import StudioLayout from '../../Layouts/StudioLayout'
|
||||
|
||||
function toggleItem(list, value) {
|
||||
return list.includes(value) ? list.filter((item) => item !== value) : [...list, value]
|
||||
}
|
||||
|
||||
export default function StudioGroupRecruitment() {
|
||||
const { props } = usePage()
|
||||
const recruitment = props.recruitment || {}
|
||||
const form = useForm({
|
||||
is_recruiting: Boolean(recruitment.is_recruiting),
|
||||
headline: recruitment.headline || '',
|
||||
description: recruitment.description || '',
|
||||
roles_json: Array.isArray(recruitment.roles) ? recruitment.roles : [],
|
||||
skills_json: Array.isArray(recruitment.skills) ? recruitment.skills : [],
|
||||
contact_mode: recruitment.contact_mode || 'join_request',
|
||||
visibility: recruitment.visibility || 'public',
|
||||
})
|
||||
|
||||
const submit = (event) => {
|
||||
event.preventDefault()
|
||||
form.patch(props.updateUrl)
|
||||
}
|
||||
|
||||
return (
|
||||
<StudioLayout title={props.title} subtitle={props.description}>
|
||||
<form onSubmit={submit} className="grid gap-6 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]">
|
||||
<section className="rounded-[28px] border border-white/10 bg-white/[0.03] p-5">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold text-white">Recruitment profile</h2>
|
||||
<p className="mt-1 text-sm text-slate-400">Describe what the group is looking for and how applicants should reach you.</p>
|
||||
</div>
|
||||
<label className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-4 py-2 text-sm text-white">
|
||||
<input type="checkbox" checked={form.data.is_recruiting} onChange={(event) => form.setData('is_recruiting', event.target.checked)} />
|
||||
Recruiting now
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 grid gap-4">
|
||||
<label className="grid gap-2 text-sm text-slate-300">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Headline</span>
|
||||
<input value={form.data.headline} onChange={(event) => form.setData('headline', event.target.value)} className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" />
|
||||
</label>
|
||||
<label className="grid gap-2 text-sm text-slate-300">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Description</span>
|
||||
<textarea value={form.data.description} onChange={(event) => form.setData('description', event.target.value)} rows={7} className="rounded-[24px] border border-white/10 bg-black/20 px-4 py-3 text-white outline-none" />
|
||||
</label>
|
||||
<label className="grid gap-2 text-sm text-slate-300">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Roles</span>
|
||||
<div className="flex flex-wrap gap-2 rounded-[24px] border border-white/10 bg-black/20 p-4">
|
||||
{(Array.isArray(props.roleOptions) ? props.roleOptions : []).map((option) => {
|
||||
const selected = form.data.roles_json.includes(option.value)
|
||||
|
||||
return <button key={option.value} type="button" onClick={() => form.setData('roles_json', toggleItem(form.data.roles_json, option.value))} className={`rounded-full border px-3 py-1.5 text-xs font-semibold ${selected ? 'border-emerald-300/20 bg-emerald-400/10 text-emerald-100' : 'border-white/10 bg-white/[0.03] text-slate-300'}`}>{option.label}</button>
|
||||
})}
|
||||
</div>
|
||||
</label>
|
||||
<label className="grid gap-2 text-sm text-slate-300">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Skills</span>
|
||||
<div className="flex flex-wrap gap-2 rounded-[24px] border border-white/10 bg-black/20 p-4">
|
||||
{(Array.isArray(props.skillOptions) ? props.skillOptions : []).map((option) => {
|
||||
const selected = form.data.skills_json.includes(option.value)
|
||||
|
||||
return <button key={option.value} type="button" onClick={() => form.setData('skills_json', toggleItem(form.data.skills_json, option.value))} className={`rounded-full border px-3 py-1.5 text-xs font-semibold ${selected ? 'border-sky-300/20 bg-sky-300/10 text-sky-100' : 'border-white/10 bg-white/[0.03] text-slate-300'}`}>{option.label}</button>
|
||||
})}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="rounded-[28px] border border-white/10 bg-white/[0.03] p-5">
|
||||
<h2 className="text-xl font-semibold text-white">Application settings</h2>
|
||||
<div className="mt-5 grid gap-4">
|
||||
<label className="grid gap-2 text-sm text-slate-300">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Contact mode</span>
|
||||
<select value={form.data.contact_mode} onChange={(event) => form.setData('contact_mode', event.target.value)} className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none">
|
||||
{(Array.isArray(props.contactModes) ? props.contactModes : []).map((option) => <option key={option.value} value={option.value}>{option.label}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
<label className="grid gap-2 text-sm text-slate-300">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Visibility</span>
|
||||
<select value={form.data.visibility} onChange={(event) => form.setData('visibility', event.target.value)} className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-white outline-none">
|
||||
{(Array.isArray(props.visibilityOptions) ? props.visibilityOptions : []).map((option) => <option key={option.value} value={option.value}>{option.label}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
<div className="rounded-[24px] border border-white/10 bg-black/20 p-4 text-sm text-slate-300">
|
||||
<p className="font-semibold text-white">Public preview</p>
|
||||
<p className="mt-2">{form.data.headline || 'No headline yet.'}</p>
|
||||
<p className="mt-2 text-slate-400">{form.data.description || 'Recruitment copy will show here once you add it.'}</p>
|
||||
{form.data.roles_json.length > 0 ? <div className="mt-3 flex flex-wrap gap-2">{form.data.roles_json.map((role) => <span key={role} className="rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs font-semibold text-white">{role}</span>)}</div> : null}
|
||||
</div>
|
||||
<button type="submit" disabled={form.processing} className="rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-3 text-sm font-semibold text-sky-100 disabled:opacity-60">Save recruitment profile</button>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
</StudioLayout>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user