From d17b124c4d5614515a2041c3e899f57027821022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=ABl=20van=20de=20Vrie?= Date: Fri, 18 Oct 2024 20:44:54 +0200 Subject: [PATCH 1/5] feat(dashboard/profile) Initial addition of NFC form --- .../src/locales/en/modules/user.json | 1 + .../src/locales/nl/modules/user.json | 1 + .../user/components/UserSettingsComponent.vue | 21 +++++- .../user/components/forms/ChangeNFCForm.vue | 66 +++++++++++++++++++ apps/dashboard/src/utils/validation-schema.ts | 5 ++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue diff --git a/apps/dashboard/src/locales/en/modules/user.json b/apps/dashboard/src/locales/en/modules/user.json index 3d0fcb07..e236ca80 100644 --- a/apps/dashboard/src/locales/en/modules/user.json +++ b/apps/dashboard/src/locales/en/modules/user.json @@ -19,6 +19,7 @@ "header": "User settings", "changePin": "Change PIN", "changePassword": "Change password", + "changeNFC": "Change NFC", "apiKeys": "API keys", "changeApiKey": "Change API key", "deleteApiKey": "Delete API key", diff --git a/apps/dashboard/src/locales/nl/modules/user.json b/apps/dashboard/src/locales/nl/modules/user.json index ab9a339c..d9394736 100644 --- a/apps/dashboard/src/locales/nl/modules/user.json +++ b/apps/dashboard/src/locales/nl/modules/user.json @@ -19,6 +19,7 @@ "header": "Gebruikersinstellingen", "changePin": "PIN wijzigen", "changePassword": "Wachtwoord wijzigen", + "changeNFC": "NFC wijzigen", "apiKeys": "API-sleutels", "changeApiKey": "API-sleutel wijzigen", "deleteApiKey": "API-sleutel verwijderen", diff --git a/apps/dashboard/src/modules/user/components/UserSettingsComponent.vue b/apps/dashboard/src/modules/user/components/UserSettingsComponent.vue index 29e9ee81..740094de 100644 --- a/apps/dashboard/src/modules/user/components/UserSettingsComponent.vue +++ b/apps/dashboard/src/modules/user/components/UserSettingsComponent.vue @@ -23,6 +23,13 @@ @click="showPasswordDialog = true" /> +
+

{{ t('modules.user.settings.changeNFC') }}

+ +

{{ t('modules.user.settings.apiKeys') }}

@@ -59,6 +66,15 @@ + + + @@ -72,10 +88,11 @@ import Divider from "primevue/divider"; import InputSwitch from "primevue/inputswitch"; import ChangePinForm from "@/modules/user/components/forms/ChangePinForm.vue"; import FormDialog from "@/components/FormDialog.vue"; -import { editPasswordSchema, editPinSchema } from "@/utils/validation-schema"; +import { editNFCSchema, editPasswordSchema, editPinSchema } from "@/utils/validation-schema"; import { schemaToForm } from "@/utils/formUtils"; import FormSection from "@/components/FormSection.vue"; import ChangePasswordForm from "@/modules/user/components/forms/ChangePasswordForm.vue"; +import ChangeNFCForm from "@/modules/user/components/forms/ChangeNFCForm.vue"; import { useConfirm } from "primevue/useconfirm"; import { useToast } from "primevue/usetoast"; import apiService from "@/services/ApiService"; @@ -90,8 +107,10 @@ const props = defineProps({ const { t } = useI18n(); const showPasswordDialog = ref(false); +const showNFCDialog = ref(false); const pinForm = schemaToForm(editPinSchema); const passwordForm = schemaToForm(editPasswordSchema); +const nfcForm = schemaToForm(editNFCSchema); const editPin = ref(true); const confirm = useConfirm(); const toast = useToast(); diff --git a/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue b/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue new file mode 100644 index 00000000..cc5ce879 --- /dev/null +++ b/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/apps/dashboard/src/utils/validation-schema.ts b/apps/dashboard/src/utils/validation-schema.ts index 3e36d345..5d1e0e17 100644 --- a/apps/dashboard/src/utils/validation-schema.ts +++ b/apps/dashboard/src/utils/validation-schema.ts @@ -35,6 +35,11 @@ export const editPasswordSchema = passwordConfirm: yup.string().required().oneOf([yup.ref('password')], t('common.validation.password.match')), }); +export const editNFCSchema = + yup.object({ + nfcCode: yup.string().required(), + }); + export const updateInvoiceSettingsObject = yup.object({ reference: yup.string().required(), date: yup.string().required(), From d2c1f846f0b45640aca028636329dfb001f38a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=ABl=20van=20de=20Vrie?= Date: Sat, 19 Oct 2024 18:21:49 +0200 Subject: [PATCH 2/5] fix: added locales added additional locales where they were still missing and improved naming of them. --- apps/dashboard/src/locales/en/common/common.json | 1 + apps/dashboard/src/locales/en/modules/user.json | 3 ++- apps/dashboard/src/locales/nl/common/common.json | 1 + apps/dashboard/src/locales/nl/modules/user.json | 3 ++- .../src/modules/user/components/forms/ChangeNFCForm.vue | 4 ++-- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/dashboard/src/locales/en/common/common.json b/apps/dashboard/src/locales/en/common/common.json index 43f85b46..9b8b5bfd 100644 --- a/apps/dashboard/src/locales/en/common/common.json +++ b/apps/dashboard/src/locales/en/common/common.json @@ -71,6 +71,7 @@ "apiKeyChanged": "Successfully changed API key.", "apiKeyDeleted": "Successfully deleted API key.", "passwordUpdated": "Successfully updated password.", + "nfcCodeUpdated": "Successfully updated NFC code.", "pinUpdated": "Successfully updated PIN.", "finesNotified": "Successfully notified users.", "finesHandedOut": "Successfully handed out fines.", diff --git a/apps/dashboard/src/locales/en/modules/user.json b/apps/dashboard/src/locales/en/modules/user.json index e236ca80..5f2d8fba 100644 --- a/apps/dashboard/src/locales/en/modules/user.json +++ b/apps/dashboard/src/locales/en/modules/user.json @@ -9,6 +9,7 @@ "title": "Profile", "passwordNew": "New password", "passwordConfirm": "Confirm password", + "nfcNew": "New NFC Code", "pinNew": "New PIN", "pinConfirm": "Confirm PIN" }, @@ -19,7 +20,7 @@ "header": "User settings", "changePin": "Change PIN", "changePassword": "Change password", - "changeNFC": "Change NFC", + "changeNFC": "Change NFC code", "apiKeys": "API keys", "changeApiKey": "Change API key", "deleteApiKey": "Delete API key", diff --git a/apps/dashboard/src/locales/nl/common/common.json b/apps/dashboard/src/locales/nl/common/common.json index 3a7874a6..28fc17a4 100644 --- a/apps/dashboard/src/locales/nl/common/common.json +++ b/apps/dashboard/src/locales/nl/common/common.json @@ -71,6 +71,7 @@ "apiKeyChanged": "API-sleutel succesvol gewijzigd.", "apiKeyDeleted": "API-sleutel succesvol verwijderd.", "passwordUpdated": "Wachtwoord succesvol bijgewerkt.", + "nfcCodeUpdated": "NFC code succesvol bijgewerkt.", "pinUpdated": "Pincode succesvol bijgewerkt.", "finesNotified": "Gebruikers succesvol op de hoogte gebracht.", "finesHandedOut": "Boetes succesvol uitgedeeld.", diff --git a/apps/dashboard/src/locales/nl/modules/user.json b/apps/dashboard/src/locales/nl/modules/user.json index d9394736..ecc0a54a 100644 --- a/apps/dashboard/src/locales/nl/modules/user.json +++ b/apps/dashboard/src/locales/nl/modules/user.json @@ -9,6 +9,7 @@ "title": "Profiel", "passwordNew": "Nieuw wachtwoord", "passwordConfirm": "Bevestig wachtwoord", + "nfcNew": "Nieuwe NFC Code", "pinNew": "Nieuwe PIN", "pinConfirm": "Bevestig PIN" }, @@ -19,7 +20,7 @@ "header": "Gebruikersinstellingen", "changePin": "PIN wijzigen", "changePassword": "Wachtwoord wijzigen", - "changeNFC": "NFC wijzigen", + "changeNFC": "NFC code wijzigen", "apiKeys": "API-sleutels", "changeApiKey": "API-sleutel wijzigen", "deleteApiKey": "API-sleutel verwijderen", diff --git a/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue b/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue index cc5ce879..1125029c 100644 --- a/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue +++ b/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue @@ -1,6 +1,6 @@ - - - @@ -88,15 +79,66 @@ import Divider from "primevue/divider"; import InputSwitch from "primevue/inputswitch"; import ChangePinForm from "@/modules/user/components/forms/ChangePinForm.vue"; import FormDialog from "@/components/FormDialog.vue"; -import { editNFCSchema, editPasswordSchema, editPinSchema } from "@/utils/validation-schema"; +import { editPasswordSchema, editPinSchema } from "@/utils/validation-schema"; import { schemaToForm } from "@/utils/formUtils"; import FormSection from "@/components/FormSection.vue"; import ChangePasswordForm from "@/modules/user/components/forms/ChangePasswordForm.vue"; -import ChangeNFCForm from "@/modules/user/components/forms/ChangeNFCForm.vue"; import { useConfirm } from "primevue/useconfirm"; import { useToast } from "primevue/usetoast"; import apiService from "@/services/ApiService"; import { handleError } from "@/utils/errorUtils"; +import { useUserStore } from "@sudosos/sudosos-frontend-common"; + +const status: Ref = ref(""); + +async function startScan() { + try { + if (!('NDEFReader' in window)) { + status.value = "Web NFC is not supported on this device."; + console.log('no'); + toast.add({ + severity: "error", + summary: "Unsupported", + detail: "Browser is not mobile and does not have Web NFC.", + life: 3000, + }); + } else { + const ndef = new (window as any).NDEFReader(); + await ndef.scan(); + toast.add({ + severity: "info", + summary: "Scan started", + detail: "NFC Scan started, please hold your NFC card to your phone!", + life: 3000, + }); + + // Handle the NFC tag when it is detected + ndef.onreading = async (event: NDEFReadingEvent) => { + + // Extract and log the NFC tag's ID (serial number) + const tagId = event.serialNumber; + toast.add({ + severity: "success", + summary: "Scan finished", + detail: "NFC Scan finished, NFC ID added.", + life: 3000, + }); + console.log(tagId); + await apiService.user.updateUserNfc(useUserStore().getCurrentUser.user.id, { nfcCode: tagId }); + }; + } + } catch (error) { + toast.add({ + severity: "error", + summary: "Scan finished", + detail: "NFC Scan finished, NFC ID added.", + life: 3000, + }); + console.error("Error starting NFC reader:", error); + status.value = "Error starting NFC reader"; + } +} + const props = defineProps({ user: { @@ -107,10 +149,8 @@ const props = defineProps({ const { t } = useI18n(); const showPasswordDialog = ref(false); -const showNFCDialog = ref(false); const pinForm = schemaToForm(editPinSchema); const passwordForm = schemaToForm(editPasswordSchema); -const nfcForm = schemaToForm(editNFCSchema); const editPin = ref(true); const confirm = useConfirm(); const toast = useToast(); diff --git a/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue b/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue deleted file mode 100644 index 1125029c..00000000 --- a/apps/dashboard/src/modules/user/components/forms/ChangeNFCForm.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - - - From ee106343d1a136c1efc3030dc5d3e49adcbc1450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=ABl=20van=20de=20Vrie?= Date: Thu, 31 Oct 2024 15:21:43 +0100 Subject: [PATCH 4/5] fix(dashboard/nfc-reader): Addresses remarks in pull request Addresses remarks made in the pull request by @justSamuel --- .../src/locales/en/common/common.json | 9 ++ .../src/locales/nl/common/common.json | 9 ++ .../src/modules/auth/views/AuthLoginView.vue | 1 + .../user/components/UserSettingsComponent.vue | 82 +++++++++--------- apps/dashboard/src/types/web-nfc.d.ts | 83 +++++++++++++++++++ 5 files changed, 141 insertions(+), 43 deletions(-) create mode 100644 apps/dashboard/src/types/web-nfc.d.ts diff --git a/apps/dashboard/src/locales/en/common/common.json b/apps/dashboard/src/locales/en/common/common.json index 9b8b5bfd..93382188 100644 --- a/apps/dashboard/src/locales/en/common/common.json +++ b/apps/dashboard/src/locales/en/common/common.json @@ -61,6 +61,10 @@ "email": "Email address", "usertype": "Usertype", "toast": { + "info": { + "info": "Info", + "scanStarted": "NFC Scan started, please hold your NFC card to your phone!" + }, "success": { "success": "Success", "userUpdated": "Successfully updated user.", @@ -97,6 +101,11 @@ "details": "Payout is verified." } }, + "error": { + "error": "Error", + "scanNotStarted": "NFC scan not started, please check permission regarding NFC.", + "unsupported": "Your browser is not mobile and does not have Web NFC." + }, "canceled": "Canceled", "reject": { "waiveFinesRejected": "Canceled waiving fines." diff --git a/apps/dashboard/src/locales/nl/common/common.json b/apps/dashboard/src/locales/nl/common/common.json index 28fc17a4..b6474685 100644 --- a/apps/dashboard/src/locales/nl/common/common.json +++ b/apps/dashboard/src/locales/nl/common/common.json @@ -61,6 +61,10 @@ "email": "E-mailadres", "usertype": "Gebruikerstype", "toast": { + "info": { + "Info": "Info", + "scanStarted": "NFC Scan gestart, houd je NFC kaart tegen je telefoon!" + }, "success": { "success": "Succes", "userUpdated": "Gebruiker succesvol bijgewerkt.", @@ -97,6 +101,11 @@ "details": "Uitbetaling is geverifieerd." } }, + "error": { + "error": "Error", + "scanNotStarted": "NFC scan niet gestart, kijk of NFC permissies kloppen.", + "unsupported": "Je browser is niet mobiel en heeft geen Web NFC." + }, "canceled": "Geannuleerd", "reject": { "waiveFinesRejected": "Kwijtschelding van boetes geannuleerd." diff --git a/apps/dashboard/src/modules/auth/views/AuthLoginView.vue b/apps/dashboard/src/modules/auth/views/AuthLoginView.vue index 470a80f4..6be46e6f 100644 --- a/apps/dashboard/src/modules/auth/views/AuthLoginView.vue +++ b/apps/dashboard/src/modules/auth/views/AuthLoginView.vue @@ -61,6 +61,7 @@ onBeforeMount(() => { const loginViaGEWIS = () => { window.location.href = `https://gewis.nl/token/${import.meta.env.VITE_APP_GEWIS_TOKEN}`; }; +