feat: 更新发行申请表单,添加订阅开始和结束时间字段,优化日期验证逻辑

This commit is contained in:
2025-12-21 03:42:45 +07:00
parent fcaf7db923
commit 101554ef5e
9 changed files with 175 additions and 97 deletions

View File

@@ -10,9 +10,9 @@ interface Props {
interface Emits { interface Emits {
"update:modelValue": [value: boolean]; "update:modelValue": [value: boolean];
"scan-success": [result: QRScanResult]; "scanSuccess": [result: QRScanResult];
"scan-error": [error: Error]; "scanError": [error: Error];
"scan-cancelled": []; "scanCancelled": [];
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
@@ -37,17 +37,17 @@ async function handleStartScan() {
const result = await startScan(); const result = await startScan();
if (result) { if (result) {
emit("scan-success", result); emit("scanSuccess", result);
await handleClose(); await handleClose();
} }
else { else {
emit("scan-cancelled"); emit("scanCancelled");
await handleClose(); await handleClose();
} }
} }
catch (error) { catch (error) {
console.error("Scan failed:", error); console.error("Scan failed:", error);
emit("scan-error", error as Error); emit("scanError", error as Error);
await handleClose(); await handleClose();
} }
finally { finally {

View File

@@ -14,9 +14,10 @@ const props = defineProps<Props>();
const emit = defineEmits<{ const emit = defineEmits<{
(e: "update:value", value: string): void; (e: "update:value", value: string): void;
}>(); }>();
const model = defineModel({ type: String, required: true });
function handleChange(value: string) { function handleChange(value: string) {
const formattedValue = props.formatterValue ? props.formatterValue(value) : new Date(value).toISOString(); const formattedValue = props.formatterValue ? props.formatterValue(value) : new Date(value).toISOString();
model.value = formattedValue;
props.onChange(formattedValue); props.onChange(formattedValue);
emit("update:value", formattedValue); emit("update:value", formattedValue);
} }
@@ -41,7 +42,7 @@ function formatDisplay(value: string) {
:id="datetime" :id="datetime"
class="ui-datetime" class="ui-datetime"
done-text="Done" done-text="Done"
presentation="date" presentation="date-time"
:show-default-buttons="true" :show-default-buttons="true"
:min="props.min" :min="props.min"
:max="props.max" :max="props.max"

View File

@@ -151,14 +151,16 @@
"enterTotalSupplyLimit": "الرجاء إدخال الحد الأقصى لإجمالي الإصدار", "enterTotalSupplyLimit": "الرجاء إدخال الحد الأقصى لإجمالي الإصدار",
"editionName": "اسم فترة الإصدار", "editionName": "اسم فترة الإصدار",
"enterEditionName": "الرجاء إدخال اسم فترة الإصدار", "enterEditionName": "الرجاء إدخال اسم فترة الإصدار",
"launchDate": "تاريخ الإصدار", "launchDate": "وقت الإحماء",
"enterLaunchDate": "الرجاء إدخال تاريخ الإصدار", "enterLaunchDate": "الرجاء إدخال وقت الإحماء",
"perUserLimit": "الحد الأقصى للاشتراك الفردي", "perUserLimit": "الحد الأقصى للاشتراك الفردي",
"enterPerUserLimit": "الرجاء إدخال الحد الأقصى للاشتراك الفردي", "enterPerUserLimit": "الرجاء إدخال الحد الأقصى للاشتراك الفردي",
"totalSupply": "إجمالي الإصدار", "totalSupply": "إجمالي الإصدار",
"enterTotalSupply": "الرجاء إدخال إجمالي الإصدار", "enterTotalSupply": "الرجاء إدخال إجمالي الإصدار",
"subscriptionDeadline": "الموعد النهائي للاشتراك", "subscriptionDeadline": "الموعد النهائي للاشتراك",
"enterSubscriptionDeadline": "الرجاء إدخال الموعد النهائي للاشتراك", "enterSubscriptionDeadline": "الرجاء إدخال الموعد النهائي للاشتراك",
"subscriptionStartDate": "تاريخ بدء الاشتراك",
"subscriptionEndDate": "تاريخ انتهاء الاشتراك",
"unitPrice": "سعر الوحدة", "unitPrice": "سعر الوحدة",
"enterUnitPrice": "الرجاء إدخال سعر الوحدة", "enterUnitPrice": "الرجاء إدخال سعر الوحدة",
"dividendRate": "معدل الأرباح", "dividendRate": "معدل الأرباح",
@@ -176,8 +178,14 @@
"codeRequired": "رمز المنتج مطلوب", "codeRequired": "رمز المنتج مطلوب",
"categoryRequired": "نوع المنتج مطلوب", "categoryRequired": "نوع المنتج مطلوب",
"editionNameRequired": "اسم فترة الإصدار مطلوب", "editionNameRequired": "اسم فترة الإصدار مطلوب",
"launchDateRequired": "تاريخ الإصدار مطلوب", "launchDateRequired": "وقت الإحماء مطلوب",
"launchDateNotPast": "لا يمكن أن يكون تاريخ الإصدار قبل التاريخ الحالي", "launchDateNotPast": "لا يمكن أن يكون وقت الإحماء قبل الوقت الحالي",
"launchBeforeSubscription": "يجب أن يكون وقت الإحماء قبل تاريخ بدء الاشتراك",
"subscriptionStartDateRequired": "تاريخ بدء الاشتراك مطلوب",
"subscriptionStartDateNotPast": "لا يمكن أن يكون تاريخ بدء الاشتراك قبل التاريخ الحالي",
"subscriptionAfterLaunch": "يجب أن يكون تاريخ بدء الاشتراك بعد وقت الإحماء",
"subscriptionEndDateRequired": "تاريخ انتهاء الاشتراك مطلوب",
"subscriptionEndAfterStart": "يجب أن يكون تاريخ انتهاء الاشتراك بعد تاريخ بدء الاشتراك",
"perUserLimitRequired": "الحد الأقصى للاشتراك الفردي مطلوب", "perUserLimitRequired": "الحد الأقصى للاشتراك الفردي مطلوب",
"totalSupplyRequired": "إجمالي الإصدار مطلوب", "totalSupplyRequired": "إجمالي الإصدار مطلوب",
"subscriptionDeadlineRequired": "الموعد النهائي للاشتراك مطلوب", "subscriptionDeadlineRequired": "الموعد النهائي للاشتراك مطلوب",
@@ -239,7 +247,7 @@
"unitPrice": "سعر الوحدة", "unitPrice": "سعر الوحدة",
"totalSupply": "إجمالي الإصدار", "totalSupply": "إجمالي الإصدار",
"perUserLimit": "الحد لكل شخص", "perUserLimit": "الحد لكل شخص",
"launchDate": "وقت الإصدار", "launchDate": "وقت الإحماء",
"subscriptionDeadline": "الموعد النهائي للاشتراك" "subscriptionDeadline": "الموعد النهائي للاشتراك"
}, },
"units": { "units": {

View File

@@ -151,14 +151,16 @@
"enterTotalSupplyLimit": "Please enter total supply limit", "enterTotalSupplyLimit": "Please enter total supply limit",
"editionName": "Edition Name", "editionName": "Edition Name",
"enterEditionName": "Please enter edition name", "enterEditionName": "Please enter edition name",
"launchDate": "Launch Date", "launchDate": "Warm-up Time",
"enterLaunchDate": "Please enter launch date", "enterLaunchDate": "Please enter warm-up time",
"perUserLimit": "Per User Limit", "perUserLimit": "Per User Limit",
"enterPerUserLimit": "Please enter per user limit", "enterPerUserLimit": "Please enter per user limit",
"totalSupply": "Total Supply", "totalSupply": "Total Supply",
"enterTotalSupply": "Please enter total supply", "enterTotalSupply": "Please enter total supply",
"subscriptionDeadline": "Subscription Deadline", "subscriptionDeadline": "Subscription Deadline",
"enterSubscriptionDeadline": "Please enter subscription deadline", "enterSubscriptionDeadline": "Please enter subscription deadline",
"subscriptionStartDate": "Subscription Start Date",
"subscriptionEndDate": "Subscription End Date",
"unitPrice": "Unit Price", "unitPrice": "Unit Price",
"enterUnitPrice": "Please enter unit price", "enterUnitPrice": "Please enter unit price",
"dividendRate": "Dividend Rate", "dividendRate": "Dividend Rate",
@@ -176,8 +178,14 @@
"codeRequired": "Code is required", "codeRequired": "Code is required",
"categoryRequired": "Type is required", "categoryRequired": "Type is required",
"editionNameRequired": "Edition name is required", "editionNameRequired": "Edition name is required",
"launchDateRequired": "Launch date is required", "launchDateRequired": "Warm-up time is required",
"launchDateNotPast": "Launch date cannot be earlier than current date", "launchDateNotPast": "Warm-up time cannot be earlier than current date",
"launchBeforeSubscription": "Warm-up time must be before subscription start date",
"subscriptionStartDateRequired": "Subscription start date is required",
"subscriptionStartDateNotPast": "Subscription start date cannot be earlier than current date",
"subscriptionAfterLaunch": "Subscription start date must be after warm-up time",
"subscriptionEndDateRequired": "Subscription end date is required",
"subscriptionEndAfterStart": "Subscription end date must be after subscription start date",
"perUserLimitRequired": "Per user limit is required", "perUserLimitRequired": "Per user limit is required",
"totalSupplyRequired": "Total supply is required", "totalSupplyRequired": "Total supply is required",
"subscriptionDeadlineRequired": "Subscription deadline is required", "subscriptionDeadlineRequired": "Subscription deadline is required",
@@ -239,7 +247,7 @@
"unitPrice": "Unit Price", "unitPrice": "Unit Price",
"totalSupply": "Total Supply", "totalSupply": "Total Supply",
"perUserLimit": "Per User Limit", "perUserLimit": "Per User Limit",
"launchDate": "Launch Date", "launchDate": "Warm-up Time",
"subscriptionDeadline": "Subscription Deadline" "subscriptionDeadline": "Subscription Deadline"
}, },
"units": { "units": {

View File

@@ -151,14 +151,16 @@
"enterTotalSupplyLimit": "请输入总发行量上限", "enterTotalSupplyLimit": "请输入总发行量上限",
"editionName": "发行期名称", "editionName": "发行期名称",
"enterEditionName": "请输入发行期名称", "enterEditionName": "请输入发行期名称",
"launchDate": "发行日期", "launchDate": "预热时间",
"enterLaunchDate": "请输入发行日期", "enterLaunchDate": "请输入预热时间",
"perUserLimit": "个人申购上限", "perUserLimit": "个人申购上限",
"enterPerUserLimit": "请输入个人申购上限", "enterPerUserLimit": "请输入个人申购上限",
"totalSupply": "发行总量", "totalSupply": "发行总量",
"enterTotalSupply": "请输入发行总量", "enterTotalSupply": "请输入发行总量",
"subscriptionDeadline": "申购截止日期", "subscriptionDeadline": "申购截止日期",
"enterSubscriptionDeadline": "请输入申购截止日期", "enterSubscriptionDeadline": "请输入申购截止日期",
"subscriptionStartDate": "订阅开始时间",
"subscriptionEndDate": "订阅结束时间",
"unitPrice": "单价", "unitPrice": "单价",
"enterUnitPrice": "请输入单价", "enterUnitPrice": "请输入单价",
"dividendRate": "分红率", "dividendRate": "分红率",
@@ -176,8 +178,14 @@
"codeRequired": "产品编码是必填项", "codeRequired": "产品编码是必填项",
"categoryRequired": "产品类型是必填项", "categoryRequired": "产品类型是必填项",
"editionNameRequired": "发行期名称是必填项", "editionNameRequired": "发行期名称是必填项",
"launchDateRequired": "发行日期是必填项", "launchDateRequired": "预热时间是必填项",
"launchDateNotPast": "发行日期不能于当前日期", "launchDateNotPast": "预热时间不能于当前时间",
"launchBeforeSubscription": "预热时间必须在订阅开始时间之前",
"subscriptionStartDateRequired": "订阅开始时间是必填项",
"subscriptionStartDateNotPast": "订阅开始时间不能早于当前时间",
"subscriptionAfterLaunch": "订阅开始时间必须在预热时间之后",
"subscriptionEndDateRequired": "订阅结束时间是必填项",
"subscriptionEndAfterStart": "订阅结束时间必须在订阅开始时间之后",
"perUserLimitRequired": "个人申购上限是必填项", "perUserLimitRequired": "个人申购上限是必填项",
"totalSupplyRequired": "发行总量是必填项", "totalSupplyRequired": "发行总量是必填项",
"subscriptionDeadlineRequired": "申购截止日期是必填项", "subscriptionDeadlineRequired": "申购截止日期是必填项",
@@ -239,7 +247,7 @@
"unitPrice": "单价", "unitPrice": "单价",
"totalSupply": "总发行量", "totalSupply": "总发行量",
"perUserLimit": "每人限量", "perUserLimit": "每人限量",
"launchDate": "发行时间", "launchDate": "预热时间",
"subscriptionDeadline": "认购截止时间" "subscriptionDeadline": "认购截止时间"
}, },
"units": { "units": {

View File

@@ -151,14 +151,16 @@
"enterTotalSupplyLimit": "請輸入總發行量上限", "enterTotalSupplyLimit": "請輸入總發行量上限",
"editionName": "發行期名稱", "editionName": "發行期名稱",
"enterEditionName": "請輸入發行期名稱", "enterEditionName": "請輸入發行期名稱",
"launchDate": "發行日期", "launchDate": "預熱時間",
"enterLaunchDate": "請輸入發行日期", "enterLaunchDate": "請輸入預熱時間",
"perUserLimit": "個人申購上限", "perUserLimit": "個人申購上限",
"enterPerUserLimit": "請輸入個人申購上限", "enterPerUserLimit": "請輸入個人申購上限",
"totalSupply": "發行總量", "totalSupply": "發行總量",
"enterTotalSupply": "請輸入發行總量", "enterTotalSupply": "請輸入發行總量",
"subscriptionDeadline": "申購截止日期", "subscriptionDeadline": "申購截止日期",
"enterSubscriptionDeadline": "請輸入申購截止日期", "enterSubscriptionDeadline": "請輸入申購截止日期",
"subscriptionStartDate": "訂閱開始時間",
"subscriptionEndDate": "訂閱結束時間",
"unitPrice": "單價", "unitPrice": "單價",
"enterUnitPrice": "請輸入單價", "enterUnitPrice": "請輸入單價",
"dividendRate": "分紅率", "dividendRate": "分紅率",
@@ -176,8 +178,14 @@
"codeRequired": "產品編碼是必填項", "codeRequired": "產品編碼是必填項",
"categoryRequired": "產品類型是必填項", "categoryRequired": "產品類型是必填項",
"editionNameRequired": "發行期名稱是必填項", "editionNameRequired": "發行期名稱是必填項",
"launchDateRequired": "發行日期是必填項", "launchDateRequired": "預熱時間是必填項",
"launchDateNotPast": "發行日期不能於當前日期", "launchDateNotPast": "預熱時間不能於當前時間",
"launchBeforeSubscription": "預熱時間必須在訂閱開始時間之前",
"subscriptionStartDateRequired": "訂閱開始時間是必填項",
"subscriptionStartDateNotPast": "訂閱開始時間不能早於當前時間",
"subscriptionAfterLaunch": "訂閱開始時間必須在預熱時間之後",
"subscriptionEndDateRequired": "訂閱結束時間是必填項",
"subscriptionEndAfterStart": "訂閱結束時間必須在訂閱開始時間之後",
"perUserLimitRequired": "個人申購上限是必填項", "perUserLimitRequired": "個人申購上限是必填項",
"totalSupplyRequired": "發行總量是必填項", "totalSupplyRequired": "發行總量是必填項",
"subscriptionDeadlineRequired": "申購截止日期是必填項", "subscriptionDeadlineRequired": "申購截止日期是必填項",
@@ -239,7 +247,7 @@
"unitPrice": "單價", "unitPrice": "單價",
"totalSupply": "總發行量", "totalSupply": "總發行量",
"perUserLimit": "每人限量", "perUserLimit": "每人限量",
"launchDate": "發行時間", "launchDate": "預熱時間",
"subscriptionDeadline": "認購截止時間" "subscriptionDeadline": "認購截止時間"
}, },
"units": { "units": {

View File

@@ -22,16 +22,16 @@ ion-datetime.ui-datetime {
--wheel-highlight-background: rgb(194 194 194); --wheel-highlight-background: rgb(194 194 194);
--wheel-fade-background-rgb: 255, 255, 255; --wheel-fade-background-rgb: 255, 255, 255;
border-radius: 16px; border-radius: 16px;
overflow: hidden; box-shadow: rgba(var(--ion-color-rose-rgb), 0.3) 0px 10px 15px -3px;
} }
.ion-palette-dark { html.ion-palette-dark ion-datetime.ui-datetime {
ion-datetime.ui-datetime { --background: rgb(15, 15, 15);
--background: rgb(15, 15, 15); --background-rgb: 15, 15, 15;
--background-rgb: 15, 15, 15; --wheel-highlight-background: rgb(50, 50, 50);
--wheel-highlight-background: rgb(50, 50, 50); --wheel-highlight-border-radius: 48px;
--wheel-highlight-border-radius: 48px; --wheel-fade-background-rgb: 15, 15, 15;
--wheel-fade-background-rgb: 15, 15, 15; border-radius: 16px;
} box-shadow: rgba(var(--ion-color-rose-rgb), 0.3) 0px 10px 15px -3px;
} }
:root.ios { :root.ios {

View File

@@ -9,7 +9,7 @@ import Done from "./done.vue";
import IssuePeriod from "./issue-period.vue"; import IssuePeriod from "./issue-period.vue";
const { t } = useI18n(); const { t } = useI18n();
const { data: categories, onFetchResponse } = await safeClient(() => client.api.rwa.issuance.categories.get()); const { data: categories, onFetchResponse } = await safeClient(() => client.api.rwa.category.categories.get());
const step = useRouteQuery<number>("step", 1, { transform: v => Number(v), mode: "push" }); const step = useRouteQuery<number>("step", 1, { transform: v => Number(v), mode: "push" });
const initialData: RwaIssuanceProductBody = { const initialData: RwaIssuanceProductBody = {
@@ -23,7 +23,8 @@ const initialData: RwaIssuanceProductBody = {
editionName: "", editionName: "",
launchDate: new Date(), launchDate: new Date(),
perUserLimit: "", perUserLimit: "",
subscriptionDeadline: new Date(), subscriptionStartDate: new Date(),
subscriptionEndDate: new Date(),
totalSupply: "", totalSupply: "",
unitPrice: "", unitPrice: "",
dividendRate: "", dividendRate: "",

View File

@@ -20,7 +20,8 @@ const initialIssuePeriod: RwaIssuanceProductBody["editions"][0] = {
editionName: "", editionName: "",
launchDate: new Date(), launchDate: new Date(),
perUserLimit: "", perUserLimit: "",
subscriptionDeadline: new Date(), subscriptionStartDate: new Date(),
subscriptionEndDate: new Date(),
totalSupply: "", totalSupply: "",
unitPrice: "", unitPrice: "",
dividendRate: "", dividendRate: "",
@@ -30,6 +31,10 @@ const initialValues = ref({
editions: props.initialData || [{ ...initialIssuePeriod }], editions: props.initialData || [{ ...initialIssuePeriod }],
}); });
const launchDate = ref(new Date().toISOString());
const subscriptionStartDate = ref(new Date().toISOString());
const subscriptionEndDate = ref(new Date().toISOString());
const schema = toTypedSchema(yup.object({ const schema = toTypedSchema(yup.object({
editions: yup.array().of( editions: yup.array().of(
yup.object({ yup.object({
@@ -40,17 +45,33 @@ const schema = toTypedSchema(yup.object({
if (!value) if (!value)
return true; return true;
return new Date(value) >= new Date(now.value.toDateString()); return new Date(value) >= new Date(now.value.toDateString());
})
.test("before-subscription", t("asset.issue.apply.validation.launchBeforeSubscription"), (value) => {
if (!value || !subscriptionStartDate.value)
return true;
return new Date(value) < new Date(subscriptionStartDate.value);
}),
subscriptionStartDate: yup.string()
.required(t("asset.issue.apply.validation.subscriptionStartDateRequired"))
.test("not-past", t("asset.issue.apply.validation.subscriptionStartDateNotPast"), (value) => {
if (!value)
return true;
return new Date(value) >= new Date(now.value.toDateString());
})
.test("after-launch", t("asset.issue.apply.validation.subscriptionAfterLaunch"), (value) => {
if (!value || !launchDate.value)
return true;
return new Date(value) > new Date(launchDate.value);
}),
subscriptionEndDate: yup.string()
.required(t("asset.issue.apply.validation.subscriptionEndDateRequired"))
.test("after-start", t("asset.issue.apply.validation.subscriptionEndAfterStart"), (value) => {
if (!value || !subscriptionStartDate.value)
return true;
return new Date(value) > new Date(subscriptionStartDate.value);
}), }),
perUserLimit: yup.string().required(t("asset.issue.apply.validation.perUserLimitRequired")), perUserLimit: yup.string().required(t("asset.issue.apply.validation.perUserLimitRequired")),
totalSupply: yup.string().required(t("asset.issue.apply.validation.totalSupplyRequired")), totalSupply: yup.string().required(t("asset.issue.apply.validation.totalSupplyRequired")),
subscriptionDeadline: yup.string()
.required(t("asset.issue.apply.validation.subscriptionDeadlineRequired"))
.test("after-launch", t("asset.issue.apply.validation.deadlineAfterLaunch"), function (value) {
const { launchDate } = this.parent;
if (!value || !launchDate)
return true;
return new Date(value) >= new Date(launchDate);
}),
unitPrice: yup.string().required(t("asset.issue.apply.validation.unitPriceRequired")), unitPrice: yup.string().required(t("asset.issue.apply.validation.unitPriceRequired")),
dividendRate: yup.string().required(t("asset.issue.apply.validation.dividendRateRequired")), dividendRate: yup.string().required(t("asset.issue.apply.validation.dividendRateRequired")),
}), }),
@@ -68,20 +89,22 @@ function handleSubmit(values: GenericObject) {
<ui-collapse v-for="(entry, idx) in fields" :key="entry.key" :title="t('asset.issue.apply.issuePeriodIndex', { index: idx + 1 })" size="small"> <ui-collapse v-for="(entry, idx) in fields" :key="entry.key" :title="t('asset.issue.apply.issuePeriodIndex', { index: idx + 1 })" size="small">
<div> <div>
<Field :name="`editions[${idx}].editionName`"> <Field :name="`editions[${idx}].editionName`">
<template #default="{ field }"> <template #default="{ field, errorMessage }">
<ui-input-label <ui-input-label
v-bind="field" v-bind="field"
:label="t('asset.issue.apply.editionName')" :label="t('asset.issue.apply.editionName')"
:placeholder="t('asset.issue.apply.enterEditionName')" :placeholder="t('asset.issue.apply.enterEditionName')"
/> />
<div v-if="errorMessage" class="text-xs text-red-500 mt-1">
{{ errorMessage }}
</div>
</template> </template>
</Field> </Field>
<ErrorMessage :name="`editions[${idx}].editionName`" />
</div> </div>
<div> <div>
<Field :name="`editions[${idx}].perUserLimit`" type="text"> <Field :name="`editions[${idx}].perUserLimit`" type="text">
<template #default="{ field }"> <template #default="{ field, errorMessage }">
<ui-input-label <ui-input-label
v-bind="field" v-bind="field"
type="number" type="number"
@@ -89,14 +112,16 @@ function handleSubmit(values: GenericObject) {
:label="t('asset.issue.apply.perUserLimit')" :label="t('asset.issue.apply.perUserLimit')"
:placeholder="t('asset.issue.apply.enterPerUserLimit')" :placeholder="t('asset.issue.apply.enterPerUserLimit')"
/> />
<div v-if="errorMessage" class="text-xs text-red-500 mt-1">
{{ errorMessage }}
</div>
</template> </template>
</Field> </Field>
<ErrorMessage :name="`editions[${idx}].perUserLimit`" />
</div> </div>
<div> <div>
<Field :name="`editions[${idx}].totalSupply`" type="text"> <Field :name="`editions[${idx}].totalSupply`" type="text">
<template #default="{ field }"> <template #default="{ field, errorMessage }">
<ui-input-label <ui-input-label
v-bind="field" v-bind="field"
type="number" type="number"
@@ -104,53 +129,17 @@ function handleSubmit(values: GenericObject) {
:label="t('asset.issue.apply.totalSupply')" :label="t('asset.issue.apply.totalSupply')"
:placeholder="t('asset.issue.apply.enterTotalSupply')" :placeholder="t('asset.issue.apply.enterTotalSupply')"
/> />
<div v-if="errorMessage" class="text-xs text-red-500 mt-1">
{{ errorMessage }}
</div>
</template> </template>
</Field> </Field>
<ErrorMessage :name="`editions[${idx}].totalSupply`" /> <ErrorMessage :name="`editions[${idx}].totalSupply`" />
</div> </div>
<div>
<Field :name="`editions[${idx}].subscriptionDeadline`">
<template #default="{ setValue }">
<Field :name="`editions[${idx}].launchDate`">
<template #default="{ field }">
<ui-datetime
datetime="launchDate"
v-bind="field"
:label="t('asset.issue.apply.launchDate')"
:min="now.toISOString()"
@update:value="(val) => {
setValue(val);
}"
/>
</template>
</Field>
<ErrorMessage :name="`editions[${idx}].launchDate`" />
</template>
</Field>
</div>
<div>
<Field :name="`editions[${idx}].launchDate`">
<template #default="{ value: launchDate }">
<Field :name="`editions[${idx}].subscriptionDeadline`">
<template #default="{ field }">
<ui-datetime
datetime="subscriptionDeadline"
v-bind="field"
:label="t('asset.issue.apply.subscriptionDeadline')"
:min="launchDate ? new Date(launchDate).toISOString() : now.toISOString()"
/>
</template>
</Field>
<ErrorMessage :name="`editions[${idx}].subscriptionDeadline`" />
</template>
</Field>
</div>
<div> <div>
<Field :name="`editions[${idx}].unitPrice`" type="text"> <Field :name="`editions[${idx}].unitPrice`" type="text">
<template #default="{ field }"> <template #default="{ field, errorMessage }">
<ui-input-label <ui-input-label
v-bind="field" v-bind="field"
type="number" type="number"
@@ -158,14 +147,16 @@ function handleSubmit(values: GenericObject) {
:label="t('asset.issue.apply.unitPrice')" :label="t('asset.issue.apply.unitPrice')"
:placeholder="t('asset.issue.apply.enterUnitPrice')" :placeholder="t('asset.issue.apply.enterUnitPrice')"
/> />
<div v-if="errorMessage" class="text-xs text-red-500 mt-1">
{{ errorMessage }}
</div>
</template> </template>
</Field> </Field>
<ErrorMessage :name="`editions[${idx}].unitPrice`" />
</div> </div>
<div> <div>
<Field :name="`editions[${idx}].dividendRate`" type="number"> <Field :name="`editions[${idx}].dividendRate`" type="number">
<template #default="{ field }"> <template #default="{ field, errorMessage }">
<ui-input-label <ui-input-label
v-bind="field" v-bind="field"
type="number" type="number"
@@ -173,9 +164,62 @@ function handleSubmit(values: GenericObject) {
:label="t('asset.issue.apply.dividendRate')" :label="t('asset.issue.apply.dividendRate')"
:placeholder="t('asset.issue.apply.enterDividendRate')" :placeholder="t('asset.issue.apply.enterDividendRate')"
/> />
<div v-if="errorMessage" class="text-xs text-red-500 mt-1">
{{ errorMessage }}
</div>
</template>
</Field>
</div>
<div>
<Field :name="`editions[${idx}].launchDate`">
<template #default="{ field, errorMessage }">
<ui-datetime
v-bind="field"
v-model="launchDate"
datetime="launchDate"
:label="t('asset.issue.apply.launchDate')"
:min="now.toISOString()"
/>
<div v-if="errorMessage" class="text-xs text-red-500 mt-1">
{{ errorMessage }}
</div>
</template>
</Field>
</div>
<div>
<Field :name="`editions[${idx}].subscriptionStartDate`">
<template #default="{ field, errorMessage }">
<ui-datetime
v-bind="field"
v-model="subscriptionStartDate"
datetime="subscriptionStartDate"
:label="t('asset.issue.apply.subscriptionStartDate')"
:min="launchDate ? new Date(launchDate).toISOString() : now.toISOString()"
/>
<div v-if="errorMessage" class="text-xs text-red-500 mt-1">
{{ errorMessage }}
</div>
</template>
</Field>
</div>
<div>
<Field :name="`editions[${idx}].subscriptionEndDate`">
<template #default="{ field, errorMessage }">
<ui-datetime
v-bind="field"
v-model="subscriptionEndDate"
datetime="subscriptionEndDate"
:label="t('asset.issue.apply.subscriptionEndDate')"
:min="subscriptionStartDate ? new Date(subscriptionStartDate).toISOString() : now.toISOString()"
/>
<div v-if="errorMessage" class="text-xs text-red-500 mt-1">
{{ errorMessage }}
</div>
</template> </template>
</Field> </Field>
<ErrorMessage :name="`editions[${idx}].dividendRate`" />
</div> </div>
<ion-button color="tertiary" size="small" class="ui-button" @click="remove(idx)"> <ion-button color="tertiary" size="small" class="ui-button" @click="remove(idx)">
@@ -191,7 +235,7 @@ function handleSubmit(values: GenericObject) {
</FieldArray> </FieldArray>
<div class="flex justify-center space-x-4"> <div class="flex justify-center space-x-4">
<ion-button expand="block" shape="round" @click="$router.back()"> <ion-button expand="block" shape="round" class="w-40" @click="$router.back()">
{{ t('asset.issue.apply.back') }} {{ t('asset.issue.apply.back') }}
</ion-button> </ion-button>
<ion-button expand="block" type="submit" class="w-full" shape="round" color="success"> <ion-button expand="block" type="submit" class="w-full" shape="round" color="success">