feat: complete admin panel and backend admin api migration
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<!--
|
||||
Ported from legacy henza_admin/src/views/workshop/AddWorkshop.vue.
|
||||
Serves BOTH create and edit — EditWorkshop.vue is a wrapper over it.
|
||||
|
||||
Unlike the branch form, this one CREATES its supervisor inline from three
|
||||
fields (نام / نام خانوادگی / موبایل) rather than picking an existing admin.
|
||||
The supervisor is saved as an AdminUser with role WORKSHOP_SUPERVISOR.
|
||||
-->
|
||||
<a-spin :spinning="loading">
|
||||
<a-form layout="vertical" @submit.prevent="handleSubmit">
|
||||
<a-card :title="id ? 'ویرایش کارگاه' : 'افزودن کارگاه'" class="mb-base">
|
||||
<div class="grid-3">
|
||||
<a-form-item
|
||||
label="نام کارگاه"
|
||||
:validate-status="err.workshop_name ? 'error' : ''"
|
||||
:help="err.workshop_name"
|
||||
>
|
||||
<a-input v-model:value="form.workshop_name" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="تلفن کارگاه">
|
||||
<a-input v-model:value="form.workshop_phone" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="نام سرپرست کارگاه">
|
||||
<a-input v-model:value="form.user_fname" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="نام خانوادگی سرپرست کارگاه">
|
||||
<a-input v-model:value="form.user_lname" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="موبایل سرپرست کارگاه"
|
||||
:validate-status="err.user_phone ? 'error' : ''"
|
||||
:help="err.user_phone"
|
||||
>
|
||||
<a-input v-model:value="form.user_phone" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<a-form-item label="آدرس">
|
||||
<a-textarea v-model:value="form.workshop_address" :auto-size="{ minRows: 2, maxRows: 5 }" />
|
||||
</a-form-item>
|
||||
|
||||
<a-button type="primary" @click="handleSubmit">ثبت اطلاعات</a-button>
|
||||
</a-card>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { message } from 'ant-design-vue';
|
||||
import api from '../../api/client';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const id = route.params.id as string | undefined;
|
||||
const loading = ref(false);
|
||||
|
||||
const form = reactive<Record<string, any>>({
|
||||
workshop_name: '',
|
||||
workshop_phone: '',
|
||||
workshop_address: '',
|
||||
user_fname: '',
|
||||
user_lname: '',
|
||||
user_phone: '',
|
||||
});
|
||||
const err = reactive<Record<string, string>>({});
|
||||
|
||||
async function handleSubmit() {
|
||||
Object.keys(err).forEach((k) => delete err[k]);
|
||||
if (!form.workshop_name) err.workshop_name = 'لطفا مقدار را وارد کنید';
|
||||
// The server requires a mobile whenever any supervisor field is filled.
|
||||
if ((form.user_fname || form.user_lname) && !form.user_phone) {
|
||||
err.user_phone = 'موبایل سرپرست کارگاه الزامی است';
|
||||
}
|
||||
if (Object.keys(err).length) return;
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
if (id) {
|
||||
await api.put(`workshop/${id}`, form);
|
||||
} else {
|
||||
await api.post('workshop', form);
|
||||
}
|
||||
message.info('اطلاعات با موفقیت به ثبت رسید.');
|
||||
router.push('/workshop/list');
|
||||
} catch (e: any) {
|
||||
message.error(e?.response?.data?.message ?? 'خطا در ثبت اطلاعات.');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (id) {
|
||||
try {
|
||||
const { data } = await api.get(`workshop/${id}`);
|
||||
Object.assign(form, {
|
||||
workshop_name: data.workshop_name ?? data.name ?? '',
|
||||
workshop_phone: data.workshop_phone ?? data.phone ?? '',
|
||||
workshop_address: data.workshop_address ?? data.address ?? '',
|
||||
user_fname: data.user_fname ?? '',
|
||||
user_lname: data.user_lname ?? '',
|
||||
user_phone: data.user_phone ?? '',
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.grid-3 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<!-- Ported from legacy views/workshop/EditWorkshop.vue. AddWorkshop reads the
|
||||
:id route param to switch between create and edit. -->
|
||||
<AddWorkshop />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import AddWorkshop from './AddWorkshop.vue';
|
||||
</script>
|
||||
@@ -0,0 +1,13 @@
|
||||
// Ported from legacy henza_admin/src/views/workshop/ListWorkshop.js
|
||||
import XTbl, { Xtc } from '../../components/x-table/model';
|
||||
|
||||
export function buildWorkshopListModel(): XTbl {
|
||||
const tbl = new XTbl('admin/workshops/list', 'لیست کارگاه ها');
|
||||
tbl.add(new Xtc('name', 'نام').filterText());
|
||||
tbl.add(new Xtc('address', 'آدرس').filterText());
|
||||
tbl.add(new Xtc('phone', 'شماره تلفن').filterNumber());
|
||||
tbl.add(new Xtc('op', 'عملیات').noSort().renderSlot('actions'));
|
||||
return tbl;
|
||||
}
|
||||
|
||||
export default buildWorkshopListModel;
|
||||
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<!-- Ported from legacy views/workshop/ListWorkshop.vue — differs from the
|
||||
branch list by 14 lines (title, model, edit route). -->
|
||||
<FacilityList
|
||||
title="لیست کارگاه ها"
|
||||
:model="model"
|
||||
edit-path="/workshop/edit"
|
||||
active-path="workshop/active"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import FacilityList from '../branch/FacilityList.vue';
|
||||
import { buildWorkshopListModel } from './ListWorkshop';
|
||||
|
||||
const model = buildWorkshopListModel();
|
||||
</script>
|
||||
Reference in New Issue
Block a user