Skip to content

Commit f1ec2c8

Browse files
committed
feat: show modal for deactivated users on POS login
When a deactivated user (active=false) successfully authenticates at the POS keypad, show a modal explaining their account is deactivated and that they cannot make purchases. Clicking "I Understand" logs them out and clears the keypad, preventing entry into the cashier flow. Refs #813
1 parent 166fbb7 commit f1ec2c8

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<template>
2+
<Dialog
3+
class="w-[35rem]"
4+
:closable="false"
5+
:close-on-escape="false"
6+
:dismissable-mask="false"
7+
:draggable="false"
8+
header="Account deactivated"
9+
modal
10+
:visible="show"
11+
>
12+
<Message :closable="false" :icon="undefined" severity="warn">
13+
Your account is <span class="font-bold">deactivated</span>.
14+
<br />
15+
You cannot make purchases at the POS until it is reactivated.
16+
<br /><br />
17+
Please contact the SudoSOS administrators to resolve this.
18+
</Message>
19+
20+
<div class="flex justify-center items-center mt-4">
21+
<Button class="text-xl px-6 py-3 understand-button" @click="emit('dismiss')"> I Understand </Button>
22+
</div>
23+
</Dialog>
24+
</template>
25+
26+
<script setup lang="ts">
27+
defineProps({
28+
show: {
29+
type: Boolean,
30+
required: true,
31+
},
32+
});
33+
34+
const emit = defineEmits(['dismiss']);
35+
</script>
36+
37+
<style scoped lang="scss">
38+
.understand-button {
39+
background-color: var(--p-primary-color);
40+
border-color: var(--p-primary-color);
41+
color: var(--p-primary-inverse-color);
42+
43+
&:hover:not(:disabled) {
44+
background-color: var(--p-primary-hover-color);
45+
border-color: var(--p-primary-hover-color);
46+
}
47+
48+
&:focus-visible {
49+
outline-color: var(--p-primary-color);
50+
}
51+
}
52+
</style>

apps/point-of-sale/src/composables/useLoginForm.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export function useLoginForm() {
1515
const enteringUserId = ref(true);
1616
const loggingIn = ref(false);
1717
const wrongPin = ref(false);
18+
const showDeactivatedModal = ref(false);
1819
const maxUserIdLength = 5;
1920
const maxPasscodeLength = 4;
2021
const maxUserId = 40000;
@@ -44,6 +45,11 @@ export function useLoginForm() {
4445
const user = authStore.getUser;
4546
if (user === null) return;
4647

48+
if (!user.active) {
49+
showDeactivatedModal.value = true;
50+
return;
51+
}
52+
4753
void useCartStore().setBuyer(user);
4854
void userStore.fetchCurrentUserBalance(user.id, apiService);
4955

@@ -53,6 +59,14 @@ export function useLoginForm() {
5359
enteringUserId.value = true;
5460
};
5561

62+
const dismissDeactivatedModal = () => {
63+
authStore.logout();
64+
showDeactivatedModal.value = false;
65+
userId.value = '';
66+
pinCode.value = '';
67+
enteringUserId.value = true;
68+
};
69+
5670
const loginFail = () => {
5771
pinCode.value = '';
5872
wrongPin.value = true;
@@ -112,6 +126,7 @@ export function useLoginForm() {
112126
enteringUserId,
113127
loggingIn,
114128
wrongPin,
129+
showDeactivatedModal,
115130
maxUserIdLength,
116131
maxPasscodeLength,
117132
maxUserId,
@@ -124,6 +139,7 @@ export function useLoginForm() {
124139
loginSuccess,
125140
loginFail,
126141
login,
142+
dismissDeactivatedModal,
127143
shouldShowBanner,
128144
};
129145
}

apps/point-of-sale/src/views/LoginView.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<GitInfo />
3838
</div>
3939
<ScannersLoginComponent :handle-ean-login="eanLogin" :handle-nfc-login="nfcLogin" />
40+
<DeactivatedAccountModalComponent :show="showDeactivatedModal" @dismiss="dismissDeactivatedModal" />
4041
</div>
4142
</template>
4243

@@ -49,6 +50,7 @@ import KeypadDisplayComponent from '@/components/Keypad/KeypadDisplayComponent.v
4950
import { posApiService, userApiService } from '@/services/ApiService';
5051
import BannerComponent from '@/components/Banner/BannerComponent.vue';
5152
import ScannersLoginComponent from '@/components/ScannersLoginComponent.vue';
53+
import DeactivatedAccountModalComponent from '@/components/DeactivatedAccountModalComponent.vue';
5254
import GitInfo from '@/components/GitInfo.vue';
5355
import PosInfo from '@/components/PosInfo.vue';
5456
import { useLoginForm } from '@/composables/useLoginForm';
@@ -65,6 +67,7 @@ const {
6567
enteringUserId,
6668
loggingIn,
6769
wrongPin,
70+
showDeactivatedModal,
6871
maxUserIdLength,
6972
maxPasscodeLength,
7073
maxUserId,
@@ -76,6 +79,7 @@ const {
7679
displayContainerClasses,
7780
loginSuccess,
7881
login,
82+
dismissDeactivatedModal,
7983
shouldShowBanner,
8084
} = useLoginForm();
8185

0 commit comments

Comments
 (0)