This commit is contained in:
Viet An
2026-06-09 11:43:27 +07:00
parent 5325168248
commit bb05320d65
19 changed files with 418 additions and 1008 deletions

View File

@@ -1,26 +1,4 @@
<!-- CountdownTimer.vue -->
<template>
<div class="countdown-wrapper">
<span
v-if="isExpired"
class="tag is-danger"
>
{{ isVietnamese ? "Hết giờ" : "Expired" }}
</span>
<span
v-else
class="tag"
:class="tagClass"
>
<span class="countdown-text">{{ formattedTime }}</span>
</span>
</div>
</template>
<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
import { useStore } from "~/stores/index";
const props = defineProps({
dateValue: {
type: [String, Date],
@@ -48,6 +26,8 @@ let intervalId = null;
const isVietnamese = computed(() => store.lang === "vi");
const tagClass = computed(() => {
if (isExpired) return "is-danger";
const totalSeconds =
timeRemaining.value.days * 86400 +
timeRemaining.value.hours * 3600 +
@@ -123,19 +103,15 @@ watch(
{ deep: true },
);
onMounted(() => {
startCountdown();
});
onMounted(startCountdown);
onBeforeUnmount(() => {
if (intervalId) {
clearInterval(intervalId);
}
clearInterval(intervalId);
});
</script>
<style scoped>
.countdown-wrapper {
display: inline-block;
}
</style>
<template>
<span :class="['tag', tagClass]">
{{ isExpired ? (isVietnamese ? "Hết giờ" : "Expired") : formattedTime }}
</span>
</template>

View File

@@ -0,0 +1,10 @@
<script setup>
const { $dayjs } = useNuxtApp();
const props = defineProps({
date: String,
});
</script>
<template>
<span>{{ $dayjs(date).format("L") }}</span>
</template>

View File

@@ -0,0 +1,10 @@
<script setup>
const { $empty, $numtoString } = useNuxtApp();
const props = defineProps({
value: Number,
});
</script>
<template>
<span>{{ $empty(value) ? "-" : $numtoString(value) }}</span>
</template>

View File

@@ -1,82 +1,85 @@
<script setup>
const props = defineProps(["row", "pagename"]);
const { $copyToClipboard } = useNuxtApp();
const phone = props.row.customer__phone || props.row.party__phone || props.row.phone;
const format = (s) => `${s.slice(0, 3)} ${s.slice(3, 6)} ${s.slice(6, 20)}`;
const text = format(phone);
const showmodal = ref();
function call() {
window.open(`tel:${phone}`);
}
function sms() {
window.open(`sms:${phone}`);
}
function openZalo() {
window.open(`https://zalo.me/${phone}`, "_blank");
}
function sendSms() {
showmodal.value = {
component: "user/Sms",
title: "Nhắn tin SMS",
width: "50%",
height: "400px",
vbind: {
row: props.row,
pagename: props.pagename,
api: "customersms",
},
};
}
</script>
<template>
<div>
<p class="fsb-30">
{{ text }}
<a
class="ml-3"
@click="copy()"
<p class="is-flex is-gap-1 is-align-items-center">
<span class="is-size-4 font-bold">
{{ text }}
</span>
<button
class="button is-small is-light is-primary rounded-full"
@click="$copyToClipboard(phone)"
>
<SvgIcon v-bind="{ name: 'copy.svg', type: 'primary', size: 24 }"></SvgIcon>
</a>
<span class="icon">
<Icon
name="material-symbols:content-copy-outline-rounded"
:size="17"
/>
</span>
</button>
</p>
<p class="buttons mt-4">
<p class="buttons are-small mt-2">
<button
class="button is-primary"
@click="call()"
@click="call"
>
Call
<span class="icon">
<Icon
name="material-symbols:call-outline-rounded"
:size="18"
/>
</span>
<span>Call</span>
</button>
<button
class="button is-primary"
@click="sms()"
class="button"
@click="sms"
>
SMS
</button>
<button
class="button is-primary"
@click="openZalo()"
class="button"
@click="openZalo"
>
Zalo
</button>
</p>
<Modal
@close="showmodal = undefined"
v-bind="showmodal"
v-if="showmodal"
></Modal>
v-bind="showmodal"
@close="showmodal = undefined"
/>
</div>
</template>
<script>
export default {
props: ["row", "pagename"],
data() {
return {
text: undefined,
phone: this.row.customer__phone || this.row.party__phone || this.row.phone,
showmodal: undefined,
};
},
created() {
var format = function (s) {
return `${s.slice(0, 3)} ${s.slice(3, 6)} ${s.slice(6, 20)}`;
};
this.text = format(this.phone);
},
methods: {
call() {
window.open(`tel:${this.phone}`);
},
sms() {
window.open(`sms:${this.phone}`);
},
sendSms() {
let api = this.row.code.indexOf("CN") >= 0 ? "customersms" : undefined;
if (this.row.code.indexOf("LN") >= 0) api = "loansms";
else if (this.row.code.indexOf("TS") >= 0) api = "collateralsms";
this.showmodal = {
component: "user/Sms",
title: "Nhắn tin SMS",
width: "50%",
height: "400px",
vbind: { row: this.row, pagename: this.pagename, api: api },
};
},
copy() {
this.$copyToClipboard(this.phone);
},
openZalo() {
window.open(`https://zalo.me/${this.phone}`, "_blank");
},
},
};
</script>

View File

@@ -1,13 +0,0 @@
<template>
<div>
<DataView
v-if="vbind"
v-bind="vbind"
></DataView>
</div>
</template>
<script>
export default {
props: ["vbind"],
};
</script>