This commit is contained in:
Viet An
2026-05-14 17:00:03 +07:00
parent 1f44f9e6bf
commit 400bbf242e
5 changed files with 76 additions and 71 deletions

View File

@@ -1,24 +1,25 @@
<template> <template>
<div> <div class="field is-grouped is-gap-1">
<Caption v-bind="{ title: 'Lỗi', type: 'has-text-findata' }"></Caption> <Icon
<div class="field is-grouped mb-0"> name="material-symbols:cancel-rounded"
<div :size="22"
class="control is-expanded pr-3" class="has-text-danger-70"
/>
<p
v-html="content" v-html="content"
></div> class="control is-expanded"
<div class="control"> ></p>
<SvgIcon v-bind="{ name: 'error.svg', type: 'danger', size: 24 }"></SvgIcon>
</div>
</div>
</div> </div>
</template> </template>
<script> <script setup>
export default { const props = defineProps({
props: ["content"], content: String,
methods: { title: String,
cancel() { });
this.$store.commit("updateStore", { name: "showmodal", data: undefined });
}, const { $store } = useNuxtApp();
},
}; function cancel() {
$store.commit("updateStore", { name: "showmodal", data: undefined });
}
</script> </script>

View File

@@ -2,10 +2,13 @@
<p v-html="props.content"></p> <p v-html="props.content"></p>
</template> </template>
<script setup> <script setup>
var props = defineProps({ const props = defineProps({
content: String, content: String,
}); });
const { $store } = useNuxtApp();
function cancel() { function cancel() {
this.$store.commit("updateStore", { name: "showmodal", data: undefined }); $store.commit("updateStore", { name: "showmodal", data: undefined });
} }
</script> </script>

View File

@@ -1,28 +1,29 @@
<template> <template>
<div class="show"> <div class="snackbar has-text-white has-background-grey-35 px-3 py-2 rounded-md">
<component <component
:is="dynamicComponent" :is="dynamicComponent"
v-bind="vbind" v-bind="vbind"
@close="$emit('close')" @close="$emit('close')"
></component> />
</div> </div>
</template> </template>
<script setup> <script setup>
import { defineAsyncComponent } from "vue"; import { defineAsyncComponent } from "vue";
import { useStore } from "@/stores/index"; import { useStore } from "@/stores/index";
const store = useStore(); const props = defineProps({
var props = defineProps({
component: String, component: String,
width: Number, width: String,
height: Number, height: String,
vbind: Object, vbind: Object,
title: String, title: String,
}); });
const dynamicComponent = defineAsyncComponent(() => import(`~/components/snackbar/Info.vue`));
const store = useStore();
const dynamicComponent = defineAsyncComponent(() => import(`../snackbar/${props.component || "Info"}.vue`));
setTimeout(() => store.commit("snackbar", undefined), 3900); setTimeout(() => store.commit("snackbar", undefined), 3900);
</script> </script>
<style> <style scoped>
.show { .snackbar {
position: fixed; position: fixed;
z-index: 999; z-index: 999;
top: 50px; top: 50px;
@@ -32,10 +33,6 @@ setTimeout(() => store.commit("snackbar", undefined), 3900);
width: fit-content; width: fit-content;
max-width: 500px; max-width: 500px;
background-color: #303030;
color: white;
border-radius: 6px;
padding: 10px;
/* Add animation: Take 0.5 seconds to fade in and out the snackbar. /* Add animation: Take 0.5 seconds to fade in and out the snackbar.
However, delay the fade out process for 2.5 seconds */ However, delay the fade out process for 2.5 seconds */
-webkit-animation: -webkit-animation:

View File

@@ -1,29 +1,25 @@
<template> <template>
<div> <div class="field is-grouped is-gap-1">
<Caption <Icon
v-bind="{ name="material-symbols:check-circle-rounded"
title: $stripHtml(title) || 'Thành công', :size="22"
type: 'has-text-primary', class="has-text-success"
}" />
></Caption> <p
<div class="field is-grouped mb-0 pb-0">
<div
class="control is-expanded pr-3 mb-0"
v-html="content" v-html="content"
></div> class="control is-expanded"
<div class="control mb-0"> ></p>
<SvgIcon v-bind="{ name: 'check2.svg', type: 'primary', size: 24 }"></SvgIcon>
</div>
</div>
</div> </div>
</template> </template>
<script> <script setup>
export default { const props = defineProps({
props: ["content", "title"], content: String,
methods: { title: String,
cancel() { });
this.$store.commit("updateStore", { name: "showmodal", data: undefined });
}, const { $store } = useNuxtApp();
},
}; function cancel() {
$store.commit("updateStore", { name: "showmodal", data: undefined });
}
</script> </script>

View File

@@ -27,7 +27,7 @@ export default defineNuxtPlugin((nuxtApp) => {
? `<span class="has-text-danger">${title}</span>` ? `<span class="has-text-danger">${title}</span>`
: title; : title;
let data = { const data = {
id: $id(), id: $id(),
component: `dialog/${type || "Info"}`, component: `dialog/${type || "Info"}`,
vbind: { content, duration, vbind }, vbind: { content, duration, vbind },
@@ -35,17 +35,24 @@ export default defineNuxtPlugin((nuxtApp) => {
width: width || "600px", width: width || "600px",
height: height || "100px", height: height || "100px",
}; };
$store.commit("showmodal", data); $store.commit("showmodal", data);
}; };
const snackbar = function (content, title, type, width, height) { const snackbar = function (content, title, type, width, height) {
content = typeof content == "string" ? content : JSON.stringify(content); content = typeof content == "string" ? content : JSON.stringify(content);
let vtitle = type === "Success" ? `<span class="has-text-primary">${title}</span>` : title;
if (type === "Error") vtitle = `<span class="has-text-danger">${title}</span>`; const vtitle =
let data = { type === "Success"
? `<span class="has-text-primary">${title}</span>`
: type === "Error"
? `<span class="has-text-danger">${title}</span>`
: title;
const data = {
id: $id(), id: $id(),
component: `snackbar/${type || "Info"}`, component: type || "Info",
vbind: { content: content }, vbind: { content },
title: vtitle, title: vtitle,
width: width || "600px", width: width || "600px",
height: height || "100px", height: height || "100px",
@@ -54,13 +61,14 @@ export default defineNuxtPlugin((nuxtApp) => {
}; };
const getLink = function (val) { const getLink = function (val) {
if (val === undefined || val === null || val === "" || val === "") return ""; if ($empty(val)) return "";
let json = val.indexOf("{") >= 0 ? JSON.parse(val) : { path: val }; const json = val.indexOf("{") >= 0 ? JSON.parse(val) : { path: val };
return json; return json;
}; };
const errPhone = function (phone) { const errPhone = function (phone) {
var text = undefined; let text;
if ($empty(phone)) { if ($empty(phone)) {
text = "Số điện thoại di động không được bỏ trống."; text = "Số điện thoại di động không được bỏ trống.";
} else if (isNaN(phone)) { } else if (isNaN(phone)) {
@@ -74,7 +82,7 @@ export default defineNuxtPlugin((nuxtApp) => {
const errEmail = function (email) { const errEmail = function (email) {
const re = const re =
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var text = undefined; let text = undefined;
if ($empty(email)) { if ($empty(email)) {
text = "Email không được bỏ trống."; text = "Email không được bỏ trống.";
} else if (!re.test(String(email).toLowerCase())) { } else if (!re.test(String(email).toLowerCase())) {
@@ -86,7 +94,7 @@ export default defineNuxtPlugin((nuxtApp) => {
const errPhoneEmail = function (contact) { const errPhoneEmail = function (contact) {
const re = const re =
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var text = undefined; let text = undefined;
if ($empty(contact)) { if ($empty(contact)) {
text = "Số điện thoại di động hoặc Email không được bỏ trống."; text = "Số điện thoại di động hoặc Email không được bỏ trống.";