<template>
<div class="justify-center">
<NForm
ref="formRef"
:disabled="isEdited"
:model="model"
:rules="rules"
class="flex flex-col gap-y-10 sm:w-full md:w-full lg:w-full xl:px-20"
label-placement="left"
:label-width="200"
require-mark-placement="right-hanging"
@submit="handleFormSubmit"
>
<NCard>
<NH2 class="text-center">
{{ $t('label.information') }}
</NH2>
<NFormItem :label="$t('label.name')" path="name">
<NInput
v-model:value="model.name"
:maxlength="MAX_INPUT_NAME"
show-count
/>
</NFormItem>
<NFormItem :label="$t('label.description')" path="description">
<NInput
v-model:value="model.description"
type="textarea"
:maxlength="MAX_INPUT_DESC"
show-count
/>
</NFormItem>
<NFormItem :label="$t('label.assignee')" path="assignee">
<NSelect
v-model:value="model.assignee_id"
:options="userListItemOptions"
:placeholder="$t('label.select', { attr: $t('label.assignee') })"
/>
</NFormItem>
<NFormItem :label="$t('label.watchers')" path="watchers">
<NSelect
v-model:value="model.watchers"
multiple
:options="userListItemOptions"
/>
</NFormItem>
</NCard>
<NCard>
<div class="flex gap-x-5">
<NCard>
<QuestImageUpload
:disabled="isEdited"
:default-image="model.files_picture"
@upload="handleUploadImage"
/>
</NCard>
<NCard>
<QuestImageUpload
:path="$t('label.proof')"
:disabled="isEdited"
:default-image="model.proof_url"
@upload="handleUploadProof"
/>
</NCard>
</div>
</NCard>
<NCard>
<NH2 class="text-center">
{{ $t('label.endorsement') }} / {{ $t('label.duration') }}
</NH2>
<NCard>
<NFormItem
:label="$t('label.numberOfEndorsement')"
path="number_of_endorsement"
class="ml-20"
>
<NInputNumber
v-model:value="model.min_of_endorsements"
:min="0"
class="w-3/4"
/>
</NFormItem>
<NFormItem
:label="$t('label.durationInDays')"
path="duration_in_days"
class="ml-20"
>
<NInputNumber
v-model:value="model.duration_in_days"
:min="1"
class="w-3/4"
/>
</NFormItem>
</NCard>
</NCard>
<QuestRewardsList
:default-rewards="model.rewards"
@show-modal="() => (isShowModal = true)"
@delete-rewards="handleDeleteRewards"
/>
<QuestRewardModal
:disabled="isEdited"
:show-modal="isShowModal"
@close-modal="() => (isShowModal = false)"
@add-rewards="handleAddRewards"
/>
<NButton
:disabled="isEdited"
class="left-full !w-24 -translate-x-full"
strong
attr-type="submit"
type="primary"
>
{{ $t('action.submit') }}
</NButton>
</NForm>
</div>
</template>
<script setup lang="ts">
import type { FormInst, FormValidationError } from 'naive-ui'
import { NSelect, useMessage } from 'naive-ui'
import type { SelectMixedOption } from 'naive-ui/es/select/src/interface'
import type { DraftQuestDetails } from '@/apis/models/DraftQuestDetails'
import { DraftQuestStatusEnum } from '@/apis/models/DraftQuestStatusEnum'
import { QuestTypeEnum } from '@/apis/models/QuestTypeEnum'
import { UserRoleEnum } from '@/apis/models/UserRoleEnum'
import { MAX_INPUT_DESC, MAX_INPUT_NAME } from '@/constants/form'
import { draftFormModel } from '@/forms/model/draftFormModel'
import { draftFormRules } from '@/forms/rules/draftFormRules'
const ctxUserListQuery = useUserListQuery({ include_inactive: false })
const emit = defineEmits(['submit'])
const userListItemOptions = ref<SelectMixedOption[]>()
const { t } = useI18n()
ctxUserListQuery.onResult((result) => {
userListItemOptions.value = result?.data?.map(({ id, name }) => ({
value: id,
label: name,
}))
})
const props = defineProps<{ quest: DraftQuestDetails }>()
const model = draftFormModel(props.quest)
console.log('Model', model)
const { user } = storeToRefs(useAuthStore())
const isEdited = computed(() => {
if (model.status) {
if (user.value?.role === UserRoleEnum.QuestMaster) {
return model.status.toLocaleUpperCase() === DraftQuestStatusEnum.Approved
}
if (user.value?.role === UserRoleEnum.SuperPlayer) {
return model.status.toLocaleUpperCase() !== DraftQuestStatusEnum.Rejected
}
}
})
const rules = draftFormRules(props.quest, QuestTypeEnum.Group)
const formRef = ref<FormInst | null>(null)
const isShowModal = ref(false)
const message = useMessage()
const handleFormSubmit = (e: Event) => {
e.preventDefault()
formRef.value?.validate((errors: Array<FormValidationError> | undefined) => {
if (!errors) {
emit('submit', { ...model })
} else {
const errorMessages = errors
.filter((error) => Array.isArray(error) && error.length > 0)
.map((error) => error[0].message)
errorMessages.forEach((err) => message.error(err as string))
}
})
}
const handleUploadImage = (file: File) => {
model.images = file
}
const handleUploadProof = (file: File) => {
model.proof = file
console.log(file)
}
const handleAddRewards = (newRewards: string) => {
if (!model.rewards?.includes(newRewards)) {
model.rewards?.push(newRewards)
} else {
message.error(t('message.duplicateRewards'))
}
}
const handleDeleteRewards = (rewardsId: string) =>
(model.rewards = model.rewards?.filter((id) => id !== rewardsId))
watch(
() => props.quest,
(newGroupQuest) => {
Object.assign(model, draftFormModel(newGroupQuest))
},
)
</script>