240 lines
6.2 KiB
Vue
240 lines
6.2 KiB
Vue
<script setup>
|
|
definePageMeta({
|
|
title: "Penyunting Kandungan",
|
|
middleware: ["auth"],
|
|
requiresAuth: true,
|
|
});
|
|
|
|
const { $swal, $router } = useNuxtApp();
|
|
const router = useRouter();
|
|
|
|
const getPages = router.getRoutes();
|
|
|
|
const pages = getPages.filter((page) => {
|
|
// filter out the pages that are not in the admin folder
|
|
return (
|
|
page.path.includes("/devtool") === false &&
|
|
page.meta?.title &&
|
|
page.meta?.title !== "Laman Utama" &&
|
|
page.name
|
|
);
|
|
});
|
|
|
|
const searchText = ref("");
|
|
const showModal = ref(false);
|
|
const modalData = ref({
|
|
name: "",
|
|
path: "",
|
|
});
|
|
|
|
const searchPages = () => {
|
|
return pages.filter((page) => {
|
|
return page.meta.title
|
|
.toLowerCase()
|
|
.includes(searchText.value.toLowerCase());
|
|
});
|
|
};
|
|
|
|
const capitalizeSentence = (sentence) => {
|
|
return sentence
|
|
.split(" ")
|
|
.map((word) => {
|
|
return word[0].toUpperCase() + word.slice(1);
|
|
})
|
|
.join(" ");
|
|
};
|
|
|
|
const templateOptions = ref([{ label: "Pilih Templat", value: "" }]);
|
|
const selectTemplate = ref("");
|
|
|
|
const { data: templates } = await useFetch(
|
|
"/api/devtool/content/template/list",
|
|
{
|
|
method: "GET",
|
|
}
|
|
);
|
|
|
|
templateOptions.value.push(
|
|
...templates?.value.data.map((template) => {
|
|
return {
|
|
label: `${template.title} - ${template.id}`,
|
|
value: template.id,
|
|
};
|
|
})
|
|
);
|
|
|
|
const importTemplate = (pageName) => {
|
|
showModal.value = true;
|
|
modalData.value.name = pageName;
|
|
modalData.value.path = router.getRoutes().find((page) => {
|
|
return page.name === pageName;
|
|
}).path;
|
|
};
|
|
|
|
const confirmModal = async () => {
|
|
$swal
|
|
.fire({
|
|
title: "Adakah anda pasti mahu mengimport templat ini?",
|
|
text: "Tindakan ini tidak boleh dibatalkan.",
|
|
icon: "warning",
|
|
showCancelButton: true,
|
|
confirmButtonColor: "#3085d6",
|
|
cancelButtonColor: "#d33",
|
|
confirmButtonText: "Ya",
|
|
})
|
|
.then(async (result) => {
|
|
if (result.isConfirmed) {
|
|
const { data: res } = await useFetch(
|
|
"/api/devtool/content/template/import",
|
|
{
|
|
initialCache: false,
|
|
method: "GET",
|
|
query: {
|
|
path: modalData.value.path + "/index",
|
|
templateId: selectTemplate.value,
|
|
},
|
|
}
|
|
);
|
|
|
|
if (res.value.statusCode == 200) {
|
|
$swal.fire({
|
|
title: "Berjaya",
|
|
text: res.value.message,
|
|
icon: "success",
|
|
confirmButtonText: "Ok",
|
|
timer: 1000,
|
|
});
|
|
|
|
setTimeout(() => {
|
|
$router.go();
|
|
}, 1000);
|
|
}
|
|
}
|
|
})
|
|
.finally(() => {
|
|
showModal.value = false;
|
|
});
|
|
};
|
|
</script>
|
|
<template>
|
|
<div>
|
|
<LayoutsBreadcrumb />
|
|
<rs-card>
|
|
<template #header>
|
|
<div class="flex">
|
|
<Icon class="mr-2 flex justify-center" name="ic:outline-info"></Icon
|
|
>Maklumat
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<p class="mb-4">
|
|
Halaman ini digunakan untuk menyunting kandungan halaman. Anda boleh menyunting
|
|
kandungan halaman dengan memilih halaman untuk disunting dari senarai kad
|
|
di bawah.
|
|
</p>
|
|
</template>
|
|
</rs-card>
|
|
|
|
<rs-card>
|
|
<div class="p-4">
|
|
<!-- Search Button -->
|
|
<FormKit
|
|
v-model="searchText"
|
|
placeholder="Cari Tajuk..."
|
|
type="search"
|
|
/>
|
|
|
|
<div
|
|
class="page-wrapper grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5"
|
|
v-auto-animate
|
|
>
|
|
<!-- <div
|
|
class="page border-2 border-gray-400 border-dashed rounded-lg"
|
|
style="min-height: 250px"
|
|
>
|
|
Tambah Halaman Baru
|
|
</div> -->
|
|
<div
|
|
v-for="page in searchPages()"
|
|
:key="page.path"
|
|
class="page shadow-md shadow-black/5 p-5 ring-1 ring-slate-700/10 rounded-lg"
|
|
>
|
|
<div class="pb-4">
|
|
<h4 class="font-semibold">
|
|
{{ capitalizeSentence(page.meta.title) }}
|
|
</h4>
|
|
<nuxt-link :to="page.path">
|
|
<div
|
|
class="flex items-center text-primary hover:text-primary/70"
|
|
>
|
|
<Icon
|
|
class="mr-2"
|
|
name="ic:outline-link"
|
|
style="font-size: 1.2rem"
|
|
></Icon>
|
|
<p class="text-sm">{{ page.path }}</p>
|
|
</div>
|
|
</nuxt-link>
|
|
</div>
|
|
<div
|
|
class="button-list flex justify-between border-t pt-4 border-gray-300"
|
|
>
|
|
<div class="flex gap-x-2">
|
|
<nuxt-link
|
|
:to="`/devtool/content-editor/code?page=${page.name}`"
|
|
>
|
|
<rs-button variant="primary" class="!py-2 !px-3">
|
|
<Icon
|
|
name="material-symbols:code-blocks-outline-rounded"
|
|
></Icon>
|
|
</rs-button>
|
|
</nuxt-link>
|
|
</div>
|
|
<rs-button
|
|
variant="primary-text"
|
|
class="!py-2 !px-3"
|
|
@click="importTemplate(page.name)"
|
|
>
|
|
<Icon name="mdi:import"></Icon>
|
|
</rs-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</rs-card>
|
|
|
|
<rs-modal :title="`Import (${modalData.name})`" v-model="showModal">
|
|
<FormKit
|
|
v-model="selectTemplate"
|
|
type="select"
|
|
label="Templat Kandungan"
|
|
:options="templateOptions"
|
|
validation="required"
|
|
validation-visibility="dirty"
|
|
help="Sila pilih dengan teliti templat yang anda ingin import. Tindakan ini tidak boleh dibatalkan."
|
|
/>
|
|
<template #footer>
|
|
<rs-button @click="showModal = false" variant="primary-text">
|
|
Batal
|
|
</rs-button>
|
|
<rs-button @click="confirmModal" :disabled="!selectTemplate"
|
|
>Sahkan</rs-button
|
|
>
|
|
</template>
|
|
</rs-modal>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.thumbnail::before {
|
|
content: "";
|
|
display: block;
|
|
height: 100%;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
}
|
|
</style>
|