import React, { useEffect, useState } from 'react' import { useRouter } from 'next/router' import { useSnapshot } from 'valtio' import { useTranslation } from 'next-i18next' import JobDropdown from '~components/JobDropdown' import JobImage from '~components/JobImage' import JobSkillItem from '~components/JobSkillItem' import SearchModal from '~components/SearchModal' import api from '~utils/api' import { appState } from '~utils/appState' import type { JobSkillObject, SearchableObject } from '~types' import './index.scss' // Props interface Props { job?: Job jobSkills: JobSkillObject jobAccessory?: JobAccessory editable: boolean saveJob: (job?: Job) => void saveSkill: (skill: JobSkill, position: number) => void saveAccessory: (accessory: JobAccessory) => void } const JobSection = (props: Props) => { const { party } = useSnapshot(appState) const { t } = useTranslation('common') const router = useRouter() const locale = router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en' // Data state const [job, setJob] = useState() const [imageUrl, setImageUrl] = useState('') const [numSkills, setNumSkills] = useState(4) const [skills, setSkills] = useState<{ [key: number]: JobSkill | undefined }>( [] ) const [accessories, setAccessories] = useState([]) const [currentAccessory, setCurrentAccessory] = useState< JobAccessory | undefined >() // Refs const selectRef = React.createRef() useEffect(() => { // Set current job based on ID setJob(props.job) setSkills({ 0: props.jobSkills[0], 1: props.jobSkills[1], 2: props.jobSkills[2], 3: props.jobSkills[3], }) setCurrentAccessory(props.jobAccessory) if (selectRef.current && props.job) selectRef.current.value = props.job.id }, [props]) useEffect(() => { generateImageUrl() }) useEffect(() => { if (job) { if ((party.job && job.id != party.job.id) || !party.job) appState.party.job = job if (job.row === '1') setNumSkills(3) else setNumSkills(4) fetchJobAccessories() } }, [job]) // Data fetching async function fetchJobAccessories() { if (job && job.accessory) { const response = await api.jobAccessoriesForJob(job.id) const jobAccessories: JobAccessory[] = response.data setAccessories(jobAccessories) } } function receiveJob(job?: Job) { setJob(job) props.saveJob(job) } function handleAccessorySelected(value: string) { const accessory = accessories.find((accessory) => accessory.id === value) if (accessory) { setCurrentAccessory(accessory) props.saveAccessory(accessory) } } function generateImageUrl() { let imgSrc = '' if (job) { const slug = job?.name.en.replaceAll(' ', '-').toLowerCase() const gender = party.user && party.user.gender == 1 ? 'b' : 'a' imgSrc = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/jobs/${slug}_${gender}.png` } setImageUrl(imgSrc) } const canEditSkill = (skill?: JobSkill) => { // If there is a job and a skill present in the slot if (job && job.id !== '-1') { // If the skill's job is one of the job's main skill if (skill && skill.job.id === job.id && skill.main) return false return props.editable } else return false } const skillItem = (index: number, editable: boolean) => { return ( ) } const editableSkillItem = (index: number) => { return ( {skillItem(index, true)} ) } function saveJobSkill(object: SearchableObject, position: number) { const skill = object as JobSkill const newSkills = skills newSkills[position] = skill setSkills(newSkills) props.saveSkill(skill, position) } const emptyJobLabel = (

{t('no_job')}

) const filledJobLabel = (
{job?.name[locale]}

{job?.name[locale]}

) function jobLabel() { return job ? filledJobLabel : emptyJobLabel } // Render: JSX components return (
{props.editable ? ( ) : (
{party.job ? ( {party.job.name[locale]} ) : ( '' )}

{party.job ? party.job.name[locale] : t('no_job')}

)}
    {[...Array(numSkills)].map((e, i) => (
  • {canEditSkill(skills[i]) ? editableSkillItem(i) : skillItem(i, false)}
  • ))}
) } export default JobSection