@7365admin1/layer-common 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/.editorconfig +12 -0
- package/.github/workflows/main.yml +17 -0
- package/.github/workflows/publish.yml +39 -0
- package/.nuxtrc +1 -0
- package/.playground/app.vue +41 -0
- package/.playground/eslint.config.mjs +6 -0
- package/.playground/nuxt.config.ts +22 -0
- package/.playground/pages/feedback.vue +30 -0
- package/CHANGELOG.md +263 -0
- package/README.md +73 -0
- package/app.vue +3 -0
- package/components/AccessCardAddForm.vue +363 -0
- package/components/AccessManagement.vue +420 -0
- package/components/Avatar/Main.vue +68 -0
- package/components/BillingMain.vue +66 -0
- package/components/BtnUploadFile.vue +139 -0
- package/components/BuildingForm.vue +303 -0
- package/components/BuildingManagement/buildings.vue +335 -0
- package/components/BuildingManagement/units.vue +350 -0
- package/components/BuildingUnitFormAdd.vue +441 -0
- package/components/BuildingUnitFormEdit.vue +429 -0
- package/components/CameraForm.vue +264 -0
- package/components/CameraMain.vue +352 -0
- package/components/Card/DeleteConfirmation.vue +51 -0
- package/components/Card/MemberInfoSummary.vue +44 -0
- package/components/Card/Toggle.vue +25 -0
- package/components/Chat/Bubbles.vue +53 -0
- package/components/Chat/Information.vue +416 -0
- package/components/Chat/ListCard.vue +62 -0
- package/components/Chat/Message.vue +158 -0
- package/components/Chat/Navigation.vue +150 -0
- package/components/ConfirmDialog.vue +66 -0
- package/components/Container/Standard.vue +33 -0
- package/components/DashboardPlaceholder.vue +1524 -0
- package/components/Dialog/DeleteConfirmation.vue +51 -0
- package/components/Dialog/ReplaceAutofillPrompt.vue +49 -0
- package/components/Dialog/UpdateMoreAction.vue +103 -0
- package/components/DocumentForm.vue +187 -0
- package/components/DocumentManagement.vue +376 -0
- package/components/Editor.vue +95 -0
- package/components/EntryPassMain.vue +518 -0
- package/components/Feedback/Form.vue +173 -0
- package/components/FeedbackDetail.vue +599 -0
- package/components/FeedbackMain.vue +588 -0
- package/components/FormDialog.vue +65 -0
- package/components/ImageCarousel.vue +138 -0
- package/components/Input/Date.vue +177 -0
- package/components/Input/DateTimePicker.vue +131 -0
- package/components/Input/File.vue +236 -0
- package/components/Input/FileV2.vue +234 -0
- package/components/Input/InputPhoneNumberV2.vue +164 -0
- package/components/Input/ListGroupSelection.vue +96 -0
- package/components/Input/NRICNumber.vue +53 -0
- package/components/Input/NewDate.vue +123 -0
- package/components/Input/Number.vue +124 -0
- package/components/Input/Password.vue +22 -0
- package/components/Input/PhoneNumber.vue +188 -0
- package/components/Input/VehicleNumber.vue +49 -0
- package/components/InputLabel.vue +22 -0
- package/components/InvitationForm.vue +359 -0
- package/components/InvitationMain.vue +310 -0
- package/components/Layout/Header.vue +129 -0
- package/components/Layout/NavigationDrawer.vue +44 -0
- package/components/ListItem.vue +35 -0
- package/components/ListView.vue +87 -0
- package/components/LocalPagination.vue +31 -0
- package/components/MemberMain.vue +459 -0
- package/components/NFC/NFCPatrolReportMain.vue +591 -0
- package/components/NFC/NFCPatrolRouteForm.vue +596 -0
- package/components/NFC/NFCPatrolRouteMain.vue +539 -0
- package/components/NFC/NFCTagForm.vue +236 -0
- package/components/NFC/NFCTagMain.vue +337 -0
- package/components/NFC/PatrolSettings.vue +130 -0
- package/components/NavigationItem.vue +83 -0
- package/components/NumberSettingField.vue +107 -0
- package/components/OnlineFormConfigurationForm.vue +290 -0
- package/components/OnlineFormsConfiguration.vue +429 -0
- package/components/PeopleForm.vue +452 -0
- package/components/PlaceholderComponent.vue +34 -0
- package/components/RolePermissionFormCreate.vue +161 -0
- package/components/RolePermissionFormPreviewUpdate.vue +183 -0
- package/components/RolePermissionMain.vue +361 -0
- package/components/SearchVehicleNumberUser.vue +91 -0
- package/components/ServiceProviderFormCreate.vue +154 -0
- package/components/ServiceProviderMain.vue +547 -0
- package/components/SignaturePad.vue +73 -0
- package/components/Snackbar.vue +23 -0
- package/components/SpecificAttr.vue +53 -0
- package/components/SupplyManagement.vue +292 -0
- package/components/SwitchContext.vue +108 -0
- package/components/TableList.vue +150 -0
- package/components/TableListSecondary.vue +164 -0
- package/components/TableMain.vue +142 -0
- package/components/TableWithButton.vue +94 -0
- package/components/VehicleUpdateMoreAction.vue +84 -0
- package/components/VideoPlayer.vue +125 -0
- package/components/VisitorForm.vue +659 -0
- package/components/VisitorFormSelection.vue +53 -0
- package/components/VisitorManagement.vue +490 -0
- package/components/WorkOrder/Create.vue +284 -0
- package/components/WorkOrder/Detail.vue +71 -0
- package/components/WorkOrder/ListView.vue +96 -0
- package/components/WorkOrder/Main.vue +489 -0
- package/components/Workorder.vue +1 -0
- package/composables/useAddress.ts +107 -0
- package/composables/useBuilding.ts +250 -0
- package/composables/useBuildingUnit.ts +116 -0
- package/composables/useCard.ts +46 -0
- package/composables/useCommonPermission.ts +207 -0
- package/composables/useCustomer.ts +113 -0
- package/composables/useCustomerSite.ts +56 -0
- package/composables/useDashboard.ts +31 -0
- package/composables/useDashboardData.ts +425 -0
- package/composables/useDocument.ts +57 -0
- package/composables/useFacility.ts +246 -0
- package/composables/useFeedback.ts +119 -0
- package/composables/useFile.ts +55 -0
- package/composables/useInvoice.ts +18 -0
- package/composables/useLocal.ts +131 -0
- package/composables/useLocalAuth.ts +137 -0
- package/composables/useLocalSetup.ts +13 -0
- package/composables/useMember.ts +111 -0
- package/composables/useNFCPatrolRoute.ts +77 -0
- package/composables/useNFCPatrolSettings.ts +19 -0
- package/composables/useNFCPatrolTag.ts +53 -0
- package/composables/useOnlineForm.ts +67 -0
- package/composables/useOrg.ts +129 -0
- package/composables/usePDFDownload.ts +25 -0
- package/composables/usePaymentMethod.ts +101 -0
- package/composables/usePeople.ts +81 -0
- package/composables/usePermission.ts +54 -0
- package/composables/usePhoneCountries.ts +561 -0
- package/composables/usePrice.ts +15 -0
- package/composables/usePromoCode.ts +36 -0
- package/composables/useRecapPermission.ts +26 -0
- package/composables/useRole.ts +104 -0
- package/composables/useSecurityUtils.ts +18 -0
- package/composables/useServiceProvider.ts +224 -0
- package/composables/useSite.ts +109 -0
- package/composables/useSiteEntryPassSettings.ts +46 -0
- package/composables/useSiteSettings.ts +123 -0
- package/composables/useSubscription.ts +150 -0
- package/composables/useUser.ts +132 -0
- package/composables/useUtils.ts +445 -0
- package/composables/useVerification.ts +34 -0
- package/composables/useVisitor.ts +120 -0
- package/composables/useWorkOrder.ts +85 -0
- package/error.vue +41 -0
- package/layouts/plain.vue +7 -0
- package/middleware/01.auth.ts +20 -0
- package/middleware/02.org.ts +21 -0
- package/middleware/03.customer.ts +13 -0
- package/middleware/member.ts +4 -0
- package/nuxt.config.ts +54 -0
- package/package.json +39 -0
- package/pages/index.vue +3 -0
- package/pages/payment-method-linked.vue +31 -0
- package/pages/require-customer.vue +56 -0
- package/pages/require-organization-membership.vue +47 -0
- package/pages/unauthorized.vue +29 -0
- package/plugins/API.ts +21 -0
- package/plugins/iconify.client.ts +5 -0
- package/plugins/secure-member.client.ts +86 -0
- package/plugins/vuetify.ts +62 -0
- package/public/bg-camera.jpg +0 -0
- package/public/bg-city.jpg +0 -0
- package/public/bg-condo.jpg +0 -0
- package/public/images/icons/delete-icon.png +0 -0
- package/public/sprite.svg +1 -0
- package/tsconfig.json +3 -0
- package/types/address.d.ts +13 -0
- package/types/building.d.ts +27 -0
- package/types/camera.d.ts +31 -0
- package/types/card.d.ts +22 -0
- package/types/customer.d.ts +27 -0
- package/types/document.d.ts +6 -0
- package/types/feedback.d.ts +68 -0
- package/types/local.d.ts +74 -0
- package/types/member.d.ts +21 -0
- package/types/online-form.d.ts +15 -0
- package/types/org.d.ts +13 -0
- package/types/people.d.ts +24 -0
- package/types/permission.d.ts +25 -0
- package/types/phone-number.d.ts +10 -0
- package/types/price.d.ts +17 -0
- package/types/promo-code.d.ts +19 -0
- package/types/role.d.ts +11 -0
- package/types/select.d.ts +4 -0
- package/types/service-provider.d.ts +15 -0
- package/types/site.d.ts +20 -0
- package/types/subscription.d.ts +23 -0
- package/types/user.d.ts +19 -0
- package/types/verification.d.ts +20 -0
- package/types/visitor.d.ts +42 -0
- package/types/work-order.d.ts +42 -0
- package/utils/phoneMasks.ts +1703 -0
package/error.vue
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { NuxtError } from "#app";
|
|
3
|
+
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
error: Object as () => NuxtError,
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<v-app>
|
|
11
|
+
<v-main>
|
|
12
|
+
<v-row
|
|
13
|
+
class="fill-height"
|
|
14
|
+
no-gutters
|
|
15
|
+
justify="center"
|
|
16
|
+
align-content="center"
|
|
17
|
+
>
|
|
18
|
+
<v-col cols="9">
|
|
19
|
+
<v-row>
|
|
20
|
+
<v-col cols="12" class="text-center text-h2">
|
|
21
|
+
<span class="font-weight-bold">{{ props.error?.message }}</span>
|
|
22
|
+
</v-col>
|
|
23
|
+
<v-col cols="12">
|
|
24
|
+
<v-row no-gutters justify="center">
|
|
25
|
+
<v-btn
|
|
26
|
+
rounded="xl"
|
|
27
|
+
size="large"
|
|
28
|
+
class="text-none font-weight-bold"
|
|
29
|
+
variant="tonal"
|
|
30
|
+
:to="{ name: 'index' }"
|
|
31
|
+
>
|
|
32
|
+
Go back
|
|
33
|
+
</v-btn>
|
|
34
|
+
</v-row>
|
|
35
|
+
</v-col>
|
|
36
|
+
</v-row>
|
|
37
|
+
</v-col>
|
|
38
|
+
</v-row>
|
|
39
|
+
</v-main>
|
|
40
|
+
</v-app>
|
|
41
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export default defineNuxtRouteMiddleware(async (route) => {
|
|
2
|
+
const { cookieConfig } = useRuntimeConfig().public;
|
|
3
|
+
|
|
4
|
+
// Get access token from cookies
|
|
5
|
+
const sid = useCookie("sid", cookieConfig).value;
|
|
6
|
+
|
|
7
|
+
const serviceProviderEmail = (route.query.email as string) ?? "";
|
|
8
|
+
|
|
9
|
+
console.log(serviceProviderEmail);
|
|
10
|
+
|
|
11
|
+
if (serviceProviderEmail) {
|
|
12
|
+
useCookie("service-provider-email", cookieConfig).value =
|
|
13
|
+
serviceProviderEmail;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (!sid) {
|
|
17
|
+
// Redirect to login page if no access token
|
|
18
|
+
return navigateTo({ name: "index" });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const hexSchema = z
|
|
4
|
+
.string()
|
|
5
|
+
.regex(/^[0-9a-fA-F]{24}$/, "Invalid organization ID");
|
|
6
|
+
|
|
7
|
+
export default defineNuxtRouteMiddleware(async (to, from) => {
|
|
8
|
+
if (import.meta.server) return;
|
|
9
|
+
|
|
10
|
+
const { organization, org } = to.params;
|
|
11
|
+
|
|
12
|
+
// console.log('org-aut-middleware running', hexSchema.safeParse(organization).success)
|
|
13
|
+
|
|
14
|
+
if (!hexSchema.safeParse(organization || org).success) {
|
|
15
|
+
console.log('[02.org] middleware run')
|
|
16
|
+
return navigateTo(
|
|
17
|
+
{ name: "require-organization-membership" },
|
|
18
|
+
{ replace: true }
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const hexSchema = z.string().regex(/^[0-9a-fA-F]{24}$/, "Invalid customer ID");
|
|
4
|
+
|
|
5
|
+
export default defineNuxtRouteMiddleware(async (to, from) => {
|
|
6
|
+
if (import.meta.server) return;
|
|
7
|
+
|
|
8
|
+
const site = to.params.site as string;
|
|
9
|
+
|
|
10
|
+
if (!hexSchema.safeParse(site).success) {
|
|
11
|
+
return navigateTo({ name: "require-customer" }, { replace: true });
|
|
12
|
+
}
|
|
13
|
+
});
|
package/nuxt.config.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// https://nuxt.com/docs/api/configuration/nuxt-config
|
|
2
|
+
import vuetify, { transformAssetUrls } from "vite-plugin-vuetify";
|
|
3
|
+
export default defineNuxtConfig({
|
|
4
|
+
ssr: false,
|
|
5
|
+
devtools: { enabled: true },
|
|
6
|
+
build: {
|
|
7
|
+
transpile: ["vuetify"],
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
runtimeConfig: {
|
|
11
|
+
public: {
|
|
12
|
+
cookieConfig: {
|
|
13
|
+
domain: (process.env.DOMAIN as string) ?? "localhost",
|
|
14
|
+
secure: true,
|
|
15
|
+
maxAge: 30 * 24 * 60 * 60,
|
|
16
|
+
},
|
|
17
|
+
APP: (process.env.APP as string) ?? "App",
|
|
18
|
+
API_DO_STORAGE_ENDPOINT:
|
|
19
|
+
(process.env.API_DO_STORAGE_ENDPOINT as string) ?? "",
|
|
20
|
+
APP_NAME: (process.env.APP_NAME as string) ?? "App",
|
|
21
|
+
APP_NAME_ROUTE: (process.env.APP_NAME_ROUTE as string) ?? "index",
|
|
22
|
+
APP_MAIN: (process.env.APP_MAIN as string) ?? "",
|
|
23
|
+
APP_ACCOUNT: (process.env.APP_ACCOUNT as string) ?? "",
|
|
24
|
+
APP_ADMIN: (process.env.APP_ADMIN as string) ?? "",
|
|
25
|
+
APP_ORG: (process.env.APP_ORG as string) ?? "",
|
|
26
|
+
APP_HYGIENE: (process.env.APP_HYGIENE as string) ?? "",
|
|
27
|
+
APP_SECURITY: (process.env.APP_SECURITY as string) ?? "",
|
|
28
|
+
APP_PROPERTY_MANAGEMENT:
|
|
29
|
+
(process.env.APP_PROPERTY_MANAGEMENT as string) ?? "",
|
|
30
|
+
APP_MECHANICAL_ELECTRICAL:
|
|
31
|
+
(process.env.APP_MECHANICAL_ELECTRICAL as string) ?? "",
|
|
32
|
+
APP_PEST_CONTROL: (process.env.APP_PEST_CONTROL as string) ?? "",
|
|
33
|
+
APP_LANDSCAPING: (process.env.APP_LANDSCAPING as string) ?? "",
|
|
34
|
+
APP_POOL_MAINTENANCE: (process.env.APP_POOL_MAINTENANCE as string) ?? "",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
modules: [
|
|
39
|
+
(_options, nuxt) => {
|
|
40
|
+
nuxt.hooks.hook("vite:extendConfig", (config) => {
|
|
41
|
+
// @ts-expect-error
|
|
42
|
+
config.plugins.push(vuetify({ autoImport: true }));
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
|
|
47
|
+
vite: {
|
|
48
|
+
vue: {
|
|
49
|
+
template: {
|
|
50
|
+
transformAssetUrls,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@7365admin1/layer-common",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"version": "1.8.0",
|
|
6
|
+
"author": "7365admin1",
|
|
7
|
+
"main": "./nuxt.config.ts",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "nuxi dev .playground",
|
|
13
|
+
"dev:prepare": "nuxt prepare .playground",
|
|
14
|
+
"build": "nuxt build .playground",
|
|
15
|
+
"generate": "nuxt generate .playground",
|
|
16
|
+
"preview": "nuxt preview .playground",
|
|
17
|
+
"release": "yarn run build && changeset publish"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@changesets/cli": "^2.27.9",
|
|
21
|
+
"@nuxt/eslint": "latest",
|
|
22
|
+
"eslint": "^9.14.0",
|
|
23
|
+
"nuxt": "^3.13.2",
|
|
24
|
+
"typescript": "^5.8.3",
|
|
25
|
+
"vite-plugin-vuetify": "^2.0.4",
|
|
26
|
+
"vue": "latest",
|
|
27
|
+
"vuetify": "^3.10.4"
|
|
28
|
+
},
|
|
29
|
+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@ckeditor/ckeditor5-vue": "^7.3.0",
|
|
32
|
+
"@iconify/vue": "^5.0.0",
|
|
33
|
+
"@mdi/font": "^7.4.47",
|
|
34
|
+
"ckeditor5": "^47.2.0",
|
|
35
|
+
"sass": "^1.80.6",
|
|
36
|
+
"vue3-signature": "^0.2.4",
|
|
37
|
+
"zod": "^3.24.2"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/pages/index.vue
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" justify="center" align-content="center">
|
|
3
|
+
<v-card class="pa-4" elevation="4" color="success lighten-1">
|
|
4
|
+
<v-card-title class="text-white d-flex align-center">
|
|
5
|
+
<v-icon class="mr-2">mdi-check-circle</v-icon>
|
|
6
|
+
Successfully Linked Payment Method
|
|
7
|
+
</v-card-title>
|
|
8
|
+
|
|
9
|
+
<v-card-actions class="d-flex justify-center">
|
|
10
|
+
<v-btn
|
|
11
|
+
color="white"
|
|
12
|
+
variant="tonal"
|
|
13
|
+
rounded="xl"
|
|
14
|
+
size="large"
|
|
15
|
+
@click="closeWindow"
|
|
16
|
+
>Close</v-btn
|
|
17
|
+
>
|
|
18
|
+
</v-card-actions>
|
|
19
|
+
</v-card>
|
|
20
|
+
</v-row>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script setup>
|
|
24
|
+
definePageMeta({
|
|
25
|
+
layout: "plain",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const closeWindow = () => {
|
|
29
|
+
window.close();
|
|
30
|
+
};
|
|
31
|
+
</script>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" align="center" justify="center">
|
|
3
|
+
<v-col cols="12" lg="6" md="6" sm="6" class="text-center text-subtitle-1">
|
|
4
|
+
You must have a customer to view this page. Please join or contact your
|
|
5
|
+
administrator for access.
|
|
6
|
+
<v-row no-gutters justify="center" align="center" class="mt-2">
|
|
7
|
+
<v-btn
|
|
8
|
+
@click="goToAccount"
|
|
9
|
+
rounded="xl"
|
|
10
|
+
variant="tonal"
|
|
11
|
+
class="text-none text-subtitle-2"
|
|
12
|
+
>
|
|
13
|
+
Go to Organization Page
|
|
14
|
+
</v-btn>
|
|
15
|
+
<span class="mx-2">or</span>
|
|
16
|
+
<v-btn
|
|
17
|
+
@click="createCustomer"
|
|
18
|
+
rounded="xl"
|
|
19
|
+
variant="tonal"
|
|
20
|
+
class="text-none text-subtitle-2"
|
|
21
|
+
>
|
|
22
|
+
Create an Customer
|
|
23
|
+
</v-btn>
|
|
24
|
+
</v-row>
|
|
25
|
+
</v-col>
|
|
26
|
+
</v-row>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup lang="ts">
|
|
30
|
+
definePageMeta({
|
|
31
|
+
layout: "plain",
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const { APP_NAME, APP_ORG } = useRuntimeConfig().public;
|
|
35
|
+
|
|
36
|
+
function goToAccount() {
|
|
37
|
+
window.location.href = `${APP_ORG}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { authenticate } = useLocalAuth();
|
|
41
|
+
|
|
42
|
+
authenticate();
|
|
43
|
+
|
|
44
|
+
const { currentUser } = useLocalAuth();
|
|
45
|
+
|
|
46
|
+
function createCustomer() {
|
|
47
|
+
if (APP_NAME.toLowerCase() === "org") {
|
|
48
|
+
navigateTo({
|
|
49
|
+
name: "org-organizations-customers-add",
|
|
50
|
+
params: { organization: currentUser.value?.defaultOrg },
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
window.location.href = `${APP_ORG}/org/${currentUser.value?.defaultOrg}/customers/add`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" align="center" justify="center">
|
|
3
|
+
<v-col cols="12" lg="6" md="6" sm="6" class="text-center text-subtitle-1">
|
|
4
|
+
You must be a member of an organization to view this page. Please join or
|
|
5
|
+
contact your administrator for access.
|
|
6
|
+
<v-row no-gutters justify="center" align="center" class="mt-2">
|
|
7
|
+
<v-btn
|
|
8
|
+
@click="goToAccount"
|
|
9
|
+
rounded="xl"
|
|
10
|
+
variant="tonal"
|
|
11
|
+
class="text-none text-subtitle-2"
|
|
12
|
+
>
|
|
13
|
+
Go to Account Page
|
|
14
|
+
</v-btn>
|
|
15
|
+
<span class="mx-2">or</span>
|
|
16
|
+
<v-btn
|
|
17
|
+
@click="createOrg"
|
|
18
|
+
rounded="xl"
|
|
19
|
+
variant="tonal"
|
|
20
|
+
class="text-none text-subtitle-2"
|
|
21
|
+
>
|
|
22
|
+
Create an Organization
|
|
23
|
+
</v-btn>
|
|
24
|
+
</v-row>
|
|
25
|
+
</v-col>
|
|
26
|
+
</v-row>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup lang="ts">
|
|
30
|
+
definePageMeta({
|
|
31
|
+
layout: "plain",
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const { APP_ACCOUNT, APP_NAME, APP_ORG } = useRuntimeConfig().public;
|
|
35
|
+
|
|
36
|
+
function goToAccount() {
|
|
37
|
+
window.location.href = `${APP_ACCOUNT}/home`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function createOrg() {
|
|
41
|
+
if (APP_NAME.toLowerCase() === "org") {
|
|
42
|
+
navigateTo({ name: "organizations-create" });
|
|
43
|
+
} else {
|
|
44
|
+
window.location.href = `${APP_ORG}/organizations/create`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" align="center" justify="center">
|
|
3
|
+
<v-col cols="12" lg="6" md="6" sm="6" class="text-center text-subtitle-1">
|
|
4
|
+
You must be a member of an organization to view this page. Please join or
|
|
5
|
+
contact your administrator for access.
|
|
6
|
+
<v-row no-gutters justify="center" class="mt-2">
|
|
7
|
+
<v-btn
|
|
8
|
+
@click="goToAccount"
|
|
9
|
+
rounded="xl"
|
|
10
|
+
variant="tonal"
|
|
11
|
+
class="text-none text-subtitle-2"
|
|
12
|
+
>
|
|
13
|
+
Go to Account Page
|
|
14
|
+
</v-btn>
|
|
15
|
+
</v-row>
|
|
16
|
+
</v-col>
|
|
17
|
+
</v-row>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
definePageMeta({
|
|
22
|
+
layout: "plain",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
function goToAccount() {
|
|
26
|
+
const { APP_ACCOUNT } = useRuntimeConfig().public;
|
|
27
|
+
window.location.href = `${APP_ACCOUNT}/home`;
|
|
28
|
+
}
|
|
29
|
+
</script>
|
package/plugins/API.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default defineNuxtPlugin(() => {
|
|
2
|
+
const { cookieConfig } = useRuntimeConfig().public;
|
|
3
|
+
|
|
4
|
+
const api = $fetch.create({
|
|
5
|
+
baseURL: "/",
|
|
6
|
+
retry: 1,
|
|
7
|
+
retryStatusCodes: [401],
|
|
8
|
+
retryDelay: 500,
|
|
9
|
+
onRequest({ options }) {
|
|
10
|
+
const sid = useCookie("sid", cookieConfig).value ?? "";
|
|
11
|
+
options.headers.set("Authorization", sid);
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Expose to useNuxtApp().$api
|
|
16
|
+
return {
|
|
17
|
+
provide: {
|
|
18
|
+
api,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const hexSchema = z
|
|
4
|
+
.string()
|
|
5
|
+
.regex(/^[0-9a-fA-F]{24}$/, "Invalid organization ID");
|
|
6
|
+
|
|
7
|
+
export default defineNuxtPlugin(() => {
|
|
8
|
+
const router = useRouter();
|
|
9
|
+
const { getByUserType } = useMember();
|
|
10
|
+
const { getRoleById } = useRole();
|
|
11
|
+
const { getById } = useOrg();
|
|
12
|
+
|
|
13
|
+
const { userAppRole, id, orgNature } = useLocalSetup();
|
|
14
|
+
|
|
15
|
+
router.afterEach(async (to) => {
|
|
16
|
+
const isMember = to.meta?.memberOnly;
|
|
17
|
+
|
|
18
|
+
if (!isMember) return;
|
|
19
|
+
|
|
20
|
+
const APP = useRuntimeConfig().public.APP;
|
|
21
|
+
const org = computed(
|
|
22
|
+
() =>
|
|
23
|
+
(to.params.org as string) || (to.params.organization as string) || ""
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
console.log('[secure-member-plugin', 'org', org.value)
|
|
27
|
+
|
|
28
|
+
if (!hexSchema.safeParse(org.value).success) {
|
|
29
|
+
return router.replace({ name: "require-organization-membership" });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const userId = computed(() => useCookie("user").value ?? "");
|
|
33
|
+
|
|
34
|
+
const { data: userMemberData, error: userMemberError } =
|
|
35
|
+
await useLazyAsyncData(
|
|
36
|
+
"plugin-get-member-by-id-" + userId.value + "-" + APP + "-" + org.value,
|
|
37
|
+
() => getByUserType(userId.value, APP, org.value),
|
|
38
|
+
{ watch: [userId] }
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
watchEffect(() => {
|
|
42
|
+
if (userMemberError.value) {
|
|
43
|
+
console.log('running-secure-member-redirect-plugin')
|
|
44
|
+
navigateTo(
|
|
45
|
+
{
|
|
46
|
+
name: "index",
|
|
47
|
+
},
|
|
48
|
+
{ replace: true }
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const roleId = ref("roleId");
|
|
54
|
+
|
|
55
|
+
watchEffect(() => {
|
|
56
|
+
if (userMemberData.value) {
|
|
57
|
+
id.value = userMemberData.value.org ?? "";
|
|
58
|
+
roleId.value = userMemberData.value.role ?? "roleId";
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const { data: getOrgByIdReq } = await useLazyAsyncData(
|
|
63
|
+
"plugin-get-org-by-id-" + org.value,
|
|
64
|
+
() => getById(org.value),
|
|
65
|
+
{ watch: [org] }
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
watchEffect(() => {
|
|
69
|
+
if (getOrgByIdReq.value) {
|
|
70
|
+
orgNature.value = getOrgByIdReq.value.nature ?? "";
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const { data: getRoleByIdReq } = await useLazyAsyncData(
|
|
75
|
+
"plugin-get-role-by-id-" + roleId.value,
|
|
76
|
+
() => getRoleById(roleId.value),
|
|
77
|
+
{ watch: [roleId] }
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
watchEffect(() => {
|
|
81
|
+
if (getRoleByIdReq.value) {
|
|
82
|
+
userAppRole.value = getRoleByIdReq.value;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// import this after install `@mdi/font` package
|
|
2
|
+
import "@mdi/font/css/materialdesignicons.css";
|
|
3
|
+
import { VFileUpload, VFileUploadItem } from 'vuetify/labs/VFileUpload'
|
|
4
|
+
import { VMaskInput } from 'vuetify/labs/VMaskInput'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import "vuetify/styles";
|
|
8
|
+
import { createVuetify } from "vuetify";
|
|
9
|
+
import { Icon } from "@iconify/vue";
|
|
10
|
+
|
|
11
|
+
export default defineNuxtPlugin((app) => {
|
|
12
|
+
const vuetify = createVuetify({
|
|
13
|
+
defaults: {
|
|
14
|
+
VTextField: {
|
|
15
|
+
variant: "outlined",
|
|
16
|
+
density: "comfortable",
|
|
17
|
+
},
|
|
18
|
+
VAutocomplete: {
|
|
19
|
+
variant: "outlined",
|
|
20
|
+
density: "comfortable",
|
|
21
|
+
menuProps: { attach: document.body, zIndex: 3000, }
|
|
22
|
+
},
|
|
23
|
+
VSelect: {
|
|
24
|
+
variant: "outlined",
|
|
25
|
+
density: "comfortable",
|
|
26
|
+
menuProps: { attach: document.body, zIndex: 3000}
|
|
27
|
+
},
|
|
28
|
+
VTextarea: {
|
|
29
|
+
variant: "outlined",
|
|
30
|
+
density: "comfortable",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
theme: {
|
|
34
|
+
defaultTheme: "iservice365",
|
|
35
|
+
themes: {
|
|
36
|
+
iservice365: {
|
|
37
|
+
dark: false,
|
|
38
|
+
colors: {
|
|
39
|
+
primary: "#042134",
|
|
40
|
+
"primary-button": "#1867C0",
|
|
41
|
+
"text-primary": "#052439",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
icons: {
|
|
47
|
+
defaultSet: "iconify",
|
|
48
|
+
sets: {
|
|
49
|
+
iconify: {
|
|
50
|
+
component: (props: any) => h(Icon, { icon: props.icon }),
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
components: {
|
|
55
|
+
VFileUpload,
|
|
56
|
+
VFileUploadItem,
|
|
57
|
+
VMaskInput
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
app.vueApp.use(vuetify);
|
|
62
|
+
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|