diff --git a/src/components/qr-scanner/index.vue b/src/components/qr-scanner/index.vue index c096e4d..ed4af41 100644 --- a/src/components/qr-scanner/index.vue +++ b/src/components/qr-scanner/index.vue @@ -10,9 +10,9 @@ interface Props { interface Emits { "update:modelValue": [value: boolean]; - "scan-success": [result: QRScanResult]; - "scan-error": [error: Error]; - "scan-cancelled": []; + "scanSuccess": [result: QRScanResult]; + "scanError": [error: Error]; + "scanCancelled": []; } const props = withDefaults(defineProps(), { @@ -37,17 +37,17 @@ async function handleStartScan() { const result = await startScan(); if (result) { - emit("scan-success", result); + emit("scanSuccess", result); await handleClose(); } else { - emit("scan-cancelled"); + emit("scanCancelled"); await handleClose(); } } catch (error) { console.error("Scan failed:", error); - emit("scan-error", error as Error); + emit("scanError", error as Error); await handleClose(); } finally { diff --git a/src/components/ui/datetime/index.vue b/src/components/ui/datetime/index.vue index abebf87..fc884fa 100644 --- a/src/components/ui/datetime/index.vue +++ b/src/components/ui/datetime/index.vue @@ -14,9 +14,10 @@ const props = defineProps(); const emit = defineEmits<{ (e: "update:value", value: string): void; }>(); - +const model = defineModel({ type: String, required: true }); function handleChange(value: string) { const formattedValue = props.formatterValue ? props.formatterValue(value) : new Date(value).toISOString(); + model.value = formattedValue; props.onChange(formattedValue); emit("update:value", formattedValue); } @@ -41,7 +42,7 @@ function formatDisplay(value: string) { :id="datetime" class="ui-datetime" done-text="Done" - presentation="date" + presentation="date-time" :show-default-buttons="true" :min="props.min" :max="props.max" diff --git a/src/locales/ar.json b/src/locales/ar.json index e5d64e6..4ad7521 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -151,14 +151,16 @@ "enterTotalSupplyLimit": "الرجاء إدخال الحد الأقصى لإجمالي الإصدار", "editionName": "اسم فترة الإصدار", "enterEditionName": "الرجاء إدخال اسم فترة الإصدار", - "launchDate": "تاريخ الإصدار", - "enterLaunchDate": "الرجاء إدخال تاريخ الإصدار", + "launchDate": "وقت الإحماء", + "enterLaunchDate": "الرجاء إدخال وقت الإحماء", "perUserLimit": "الحد الأقصى للاشتراك الفردي", "enterPerUserLimit": "الرجاء إدخال الحد الأقصى للاشتراك الفردي", "totalSupply": "إجمالي الإصدار", "enterTotalSupply": "الرجاء إدخال إجمالي الإصدار", "subscriptionDeadline": "الموعد النهائي للاشتراك", "enterSubscriptionDeadline": "الرجاء إدخال الموعد النهائي للاشتراك", + "subscriptionStartDate": "تاريخ بدء الاشتراك", + "subscriptionEndDate": "تاريخ انتهاء الاشتراك", "unitPrice": "سعر الوحدة", "enterUnitPrice": "الرجاء إدخال سعر الوحدة", "dividendRate": "معدل الأرباح", @@ -176,8 +178,14 @@ "codeRequired": "رمز المنتج مطلوب", "categoryRequired": "نوع المنتج مطلوب", "editionNameRequired": "اسم فترة الإصدار مطلوب", - "launchDateRequired": "تاريخ الإصدار مطلوب", - "launchDateNotPast": "لا يمكن أن يكون تاريخ الإصدار قبل التاريخ الحالي", + "launchDateRequired": "وقت الإحماء مطلوب", + "launchDateNotPast": "لا يمكن أن يكون وقت الإحماء قبل الوقت الحالي", + "launchBeforeSubscription": "يجب أن يكون وقت الإحماء قبل تاريخ بدء الاشتراك", + "subscriptionStartDateRequired": "تاريخ بدء الاشتراك مطلوب", + "subscriptionStartDateNotPast": "لا يمكن أن يكون تاريخ بدء الاشتراك قبل التاريخ الحالي", + "subscriptionAfterLaunch": "يجب أن يكون تاريخ بدء الاشتراك بعد وقت الإحماء", + "subscriptionEndDateRequired": "تاريخ انتهاء الاشتراك مطلوب", + "subscriptionEndAfterStart": "يجب أن يكون تاريخ انتهاء الاشتراك بعد تاريخ بدء الاشتراك", "perUserLimitRequired": "الحد الأقصى للاشتراك الفردي مطلوب", "totalSupplyRequired": "إجمالي الإصدار مطلوب", "subscriptionDeadlineRequired": "الموعد النهائي للاشتراك مطلوب", @@ -239,7 +247,7 @@ "unitPrice": "سعر الوحدة", "totalSupply": "إجمالي الإصدار", "perUserLimit": "الحد لكل شخص", - "launchDate": "وقت الإصدار", + "launchDate": "وقت الإحماء", "subscriptionDeadline": "الموعد النهائي للاشتراك" }, "units": { diff --git a/src/locales/en-US.json b/src/locales/en-US.json index b04b2ef..86adafd 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -151,14 +151,16 @@ "enterTotalSupplyLimit": "Please enter total supply limit", "editionName": "Edition Name", "enterEditionName": "Please enter edition name", - "launchDate": "Launch Date", - "enterLaunchDate": "Please enter launch date", + "launchDate": "Warm-up Time", + "enterLaunchDate": "Please enter warm-up time", "perUserLimit": "Per User Limit", "enterPerUserLimit": "Please enter per user limit", "totalSupply": "Total Supply", "enterTotalSupply": "Please enter total supply", "subscriptionDeadline": "Subscription Deadline", "enterSubscriptionDeadline": "Please enter subscription deadline", + "subscriptionStartDate": "Subscription Start Date", + "subscriptionEndDate": "Subscription End Date", "unitPrice": "Unit Price", "enterUnitPrice": "Please enter unit price", "dividendRate": "Dividend Rate", @@ -176,8 +178,14 @@ "codeRequired": "Code is required", "categoryRequired": "Type is required", "editionNameRequired": "Edition name is required", - "launchDateRequired": "Launch date is required", - "launchDateNotPast": "Launch date cannot be earlier than current date", + "launchDateRequired": "Warm-up time is required", + "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", "totalSupplyRequired": "Total supply is required", "subscriptionDeadlineRequired": "Subscription deadline is required", @@ -239,7 +247,7 @@ "unitPrice": "Unit Price", "totalSupply": "Total Supply", "perUserLimit": "Per User Limit", - "launchDate": "Launch Date", + "launchDate": "Warm-up Time", "subscriptionDeadline": "Subscription Deadline" }, "units": { diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json index 7c79891..c4fbbe9 100644 --- a/src/locales/zh-CN.json +++ b/src/locales/zh-CN.json @@ -151,14 +151,16 @@ "enterTotalSupplyLimit": "请输入总发行量上限", "editionName": "发行期名称", "enterEditionName": "请输入发行期名称", - "launchDate": "发行日期", - "enterLaunchDate": "请输入发行日期", + "launchDate": "预热时间", + "enterLaunchDate": "请输入预热时间", "perUserLimit": "个人申购上限", "enterPerUserLimit": "请输入个人申购上限", "totalSupply": "发行总量", "enterTotalSupply": "请输入发行总量", "subscriptionDeadline": "申购截止日期", "enterSubscriptionDeadline": "请输入申购截止日期", + "subscriptionStartDate": "订阅开始时间", + "subscriptionEndDate": "订阅结束时间", "unitPrice": "单价", "enterUnitPrice": "请输入单价", "dividendRate": "分红率", @@ -176,8 +178,14 @@ "codeRequired": "产品编码是必填项", "categoryRequired": "产品类型是必填项", "editionNameRequired": "发行期名称是必填项", - "launchDateRequired": "发行日期是必填项", - "launchDateNotPast": "发行日期不能小于当前日期", + "launchDateRequired": "预热时间是必填项", + "launchDateNotPast": "预热时间不能早于当前时间", + "launchBeforeSubscription": "预热时间必须在订阅开始时间之前", + "subscriptionStartDateRequired": "订阅开始时间是必填项", + "subscriptionStartDateNotPast": "订阅开始时间不能早于当前时间", + "subscriptionAfterLaunch": "订阅开始时间必须在预热时间之后", + "subscriptionEndDateRequired": "订阅结束时间是必填项", + "subscriptionEndAfterStart": "订阅结束时间必须在订阅开始时间之后", "perUserLimitRequired": "个人申购上限是必填项", "totalSupplyRequired": "发行总量是必填项", "subscriptionDeadlineRequired": "申购截止日期是必填项", @@ -239,7 +247,7 @@ "unitPrice": "单价", "totalSupply": "总发行量", "perUserLimit": "每人限量", - "launchDate": "发行时间", + "launchDate": "预热时间", "subscriptionDeadline": "认购截止时间" }, "units": { diff --git a/src/locales/zh-HK.json b/src/locales/zh-HK.json index 3212444..c043475 100644 --- a/src/locales/zh-HK.json +++ b/src/locales/zh-HK.json @@ -151,14 +151,16 @@ "enterTotalSupplyLimit": "請輸入總發行量上限", "editionName": "發行期名稱", "enterEditionName": "請輸入發行期名稱", - "launchDate": "發行日期", - "enterLaunchDate": "請輸入發行日期", + "launchDate": "預熱時間", + "enterLaunchDate": "請輸入預熱時間", "perUserLimit": "個人申購上限", "enterPerUserLimit": "請輸入個人申購上限", "totalSupply": "發行總量", "enterTotalSupply": "請輸入發行總量", "subscriptionDeadline": "申購截止日期", "enterSubscriptionDeadline": "請輸入申購截止日期", + "subscriptionStartDate": "訂閱開始時間", + "subscriptionEndDate": "訂閱結束時間", "unitPrice": "單價", "enterUnitPrice": "請輸入單價", "dividendRate": "分紅率", @@ -176,8 +178,14 @@ "codeRequired": "產品編碼是必填項", "categoryRequired": "產品類型是必填項", "editionNameRequired": "發行期名稱是必填項", - "launchDateRequired": "發行日期是必填項", - "launchDateNotPast": "發行日期不能小於當前日期", + "launchDateRequired": "預熱時間是必填項", + "launchDateNotPast": "預熱時間不能早於當前時間", + "launchBeforeSubscription": "預熱時間必須在訂閱開始時間之前", + "subscriptionStartDateRequired": "訂閱開始時間是必填項", + "subscriptionStartDateNotPast": "訂閱開始時間不能早於當前時間", + "subscriptionAfterLaunch": "訂閱開始時間必須在預熱時間之後", + "subscriptionEndDateRequired": "訂閱結束時間是必填項", + "subscriptionEndAfterStart": "訂閱結束時間必須在訂閱開始時間之後", "perUserLimitRequired": "個人申購上限是必填項", "totalSupplyRequired": "發行總量是必填項", "subscriptionDeadlineRequired": "申購截止日期是必填項", @@ -239,7 +247,7 @@ "unitPrice": "單價", "totalSupply": "總發行量", "perUserLimit": "每人限量", - "launchDate": "發行時間", + "launchDate": "預熱時間", "subscriptionDeadline": "認購截止時間" }, "units": { diff --git a/src/theme/ionic.css b/src/theme/ionic.css index 8299433..015f104 100644 --- a/src/theme/ionic.css +++ b/src/theme/ionic.css @@ -22,16 +22,16 @@ ion-datetime.ui-datetime { --wheel-highlight-background: rgb(194 194 194); --wheel-fade-background-rgb: 255, 255, 255; border-radius: 16px; - overflow: hidden; + box-shadow: rgba(var(--ion-color-rose-rgb), 0.3) 0px 10px 15px -3px; } -.ion-palette-dark { - ion-datetime.ui-datetime { - --background: rgb(15, 15, 15); - --background-rgb: 15, 15, 15; - --wheel-highlight-background: rgb(50, 50, 50); - --wheel-highlight-border-radius: 48px; - --wheel-fade-background-rgb: 15, 15, 15; - } +html.ion-palette-dark ion-datetime.ui-datetime { + --background: rgb(15, 15, 15); + --background-rgb: 15, 15, 15; + --wheel-highlight-background: rgb(50, 50, 50); + --wheel-highlight-border-radius: 48px; + --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 { diff --git a/src/views/issue/issuing-apply/index.vue b/src/views/issue/issuing-apply/index.vue index 4ab6a21..cafefe6 100644 --- a/src/views/issue/issuing-apply/index.vue +++ b/src/views/issue/issuing-apply/index.vue @@ -9,7 +9,7 @@ import Done from "./done.vue"; import IssuePeriod from "./issue-period.vue"; 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("step", 1, { transform: v => Number(v), mode: "push" }); const initialData: RwaIssuanceProductBody = { @@ -23,7 +23,8 @@ const initialData: RwaIssuanceProductBody = { editionName: "", launchDate: new Date(), perUserLimit: "", - subscriptionDeadline: new Date(), + subscriptionStartDate: new Date(), + subscriptionEndDate: new Date(), totalSupply: "", unitPrice: "", dividendRate: "", diff --git a/src/views/issue/issuing-apply/issue-period.vue b/src/views/issue/issuing-apply/issue-period.vue index c212445..3b442e8 100644 --- a/src/views/issue/issuing-apply/issue-period.vue +++ b/src/views/issue/issuing-apply/issue-period.vue @@ -20,7 +20,8 @@ const initialIssuePeriod: RwaIssuanceProductBody["editions"][0] = { editionName: "", launchDate: new Date(), perUserLimit: "", - subscriptionDeadline: new Date(), + subscriptionStartDate: new Date(), + subscriptionEndDate: new Date(), totalSupply: "", unitPrice: "", dividendRate: "", @@ -30,6 +31,10 @@ const initialValues = ref({ 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({ editions: yup.array().of( yup.object({ @@ -40,17 +45,33 @@ const schema = toTypedSchema(yup.object({ if (!value) return true; 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")), 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")), dividendRate: yup.string().required(t("asset.issue.apply.validation.dividendRateRequired")), }), @@ -68,20 +89,22 @@ function handleSubmit(values: GenericObject) {
-