Security/register account #1

Merged
ismailmasseran merged 6 commits from security/register-account into main 2026-10-19 13:31:06 +08:00
28 changed files with 941 additions and 379 deletions
Showing only changes of commit 3fcf482383 - Show all commits
@@ -1,115 +1,412 @@
<template>
<Toast :breakpoints="{ '767px': { width: '100%', right: '0', left: '0' } }" />
<div class="flex main-container min-h-screen align-items-center justify-content-center">
<div class="surface-card fadein p-4 shadow-2 border-round w-11 md:w-10 lg:w-8 xl:w-7 content-bg">
<div class="text-center mb-5">
<div class="text-900 text-3xl font-semibold mb-3">
Lelong Erahn
<!-- <img class="logo-img" src="img/logo_arrahn.png" alt="arrahn-logo" /> -->
</div>
<span class="text-600 font-medium line-height-3">Belum punyai akaun?</span>
<router-link v-bind:to="{ name: 'register' }"
class="font-medium no-underline ml-2 text-blue-500 cursor-pointer">Daftar sekarang!</router-link>
</div>
<form @submit.prevent="submit">
<div class="px-0 text-center md:px-8">
<div class="field grid">
<label for="firstname3" class="justify-content-end" style="width: 170px">Emel</label>
<div class="col">
<span class="p-input-icon-right">
<i class="pi pi-user"></i>
<InputText class="mb-2" type="text" v-model="email" required></InputText>
</span>
</div>
</div>
<div class="">
<Button @click="doForgotPassword()" type="submit" class="p-button-sm" label="Lupa Katalaluan"
icon="pi pi-sign-in" :loading="isLoading" iconPos="right"></Button>
</div>
</div>
</form>
<div class="mt-3 text-center">
<router-link v-bind:to="{ name: 'login' }">Kembali ke Log Masuk</router-link>
</div>
<Toast :breakpoints="{ '767px': { width: '100%', right: '0', left: '0' } }" />
<div class="forgot-page">
<div class="forgot-backdrop" aria-hidden="true"></div>
<div class="forgot-shell">
<section class="forgot-brand">
<div class="brand-mark">
<img src="img/e-Rahn_Logo_FA-01.png" alt="" class="brand-seal" />
<img src="img/e-rahn-lelong.png" alt="E-Rahn Lelong" class="brand-wordmark" />
</div>
<h1 class="brand-title">ArrahnBid</h1>
<p class="brand-copy">
Masukkan emel akaun anda dan kami akan hantar pautan untuk tetapkan semula kata laluan.
</p>
</section>
<section class="forgot-panel">
<header class="panel-header">
<h2>Lupa Kata Laluan</h2>
<p>
Belum punya akaun?
<router-link :to="{ name: 'register' }">Daftar sekarang</router-link>
</p>
</header>
<form class="forgot-form" @submit.prevent="doForgotPassword">
<label class="field">
<span class="field-label">Emel</span>
<div class="field-control">
<Mail class="field-icon" :size="18" :stroke-width="1.75" />
<InputText
v-model="email"
type="email"
placeholder="nama@emel.com"
autocomplete="email"
required
/>
</div>
</label>
<button class="submit-btn" type="submit" :disabled="isLoading">
<span>{{ isLoading ? "Sedang hantar..." : "Hantar Pautan" }}</span>
<LoaderCircle v-if="isLoading" class="spin" :size="18" :stroke-width="2" />
<ArrowRight v-else :size="18" :stroke-width="2" />
</button>
</form>
<router-link class="back-link" :to="{ name: 'login' }">
<ChevronLeft :size="16" :stroke-width="2" />
<span>Kembali ke Log Masuk</span>
</router-link>
</section>
</div>
</div>
</template>
<script>
import axios from "axios";
import { ArrowRight, ChevronLeft, LoaderCircle, Mail } from "@lucide/vue";
export default {
name: "Login",
data() {
return {
isLoading: false,
email: "",
};
name: "ForgotPassword",
components: {
ArrowRight,
ChevronLeft,
LoaderCircle,
Mail,
},
data() {
return {
isLoading: false,
email: "",
};
},
methods: {
doForgotPassword() {
this.isLoading = true;
axios
.post("/forgotPassword", { email: this.email })
.then((response) => {
console.log(response);
if (response.data.success == true) {
this.$swal.fire({
icon: "success",
title: "Pautan Lupa Katalaluan Telah Dihantar!",
text: "Sila semak emel anda untuk tindakan lebih lanjut",
confirmButtonColor: "#344871",
confirmButtonText: "OK",
allowOutsideClick: false,
allowEscapeKey: false,
});
this.email = "";
this.isLoading = false;
} else if (response.data.success == false) {
if (response.data.status == 0) {
this.$toast.add({
severity: "error",
summary: "Emel tidak dijumpai",
detail: "Sila semak emel anda",
life: 10000,
});
this.isLoading = false;
} else if (response.data.status == 500) {
this.$swal.fire({
icon: "error",
title: "Failed!",
text: "There is some issue with email provider, please contact admin.",
confirmButtonColor: "#344871",
confirmButtonText: "OK",
allowOutsideClick: false,
allowEscapeKey: false,
});
this.isLoading = false;
}
}
})
.catch((response) => {
alert(response);
this.isLoading = false;
});
},
methods: {
doForgotPassword() {
this.isLoading = true;
axios
.post("/forgotPassword", { email: this.email },)
.then((response) => {
console.log(response);
if (response.data.success == true) {
this.$swal.fire({
icon: "success",
title: "Pautan Lupa Katalaluan Telah Dihantar!",
text: "Sila semak emel anda untuk tindakan lebih lanjut",
confirmButtonColor: "#344871",
confirmButtonText: "OK",
allowOutsideClick: false,
allowEscapeKey: false,
});
this.email = "";
this.isLoading = false;
} else if (response.data.success == false) {
if (response.data.status == 0) {
this.$toast.add({
severity: "error",
summary: "Emel tidak dijumpai",
detail: "Sila semak emel anda",
life: 10000,
});
this.isLoading = false;
} else if (response.data.status == 500) {
this.$swal.fire({
icon: "error",
title: "Failed!",
text: "There is some issue with email provider, please contact admin.",
confirmButtonColor: "#344871",
confirmButtonText: "OK",
allowOutsideClick: false,
allowEscapeKey: false,
});
}
}
})
.catch((response) => {
alert(response);
this.isLoading = false;
});
}
}
}
},
};
</script>
<style scoped>
.main-container {
background: url("/src/assets/background-lelong.png");
background-position: center;
background-size: cover;
@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&family=Sora:wght@500;600;700&display=swap");
.forgot-page {
--ink: #132a4f;
--navy: #1e417b;
--blue: #2f68c5;
--gold: #fec234;
--panel: rgba(255, 252, 247, 0.94);
--line: rgba(19, 42, 79, 0.12);
--muted: rgba(19, 42, 79, 0.68);
position: relative;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
overflow: hidden;
font-family: "Manrope", sans-serif;
color: var(--ink);
}
.content-bg {
background: #fff9f9eb !important;
.forgot-backdrop {
position: absolute;
inset: 0;
background:
linear-gradient(115deg, rgba(19, 42, 79, 0.78) 0%, rgba(30, 65, 123, 0.55) 42%, rgba(254, 194, 52, 0.35) 100%),
url("/src/assets/background-lelong.png") center / cover no-repeat;
transform: scale(1.04);
animation: backdrop-drift 18s ease-in-out infinite alternate;
}
.logo-img {
width: 84px;
height: 44px;
.forgot-shell {
position: relative;
z-index: 1;
width: min(980px, 100%);
display: grid;
grid-template-columns: 1.05fr 0.95fr;
border-radius: 28px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.28);
background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(10px);
animation: shell-enter 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}
</style>
.forgot-brand {
padding: 3rem 2.75rem;
color: #fffdf8;
background:
linear-gradient(160deg, rgba(19, 42, 79, 0.28), rgba(47, 104, 197, 0.1)),
radial-gradient(circle at top left, rgba(254, 194, 52, 0.35), transparent 55%);
display: flex;
flex-direction: column;
justify-content: flex-end;
min-height: 560px;
}
.brand-mark {
display: flex;
align-items: center;
gap: 0.85rem;
margin-bottom: auto;
animation: rise 0.8s 0.1s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.brand-seal {
width: 52px;
height: 52px;
object-fit: contain;
filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.18));
}
.brand-wordmark {
width: min(180px, 50vw);
height: auto;
object-fit: contain;
}
.brand-title {
margin: 0 0 0.75rem;
font-family: "Sora", sans-serif;
font-size: clamp(2.4rem, 4vw, 3.4rem);
font-weight: 700;
letter-spacing: -0.04em;
line-height: 1.05;
animation: rise 0.8s 0.18s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.brand-copy {
margin: 0;
max-width: 30ch;
font-size: 1.05rem;
line-height: 1.55;
color: rgba(255, 253, 248, 0.88);
animation: rise 0.8s 0.26s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.forgot-panel {
background: var(--panel);
padding: 2.75rem 2.5rem;
display: flex;
flex-direction: column;
justify-content: center;
animation: rise 0.8s 0.2s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.panel-header h2 {
margin: 0 0 0.4rem;
font-family: "Sora", sans-serif;
font-size: 1.85rem;
letter-spacing: -0.03em;
}
.panel-header p {
margin: 0 0 1.75rem;
color: var(--muted);
}
.panel-header a,
.back-link {
color: var(--blue);
font-weight: 600;
text-decoration: none;
}
.panel-header a:hover,
.back-link:hover {
color: var(--navy);
text-decoration: underline;
}
.forgot-form {
display: grid;
gap: 1rem;
}
.field {
display: grid;
gap: 0.45rem;
}
.field-label {
font-size: 0.92rem;
font-weight: 600;
color: var(--ink);
}
.field-control {
display: flex;
align-items: center;
gap: 0.65rem;
min-height: 3.15rem;
padding: 0 0.95rem;
border: 1px solid var(--line);
border-radius: 14px;
background: #fff;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.field-control:focus-within {
border-color: var(--blue);
box-shadow: 0 0 0 3px rgba(47, 104, 197, 0.14);
}
.field-icon {
flex: 0 0 auto;
color: var(--navy);
opacity: 0.72;
}
.field-control :deep(.p-inputtext) {
flex: 1 1 auto;
width: 100%;
min-width: 0;
border: 0 !important;
box-shadow: none !important;
background: transparent !important;
padding: 0.85rem 0 !important;
font-family: inherit;
font-size: 0.98rem;
color: var(--ink);
}
.submit-btn {
margin-top: 0.35rem;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.55rem;
width: 100%;
min-height: 3.2rem;
border: 0;
border-radius: 14px;
background: linear-gradient(135deg, var(--navy) 0%, var(--blue) 100%);
color: #fff;
font-family: "Sora", sans-serif;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s ease, filter 0.2s ease;
}
.submit-btn:hover:not(:disabled) {
filter: brightness(1.05);
transform: translateY(-1px);
}
.submit-btn:disabled {
opacity: 0.8;
cursor: wait;
}
.back-link {
margin-top: 1.5rem;
display: inline-flex;
align-items: center;
gap: 0.35rem;
width: fit-content;
}
.spin {
animation: spin 0.8s linear infinite;
}
@keyframes shell-enter {
from {
opacity: 0;
transform: translateY(18px) scale(0.985);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes rise {
from {
opacity: 0;
transform: translateY(14px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes backdrop-drift {
from {
transform: scale(1.04) translate3d(0, 0, 0);
}
to {
transform: scale(1.08) translate3d(-1.2%, -0.8%, 0);
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
@media (max-width: 900px) {
.forgot-shell {
grid-template-columns: 1fr;
}
.forgot-brand {
min-height: auto;
padding: 2rem 1.6rem 1.4rem;
}
.brand-title {
font-size: 2.2rem;
}
.brand-copy {
max-width: none;
}
.forgot-panel {
padding: 1.75rem 1.4rem 2rem;
}
}
</style>
+32 -17
View File
@@ -123,7 +123,28 @@ export default {
const authenticationStore = useAuthenticationUserStore();
return { authenticationStore };
},
mounted() {
this.showEmailVerificationToast();
},
methods: {
showEmailVerificationToast() {
const { email_verified, message } = this.$route.query;
if (email_verified === undefined) {
return;
}
const verified = String(email_verified) === "1";
this.$toast.add({
severity: verified ? "success" : "error",
summary: verified ? "Pengesahan Emel" : "Pengesahan Emel Gagal",
detail: message || (verified
? "Emel berjaya disahkan. Sila log masuk."
: "Pautan pengesahan tidak sah."),
life: 10000,
});
this.$router.replace({ query: {} });
},
doLogin() {
this.v$.$validate();
if (!this.v$.$error) {
@@ -132,24 +153,9 @@ export default {
.post("/user/login", this.form)
.then((response) => {
if (response.data.statusAkaun == 1) {
localStorage.setItem("token", response.data.token);
localStorage.setItem("id", response.data.user.id);
localStorage.setItem("nokp", response.data.user.nokp);
localStorage.setItem("name", response.data.user.name);
localStorage.setItem("email", response.data.user.email);
localStorage.setItem(
"notelbimbit",
response.data.user.notelbimbit
);
localStorage.setItem("username", response.data.user.username);
this.authenticationStore.$patch({
this.authenticationStore.setSession({
token: response.data.token,
id: response.data.user.id,
nokp: response.data.user.nokp,
name: response.data.user.name,
email: response.data.user.email,
notelbimbit: response.data.user.notelbimbit,
username: response.data.user.username,
user: response.data.user,
});
this.$router.push({ name: "home" });
} else if (response.data.statusAkaun == 0) {
@@ -198,6 +204,15 @@ export default {
"Sila log masuk menggunakan url https://adminlelong.erahn.com.my ",
life: 10000,
});
} else if (response.data.statusAkaun == 7) {
this.$toast.add({
severity: "warn",
summary: "Emel Belum Disahkan",
detail:
response.data.message ||
"Sila sahkan emel anda sebelum log masuk.",
life: 10000,
});
}
this.isLoading = false;
})
+187 -46
View File
@@ -334,27 +334,17 @@ export default {
.post("/register", this.form)
.then((response) => {
if (response.data.success == true) {
localStorage.setItem("token", response.data.token);
localStorage.setItem("id", response.data.user.id);
localStorage.setItem("nokp", response.data.user.nokp);
localStorage.setItem("name", response.data.user.name);
localStorage.setItem("email", response.data.user.email);
localStorage.setItem(
"notelbimbit",
response.data.user.notelbimbit
);
localStorage.setItem("username", response.data.user.username);
this.authenticationStore.$patch({
token: response.data.token,
id: response.data.user.id,
nokp: response.data.user.nokp,
name: response.data.user.name,
email: response.data.user.email,
notelbimbit: response.data.user.notelbimbit,
username: response.data.user.username,
});
this.$router.push({ name: "home" });
this.isLoading = false;
this.isDisplayTNC = false;
this.$toast.add({
severity: "success",
summary: "Pendaftaran Berjaya",
detail:
response.data.message ||
"Sila semak emel anda untuk pautan pengesahan.",
life: 10000,
});
this.$router.push({ name: "login" });
} else if (response.data.success == false) {
this.isLoading = false;
this.isDisplayTNC = false;
@@ -442,11 +432,13 @@ export default {
position: relative;
min-height: 100vh;
min-height: 100dvh;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
overflow: hidden;
overflow-x: hidden;
overflow-y: auto;
font-family: "Manrope", sans-serif;
color: var(--ink);
}
@@ -901,6 +893,169 @@ export default {
overflow: auto;
padding-right: 0.25rem;
}
@media (max-width: 960px) {
.register-page {
align-items: flex-start;
padding: 0.85rem;
}
.register-shell {
grid-template-columns: 1fr;
border-radius: 22px;
width: 100%;
}
.register-brand {
min-height: auto;
padding: 1.25rem 1.25rem 1rem;
justify-content: flex-start;
}
.brand-mark {
margin-bottom: 1rem;
}
.brand-seal {
width: 40px;
height: 40px;
}
.brand-wordmark {
width: min(140px, 42vw);
}
.brand-title {
font-size: 1.85rem;
margin-bottom: 0.4rem;
}
.brand-copy {
max-width: none;
font-size: 0.92rem;
line-height: 1.45;
}
.register-panel {
max-height: none;
overflow: visible;
padding: 1.25rem 1.15rem 1.5rem;
}
.panel-header h2 {
font-size: 1.45rem;
}
.panel-header p {
margin-bottom: 1rem;
font-size: 0.92rem;
}
.stepper {
grid-template-columns: auto minmax(12px, 1fr) auto minmax(12px, 1fr) auto;
align-items: start;
gap: 0.25rem;
margin-bottom: 1.15rem;
}
.stepper-item {
flex-direction: column;
align-items: center;
gap: 0.3rem;
padding: 0.15rem;
text-align: center;
}
.stepper-meta {
justify-items: center;
}
.stepper-label {
font-size: 0.72rem;
line-height: 1.2;
white-space: normal;
}
.stepper-hint {
display: none;
}
.stepper-line {
align-self: start;
margin-top: 0.9rem;
}
.form-grid,
.actions {
grid-template-columns: 1fr;
}
.actions {
gap: 0.65rem;
margin-top: 0.5rem;
}
.ghost-btn,
.submit-btn {
width: 100%;
}
.field-control-phone {
padding: 0.35rem;
}
.field-control-phone :deep(.m-phone-number-input) {
display: flex;
flex-wrap: wrap;
gap: 0.45rem;
}
.field-control-phone :deep(.m-input-wrapper),
.field-control-phone :deep(.m-phone-number-input > *) {
min-width: 0;
max-width: 100%;
}
}
@media (max-width: 560px) {
.register-page {
padding: 0;
}
.register-shell {
border-radius: 0;
border: 0;
min-height: 100vh;
min-height: 100dvh;
}
.register-brand {
padding: 1rem 1rem 0.85rem;
}
.brand-copy {
display: none;
}
.register-panel {
padding: 1.1rem 1rem 1.35rem;
flex: 1;
}
.stepper-index {
width: 1.7rem;
height: 1.7rem;
font-size: 0.78rem;
}
.stepper-label {
font-size: 0.68rem;
}
.agree-row {
font-size: 0.88rem;
}
}
</style>
<style>
@@ -917,36 +1072,22 @@ export default {
display: flex;
justify-content: flex-end;
}
</style>
<style scoped>
@media (max-width: 960px) {
.register-shell {
grid-template-columns: 1fr;
@media (max-width: 560px) {
.register-tnc-dialog.p-dialog {
width: 100vw !important;
max-width: 100vw !important;
margin: 0 !important;
}
.register-brand {
min-height: auto;
padding: 1.75rem 1.5rem 1.25rem;
.register-tnc-dialog.p-dialog .tnc-dialog-footer {
flex-direction: column-reverse;
align-items: stretch;
}
.register-panel {
max-height: none;
padding: 1.5rem 1.25rem 1.75rem;
}
.form-grid,
.actions {
grid-template-columns: 1fr;
}
.stepper {
grid-template-columns: 1fr;
gap: 0.55rem;
}
.stepper-line {
display: none;
.register-tnc-dialog.p-dialog .tnc-dialog-footer .p-button {
width: 100%;
justify-content: center;
}
}
</style>
+4 -3
View File
@@ -231,6 +231,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
import ItemMasterImageModal from "../list/ItemMasterImageModal.vue";
@@ -248,7 +249,7 @@ export default {
date: "",
lelongDetail: "",
reloadImageComponent: 0,
// userId: localStorage.getItem("id"),
// userId: useAuthenticationUserStore().id,
};
},
mounted: function () {
@@ -268,9 +269,9 @@ export default {
bidRecord() {
this.isLoading = true;
axios
.get("/bidRecordByCawangan/" + localStorage.getItem("id"), {
.get("/bidRecordByCawangan/" + useAuthenticationUserStore().id, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
+10 -9
View File
@@ -684,6 +684,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
import useVuelidate from "@vuelidate/core";
import { required, integer, numeric, minValue } from "@vuelidate/validators";
@@ -717,14 +718,14 @@ export default {
lelongBidId: "",
},
formEdit: {
userId: localStorage.getItem("id"),
userId: useAuthenticationUserStore().id,
lelongBidId: "",
hargabida: "",
},
formRegisterBid: {
lelong_id: localStorage.getItem("lelong_id"),
user_id: localStorage.getItem("id"),
name: localStorage.getItem("name"),
user_id: useAuthenticationUserStore().id,
name: useAuthenticationUserStore().name,
},
};
},
@@ -748,9 +749,9 @@ export default {
listCart() {
this.isLoading = true;
axios
.get("/cartByCawangan/" + localStorage.getItem("id"), {
.get("/cartByCawangan/" + useAuthenticationUserStore().id, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
@@ -778,12 +779,12 @@ export default {
},
deleteItem(value) {
this.isLoadingPadam = true;
this.formDelete.userId = localStorage.getItem("id");
this.formDelete.userId = useAuthenticationUserStore().id;
this.formDelete.lelongBidId = value.id;
axios
.post("/deleteItem", this.formDelete, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
@@ -836,7 +837,7 @@ export default {
axios
.post("/updateItem", this.formEdit, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
@@ -882,7 +883,7 @@ export default {
axios
.post("/bidder/biditem", this.formRegisterBid, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
@@ -16,6 +16,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
@@ -36,10 +37,10 @@ export default {
axios
.get("/itemInCart", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
},
})
+4 -3
View File
@@ -14,6 +14,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
@@ -28,17 +29,17 @@ export default {
},
methods: {
resultStatus() {
// "/resultStatus/" + localStorage.getItem("id") + "/" + this.lelongId,
// "/resultStatus/" + useAuthenticationUserStore().id + "/" + this.lelongId,
},
getLelong() {
this.loading = true;
axios
.get("/resultLelong", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
},
})
+12 -23
View File
@@ -255,12 +255,13 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
data() {
return {
username: localStorage.getItem("username"),
username: useAuthenticationUserStore().username,
visibleLeft: false,
lelongOnline: "",
};
@@ -274,27 +275,15 @@
this.getLelongOnline();
},
methods: {
doLogout() {
axios
.post(
"/user/logout",
{},
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
)
.then((response) => {
localStorage.clear();
this.authenticationStore.$reset();
this.$router.push({ name: "login" });
})
.catch((error) => {
console.log(error);
});
localStorage.clear();
this.$router.push({ name: "login" });
async doLogout() {
try {
await axios.post("/user/logout");
} catch (error) {
console.log(error);
} finally {
this.authenticationStore.clearSession();
this.$router.push({ name: "login" });
}
},
toHome() {
this.$router.push({ name: "home" });
@@ -306,7 +295,7 @@
axios
.get("/lelongOnline", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
+13 -25
View File
@@ -210,7 +210,7 @@ import { useAuthenticationUserStore } from "@/store/modules/authentication"
export default {
data() {
return {
username: localStorage.getItem("username"),
username: useAuthenticationUserStore().username,
visibleRight: false,
lelongOnline: "",
isSuccessCart: false,
@@ -227,27 +227,15 @@ export default {
// this.getItemInCart();
},
methods: {
doLogout() {
axios
.post(
"/user/logout",
{},
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
)
.then((response) => {
localStorage.clear();
this.authenticationStore.$reset();
this.$router.push({ name: "login" });
})
.catch((error) => {
console.log(error);
});
localStorage.clear();
this.$router.push({ name: "login" });
async doLogout() {
try {
await axios.post("/user/logout");
} catch (error) {
console.log(error);
} finally {
this.authenticationStore.clearSession();
this.$router.push({ name: "login" });
}
},
toHome() {
this.$router.push({ name: "home" });
@@ -262,7 +250,7 @@ export default {
axios
.get("/lelongOnline", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
@@ -287,10 +275,10 @@ export default {
axios
.get("/itemInCart", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
},
})
+2 -1
View File
@@ -6,6 +6,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
@@ -34,7 +35,7 @@ export default {
axios
.get("/photoMarhun", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
norujukan: this.norujukan,
+2 -1
View File
@@ -8,6 +8,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
@@ -36,7 +37,7 @@ export default {
axios
.get("/photoMarhun", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
norujukan: this.norujukan,
+5 -4
View File
@@ -411,6 +411,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
import useVuelidate from "@vuelidate/core";
import { required, integer, numeric, minValue } from "@vuelidate/validators";
@@ -449,7 +450,7 @@ export default {
tambahan: "",
// image: "",
form: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
lelongbid_id: "",
hargabida: "",
},
@@ -483,11 +484,11 @@ export default {
axios
.get("/lelongDetails/listSuratLelong", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
caw_id: this.selectedCawangan,
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
lelong_id: localStorage.getItem("lelong_id"),
},
})
@@ -546,7 +547,7 @@ export default {
axios
.post("/addToCart", this.form, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
+2 -1
View File
@@ -73,6 +73,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import ListItem from "./ListItem.vue";
import axios from "axios";
@@ -107,7 +108,7 @@ export default {
axios
.get("/listcawlelongtodaystarted", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
+4 -3
View File
@@ -81,6 +81,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
import ReceiptImage from "./ReceiptImage.vue";
@@ -112,10 +113,10 @@ export default {
axios
.get("/listPhotoResit", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
lelong_id: this.lelong_id,
},
})
@@ -151,7 +152,7 @@ export default {
{ fileresit_id: this.fileresit_id },
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
}
)
+2 -1
View File
@@ -8,6 +8,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
@@ -35,7 +36,7 @@ export default {
axios
.get("/showPhotoResit", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
fileresit_id: this.fileResitId,
+7 -6
View File
@@ -69,6 +69,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
emits: ["back-is-click"],
@@ -80,10 +81,10 @@ export default {
return {
// changeProp: finalSurat,
form: {
email: localStorage.getItem("email"),
notel: localStorage.getItem("notelbimbit"),
name: localStorage.getItem("name"),
user_id: localStorage.getItem("id"),
email: useAuthenticationUserStore().email,
notel: useAuthenticationUserStore().notelbimbit,
name: useAuthenticationUserStore().name,
user_id: useAuthenticationUserStore().id,
lelong_id: localStorage.getItem("lelong_id"),
invoice_id: "",
invoice_no: "",
@@ -112,10 +113,10 @@ export default {
axios
.get("/invoice", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
lelong_id: localStorage.getItem("lelong_id"),
},
})
+8 -7
View File
@@ -259,6 +259,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import SelectId from "./SelectId.vue";
import TermsAndConditionsDetails from "../authentication/TermsAndConditionsDetails.vue";
import axios from "axios";
@@ -294,10 +295,10 @@ export default {
lelongDetails: "",
fileSize: 0,
form: {
email: localStorage.getItem("email"),
notel: localStorage.getItem("notelbimbit"),
name: localStorage.getItem("name"),
user_id: localStorage.getItem("id"),
email: useAuthenticationUserStore().email,
notel: useAuthenticationUserStore().notelbimbit,
name: useAuthenticationUserStore().name,
user_id: useAuthenticationUserStore().id,
lelong_id: "",
invoice_id: "",
invoice_no: "",
@@ -333,10 +334,10 @@ export default {
axios
.get("/invoice", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
lelong_id: this.lelongIdProps,
},
})
@@ -414,7 +415,7 @@ export default {
axios
.post("/initializeCdmPayment", resitFormData, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
+3 -2
View File
@@ -84,6 +84,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
import SelectOutlet from "./SelectOutlet.vue";
// import SelectId from "./SelectId.vue";
@@ -125,13 +126,13 @@ export default {
axios
.get(
"/bayarBaki/" +
localStorage.getItem("id") +
useAuthenticationUserStore().id +
// "/1" ,
"/" +
this.lelongId,
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
}
)
+5 -4
View File
@@ -149,6 +149,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
import ListReceipt from "./ListReceipt.vue";
@@ -166,7 +167,7 @@ export default {
isDisplayFileUpload: false,
componentKey: 0,
formResit: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
lelong_id: this.$route.params.lelongId,
gambarResit: "",
},
@@ -185,13 +186,13 @@ export default {
axios
.get(
"/bayarBaki/" +
localStorage.getItem("id") +
useAuthenticationUserStore().id +
// "/1" ,
"/" +
this.lelongId,
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
}
)
@@ -222,7 +223,7 @@ export default {
axios
.post("/addPhotoResit", resitFormData, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
+3 -2
View File
@@ -104,6 +104,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
@@ -123,9 +124,9 @@ export default {
profile() {
this.loading = true;
axios
.get("/user/profile/" + localStorage.getItem("nokp"), {
.get("/user/profile/" + useAuthenticationUserStore().nokp, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
+3 -2
View File
@@ -59,6 +59,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
export default {
@@ -77,9 +78,9 @@ export default {
liveData() {
this.loading = true;
axios
.get("/history/" + localStorage.getItem("id"), {
.get("/history/" + useAuthenticationUserStore().id, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
+7 -6
View File
@@ -526,6 +526,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import jsPDF from "jspdf";
import "jspdf-autotable";
import html2canvas from "html2canvas";
@@ -560,7 +561,7 @@ export default {
isDisplayFileUpload: false,
fileSize: 0,
formResit: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
lelong_id: this.$route.params.lelongId,
gambarResit: "",
kodcaw: "",
@@ -592,9 +593,9 @@ export default {
this.loading = true;
if(this.lelongId != null) {
axios
.get("/bayar/" + localStorage.getItem("id") + "/" + this.lelongId, {
.get("/bayar/" + useAuthenticationUserStore().id + "/" + this.lelongId, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
@@ -647,7 +648,7 @@ export default {
axios
.post("/addPhotoResit", resitFormData, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
@@ -699,11 +700,11 @@ export default {
axios
.get("/resultInCawangan", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
lelong_id: this.lelongId,
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
kodcaw: value,
},
})
+3 -2
View File
@@ -111,6 +111,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import axios from "axios";
import ResultDetail from "./ResultDetail.vue";
@@ -134,10 +135,10 @@ export default {
axios
.get("/resultLelong", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
params: {
user_id: localStorage.getItem("id"),
user_id: useAuthenticationUserStore().id,
},
})
+11 -10
View File
@@ -258,6 +258,7 @@
</template>
<script>
import { useAuthenticationUserStore } from "@/store/modules/authentication";
import Navbar from "../Navbar.vue";
import Footer from "../Footer.vue";
// import HistoryResult from "./HistoryResult.vue"
@@ -276,10 +277,10 @@ export default {
total_hargabida: "",
loading: false,
formPayment: {
email: localStorage.getItem("email"),
notel: localStorage.getItem("notel"),
name: localStorage.getItem("name"),
user_id: localStorage.getItem("id"),
email: useAuthenticationUserStore().email,
notel: useAuthenticationUserStore().notelbimbit,
name: useAuthenticationUserStore().name,
user_id: useAuthenticationUserStore().id,
lelong_id: localStorage.getItem("lelong_id"),
total: "",
},
@@ -292,9 +293,9 @@ export default {
resultBid() {
this.loading = true;
axios
.get("/result/" + localStorage.getItem("id"), {
.get("/result/" + useAuthenticationUserStore().id, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Authorization: "Bearer " + useAuthenticationUserStore().token,
},
})
.then((response) => {
@@ -310,10 +311,10 @@ export default {
bidPayment() {
axios
.post("/bidpayment", {
email: localStorage.getItem("email"),
notel: localStorage.getItem("notel"),
name: localStorage.getItem("name"),
user_id: localStorage.getItem("id"),
email: useAuthenticationUserStore().email,
notel: useAuthenticationUserStore().notelbimbit,
name: useAuthenticationUserStore().name,
user_id: useAuthenticationUserStore().id,
lelong_id: localStorage.getItem("lelong_id"),
total: this.total_hargabida,
})
+32 -3
View File
@@ -1,6 +1,35 @@
import axios from "axios";
import router from "@/router";
import { useAuthenticationUserStore } from "@/store/modules/authentication";
const tokenKey = "token";
axios.defaults.headers.common['X-CSRF-TOKEN'] = tokenKey;
axios.defaults.baseURL = process.env.VUE_APP_ROOT_URL;
axios.defaults.baseURL = process.env.VUE_APP_ROOT_URL;
axios.interceptors.request.use(
(config) => {
const auth = useAuthenticationUserStore();
if (auth.token) {
config.headers.Authorization = `Bearer ${auth.token}`;
}
return config;
},
(error) => Promise.reject(error)
);
axios.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
const auth = useAuthenticationUserStore();
auth.clearSession();
const currentName = router.currentRoute.value.name;
if (
currentName !== "login" &&
currentName !== "register" &&
currentName !== "forgot-password"
) {
router.push({ name: "login" });
}
}
return Promise.reject(error);
}
);
+5 -1
View File
@@ -57,6 +57,7 @@ import VueViewer from 'v-viewer';
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import { useAuthenticationUserStore } from '@/store/modules/authentication'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
@@ -106,7 +107,10 @@ app.component('MazPhoneNumberInput', MazPhoneNumberInput)
app.component('YouTube', YouTube)
app.use(router).use(pinia).use(PrimeVue).use(VueSweetalert2).use(ToastService).use(VueViewer).mount('#app');
app.use(pinia)
useAuthenticationUserStore().migrateLegacySession()
app.use(router).use(PrimeVue).use(VueSweetalert2).use(ToastService).use(VueViewer).mount('#app');
// app.use(router).use(store).use(PrimeVue).use(ToastService).mount('#app');
// createApp(App).use(router).use(store).mount('#app')
+89 -64
View File
@@ -140,95 +140,100 @@ import {
createWebHistory,
createMemoryHistory,
} from "vue-router";
import { useAuthenticationUserStore } from "@/store/modules/authentication";
// import Register from "../components/Register.vue";
// import IndexPaymentHistory from '../components/result/IndexPaymentHistory.vue'
// import Modals from './../components/Modal.vue'
// import { Modal } from "bootstrap";
const routes = [
{
path: "/",
redirect: (to) => ({ path: "/login", query: to.query }),
},
{
path: "/login",
name: "login",
component: TheLogin,
// meta: { guest: true }
meta: { guest: true },
},
{
path: "/register",
name: "register",
component: TheRegister,
// meta: { guest: true }
},
{
path: "/",
name: "login",
component: TheLogin,
meta: { guest: true },
},
{
path: "/forgot-password",
name: "forgot-password",
component: TheForgotPassword,
},
{
path: "/home",
name: "home",
component: TheHome,
},
{
path: "/cart",
name: "cart",
component: TheCart,
// meta: { requiresAuth: true }
},
{
path: "/list",
name: "list",
component: TheList,
// meta: { requiresAuth: true }
},
{
path: "/profile",
name: "profile",
component: TheProfile,
// meta: { requiresAuth: true }
},
{
path: "/bid-record",
name: "bid-record",
component: TheBidRecord,
// meta: { requiresAuth: true }
},
{
path: "/result",
name: "result",
component: TheResult,
// meta: { requiresAuth: true }
},
{
path: "/result-detail",
name: "detail",
component: ResultDetail,
// meta: { requiresAuth: true }
},
{
path: "/result/detail/receipt",
name: "receipt",
component: ResultReceipt,
// meta: { requiresAuth: true }
},
{
path: "/pay",
name: "pay",
component: ThePay,
},
{
path: "/pay-cdm",
name: "pay-cdm",
component: ThePayCdm,
meta: { guest: true },
},
{
path: "/policy",
name: "policy",
component: ThePolicy,
meta: { guest: true },
},
{
path: "/home",
name: "home",
component: TheHome,
meta: { requiresAuth: true },
},
{
path: "/cart",
name: "cart",
component: TheCart,
meta: { requiresAuth: true },
},
{
path: "/list",
name: "list",
component: TheList,
meta: { requiresAuth: true },
},
{
path: "/profile",
name: "profile",
component: TheProfile,
meta: { requiresAuth: true },
},
{
path: "/bid-record",
name: "bid-record",
component: TheBidRecord,
meta: { requiresAuth: true },
},
{
path: "/result",
name: "result",
component: TheResult,
meta: { requiresAuth: true },
},
{
path: "/result-detail",
name: "detail",
component: ResultDetail,
meta: { requiresAuth: true },
},
{
path: "/result/detail/receipt",
name: "receipt",
component: ResultReceipt,
meta: { requiresAuth: true },
},
{
path: "/pay",
name: "pay",
component: ThePay,
meta: { requiresAuth: true },
},
{
path: "/pay-cdm",
name: "pay-cdm",
component: ThePayCdm,
meta: { requiresAuth: true },
},
];
@@ -239,4 +244,24 @@ const router = createRouter({
routes,
});
router.beforeEach((to, from, next) => {
const auth = useAuthenticationUserStore();
if (to.meta.requiresAuth && !auth.isAuthenticated) {
next({ name: "login", query: { redirect: to.fullPath } });
return;
}
if (
to.meta.guest &&
auth.isAuthenticated &&
(to.name === "login" || to.name === "register")
) {
next({ name: "home" });
return;
}
next();
});
export default router;
+89 -34
View File
@@ -1,39 +1,94 @@
import { defineStore } from 'pinia'
const LEGACY_KEYS = [
'token',
'id',
'nokp',
'name',
'email',
'notelbimbit',
'username',
'notel',
]
export const useAuthenticationUserStore = defineStore('authenticationUser', {
state: () => ({
token: "",
id: "",
nokp: "",
name: "",
email: "",
notelbimbit: "",
username: ""
}),
getters: {
getToken() {
return this.token;
},
getId() {
return this.id;
},
getNokp() {
return this.nokp;
},
getName() {
return this.name;
},
getEmail() {
return this.email;
},
getNoTelBimbit() {
return this.notelbimbit;
},
getUsername() {
return this.username;
},
state: () => ({
token: '',
id: '',
nokp: '',
name: '',
email: '',
notelbimbit: '',
username: '',
}),
getters: {
isAuthenticated: (state) => Boolean(state.token),
getToken() {
return this.token
},
actions: {
getId() {
return this.id
},
persist: true,
})
getNokp() {
return this.nokp
},
getName() {
return this.name
},
getEmail() {
return this.email
},
getNoTelBimbit() {
return this.notelbimbit
},
getUsername() {
return this.username
},
},
actions: {
setSession({ token, user }) {
this.token = token || ''
this.id = user?.id ?? ''
this.nokp = user?.nokp ?? ''
this.name = user?.name ?? ''
this.email = user?.email ?? ''
this.notelbimbit = user?.notelbimbit ?? ''
this.username = user?.username ?? ''
this.clearLegacyKeys()
},
clearSession() {
this.$reset()
this.clearLegacyKeys()
},
clearLegacyKeys() {
LEGACY_KEYS.forEach((key) => localStorage.removeItem(key))
},
migrateLegacySession() {
if (this.token) {
this.clearLegacyKeys()
return
}
const legacyToken = localStorage.getItem('token')
if (!legacyToken) {
return
}
this.setSession({
token: legacyToken,
user: {
id: localStorage.getItem('id') || '',
nokp: localStorage.getItem('nokp') || '',
name: localStorage.getItem('name') || '',
email: localStorage.getItem('email') || '',
notelbimbit:
localStorage.getItem('notelbimbit') ||
localStorage.getItem('notel') ||
'',
username: localStorage.getItem('username') || '',
},
})
},
},
persist: true,
})