@vc-shell/create-vc-app 1.0.88

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +30 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +152 -0
  5. package/dist/template/base/.browserslistrc +3 -0
  6. package/dist/template/base/.commitlintrc.json +3 -0
  7. package/dist/template/base/.editorconfig +22 -0
  8. package/dist/template/base/.env.ejs +5 -0
  9. package/dist/template/base/.eslintignore +3 -0
  10. package/dist/template/base/.eslintrc.js +40 -0
  11. package/dist/template/base/.husky/commit-msg +4 -0
  12. package/dist/template/base/.husky/pre-commit +4 -0
  13. package/dist/template/base/.prettierignore +4 -0
  14. package/dist/template/base/.prettierrc +4 -0
  15. package/dist/template/base/.vscode/extensions.json +16 -0
  16. package/dist/template/base/.vscode/settings.json +13 -0
  17. package/dist/template/base/LICENSE +12 -0
  18. package/dist/template/base/README.md +54 -0
  19. package/dist/template/base/index.html.ejs +26 -0
  20. package/dist/template/base/package.json.ejs +72 -0
  21. package/dist/template/base/postcss.config.js +6 -0
  22. package/dist/template/base/public/assets/1.jpg +0 -0
  23. package/dist/template/base/public/assets/2.jpg +0 -0
  24. package/dist/template/base/public/assets/3.jpg +0 -0
  25. package/dist/template/base/public/assets/4.jpg +0 -0
  26. package/dist/template/base/public/assets/5.jpg +0 -0
  27. package/dist/template/base/public/assets/6.jpg +0 -0
  28. package/dist/template/base/public/assets/7.jpg +0 -0
  29. package/dist/template/base/public/assets/8.jpg +0 -0
  30. package/dist/template/base/public/assets/9.jpg +0 -0
  31. package/dist/template/base/public/assets/app-select.svg +11 -0
  32. package/dist/template/base/public/assets/avatar.jpg +0 -0
  33. package/dist/template/base/public/assets/background.jpg +0 -0
  34. package/dist/template/base/public/assets/empty.png +0 -0
  35. package/dist/template/base/public/assets/logo-white.svg +21 -0
  36. package/dist/template/base/public/assets/logo.svg +8 -0
  37. package/dist/template/base/public/img/icons/apple-touch-icon.png +0 -0
  38. package/dist/template/base/public/img/icons/favicon-16x16.png +0 -0
  39. package/dist/template/base/public/img/icons/favicon-32x32.png +0 -0
  40. package/dist/template/base/public/img/icons/favicon.ico +0 -0
  41. package/dist/template/base/public/img/icons/mstile-150x150.png +0 -0
  42. package/dist/template/base/public/img/icons/pwa-192x192.png +0 -0
  43. package/dist/template/base/public/img/icons/pwa-512x512.png +0 -0
  44. package/dist/template/base/public/img/icons/safari-pinned-tab.svg +37 -0
  45. package/dist/template/base/src/api_client/README.md +28 -0
  46. package/dist/template/base/src/env.d.ts +9 -0
  47. package/dist/template/base/src/locales/en.json +23 -0
  48. package/dist/template/base/src/locales/index.ts +2 -0
  49. package/dist/template/base/src/main.ts.ejs +41 -0
  50. package/dist/template/base/src/pages/App.vue.ejs +373 -0
  51. package/dist/template/base/src/router/index.ts.ejs +134 -0
  52. package/dist/template/base/src/shims-vue.d.ts +24 -0
  53. package/dist/template/base/src/styles/index.scss +3 -0
  54. package/dist/template/base/src/types/index.ts +43 -0
  55. package/dist/template/base/tailwind.config.js +7 -0
  56. package/dist/template/base/tsconfig.json +37 -0
  57. package/dist/template/base/vite.config.ts.ejs +47 -0
  58. package/dist/template/code/blade/src/modules/default/components/index.ts +1 -0
  59. package/dist/template/code/blade/src/modules/default/composables/index.ts +1 -0
  60. package/dist/template/code/blade/src/modules/default/composables/useDefault/index.ts +9 -0
  61. package/dist/template/code/blade/src/modules/default/index.ts +9 -0
  62. package/dist/template/code/blade/src/modules/default/locales/en.json.ejs +40 -0
  63. package/dist/template/code/blade/src/modules/default/locales/index.ts +2 -0
  64. package/dist/template/code/blade/src/modules/default/pages/default-list.vue.ejs +197 -0
  65. package/dist/template/code/blade/src/modules/default/pages/index.ts +1 -0
  66. package/dist/template/code/commonPages/src/composables/index.ts +1 -0
  67. package/dist/template/code/commonPages/src/composables/useLogin/index.ts +16 -0
  68. package/dist/template/code/dashboard/src/pages/Dashboard.vue +38 -0
  69. package/dist/tsconfig.tsbuildinfo +1 -0
  70. package/package.json +34 -0
@@ -0,0 +1,134 @@
1
+ import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
2
+ <% if(commonPages === true || bladeModuleStarter === true) { -%>
3
+ import { inject } from "vue";
4
+ <% } -%>
5
+ import {
6
+ usePermissions,
7
+ useUser,
8
+ BladePageComponent,
9
+ notification,
10
+ useBladeNavigation,
11
+ <% if(commonPages === true) { -%>
12
+ Login,
13
+ ResetPassword,
14
+ Invite,
15
+ <% } -%>} from "@vc-shell/framework";
16
+ import { useCookies } from "@vueuse/integrations/useCookies";
17
+
18
+ /**
19
+ * Pages
20
+ */
21
+ <% if(dashboard === true) { -%>
22
+ import Dashboard from "../pages/Dashboard.vue";
23
+ <% } -%>
24
+ import App from "./../pages/App.vue";
25
+
26
+ // eslint-disable-next-line import/no-unresolved
27
+ import whiteLogoImage from "/assets/logo-white.svg";
28
+ // eslint-disable-next-line import/no-unresolved
29
+ import bgImage from "/assets/background.jpg";
30
+
31
+ const routes: RouteRecordRaw[] = [
32
+ {
33
+ path: "/",
34
+ component: App,
35
+ name: "App",
36
+ meta: {
37
+ root: true,
38
+ },
39
+ children: [
40
+ <% if(dashboard === true) { -%>
41
+ {
42
+ name: "Dashboard",
43
+ path: "",
44
+ alias: "/",
45
+ component: Dashboard,
46
+ },
47
+ <% } -%>
48
+ ],
49
+ },
50
+ <% if(commonPages === true) { -%>
51
+ {
52
+ path: "/login",
53
+ name: "Login",
54
+ component: Login,
55
+ props: () => ({
56
+ logo: whiteLogoImage,
57
+ background: bgImage,
58
+ title: "<%= appName %>",
59
+ }),
60
+ },
61
+ {
62
+ name: "invite",
63
+ path: "/invite",
64
+ component: Invite,
65
+ props: (route) => ({
66
+ userId: route.query.userId,
67
+ token: route.query.token,
68
+ userName: route.query.userName,
69
+ }),
70
+ },
71
+ {
72
+ name: "resetpassword",
73
+ path: "/resetpassword",
74
+ component: ResetPassword,
75
+ props: (route) => ({
76
+ userId: route.query.userId,
77
+ token: route.query.token,
78
+ userName: route.query.userName,
79
+ }),
80
+ },
81
+ <% } -%>
82
+ {
83
+ path: "/:pathMatch(.*)*",
84
+ component: App,
85
+ beforeEnter: (to) => {
86
+ const { resolveUnknownRoutes } = useBladeNavigation();
87
+
88
+ return resolveUnknownRoutes(to);
89
+ },
90
+ },
91
+ ];
92
+
93
+ export const router = createRouter({
94
+ history: createWebHashHistory(import.meta.env.APP_BASE_PATH as string),
95
+ routes,
96
+ });
97
+
98
+ <% if(commonPages === true || bladeModuleStarter === true) { -%>
99
+ router.beforeEach(async (to, from) => {
100
+ const { fetchUserPermissions, checkPermission } = usePermissions();
101
+ const { resolveBlades } = useBladeNavigation();
102
+ const { isAuthenticated } = useUser();
103
+ const pages = inject<BladePageComponent[]>("pages");
104
+ const resolvedBladeUrl = resolveBlades(to);
105
+
106
+ <% if(commonPages === true) { -%>
107
+ if (to.name !== "Login" && to.name !== "ResetPassword" && to.name !== "Invite") {
108
+ try {
109
+ // Fetch permissions if not any
110
+ await fetchUserPermissions();
111
+
112
+ const component = pages.find((blade) => blade?.url === to.path);
113
+
114
+ const hasAccess = checkPermission(component?.permissions);
115
+
116
+ if (!(await isAuthenticated()) && to.name !== "Login") {
117
+ return { name: "Login" };
118
+ } else if (hasAccess && to.name !== "Login") {
119
+ return resolvedBladeUrl ? resolvedBladeUrl : true;
120
+ } else if (!hasAccess) {
121
+ notification.error("Access restricted", {
122
+ timeout: 3000,
123
+ });
124
+ return from.path;
125
+ }
126
+ } catch (e) {
127
+ return { name: "Login" };
128
+ }
129
+ } else return true;
130
+ <% } else {-%>
131
+ return resolvedBladeUrl ? resolvedBladeUrl : true;
132
+ <% } -%>
133
+ });
134
+ <% } -%>
@@ -0,0 +1,24 @@
1
+ /* eslint-disable */
2
+ import { CoreBladeAdditionalSettings } from "@vc-shell/framework";
3
+ import { Ref } from "vue";
4
+
5
+ declare module "*.vue" {
6
+ import type { DefineComponent } from "vue";
7
+ const component: DefineComponent<{}, {}, any>;
8
+ export default component;
9
+ }
10
+
11
+ declare module "@vue/runtime-core" {
12
+ interface ComponentCustomProperties {
13
+ $hasAccess: (permissions: string | string[]) => boolean;
14
+ $isPhone: Ref<boolean>;
15
+ $isTablet: Ref<boolean>;
16
+ $isMobile: Ref<boolean>;
17
+ $isDesktop: Ref<boolean>;
18
+ $isTouch: boolean;
19
+ }
20
+
21
+ interface ComponentOptionsBase extends CoreBladeAdditionalSettings {}
22
+ }
23
+
24
+ export {};
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -0,0 +1,43 @@
1
+ import { ComputedRef } from "vue";
2
+ import { PushNotification } from "@vc-shell/framework";
3
+
4
+ enum UserPermissions {
5
+ SellerUsersManage = "seller:users:manage",
6
+ SellerDetailsEdit = "seller:details:edit",
7
+ SellerProductsSearchFromAllSellers = "seller:products:search_from_all_sellers",
8
+ ManageSellerFulfillmentCenters = "seller:fulfillment_centers:manage",
9
+ ManageSellerReviews = "seller:reviews:manage",
10
+ SellerImportProfilesEdit = "seller:import_profiles:edit",
11
+ }
12
+
13
+ interface IShippingInfo {
14
+ label: string;
15
+ name?: string;
16
+ address?: string;
17
+ phone?: string;
18
+ email?: string;
19
+ }
20
+
21
+ interface INotificationActions {
22
+ name: string | ComputedRef<string>;
23
+ clickHandler(): void;
24
+ outline: boolean;
25
+ variant: "primary" | "secondary" | "special" | "danger" | "widget" | "onlytext" | undefined;
26
+ isVisible?: boolean | ComputedRef<boolean>;
27
+ disabled?: boolean | ComputedRef<boolean>;
28
+ }
29
+
30
+ interface IProductPushNotification extends PushNotification {
31
+ profileName?: string;
32
+ newStatus?: string;
33
+ productId?: string;
34
+ productName?: string;
35
+ }
36
+
37
+ interface INewOrderPushNotification extends PushNotification {
38
+ orderId?: string;
39
+ }
40
+
41
+ export type { IShippingInfo, INotificationActions, IProductPushNotification, INewOrderPushNotification };
42
+
43
+ export { UserPermissions };
@@ -0,0 +1,7 @@
1
+ const defaultConfig = require('@vc-shell/framework/tailwind.config')
2
+
3
+ module.exports = {
4
+ prefix: 'tw-',
5
+ content: ["../../node_modules/@vc-shell/**/*.{vue,js,ts,jsx,tsx}", "./src/**/*.{vue,js,ts,jsx,tsx}"],
6
+ theme: defaultConfig.theme,
7
+ };
@@ -0,0 +1,37 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "declaration": true,
5
+ "declarationMap": true,
6
+ "sourceMap": true,
7
+ "importHelpers": true,
8
+ "resolveJsonModule": true,
9
+ "allowSyntheticDefaultImports": true,
10
+ "skipLibCheck": true,
11
+ "esModuleInterop": true,
12
+ "module": "esnext",
13
+ "moduleResolution": "node",
14
+ "target": "esnext",
15
+ "jsx": "preserve",
16
+ "isolatedModules": true,
17
+ "useDefineForClassFields": true,
18
+ "outDir": "dist",
19
+ "rootDir": "src",
20
+ "strict": false,
21
+ "lib": [
22
+ "esnext",
23
+ "dom"
24
+ ],
25
+ "types": [
26
+ "vite/client",
27
+ ]
28
+ },
29
+ "include": [
30
+ "src/**/*.ts",
31
+ "src/**/*.vue",
32
+ ],
33
+ "exclude": [
34
+ "node_modules",
35
+ "dist"
36
+ ]
37
+ }
@@ -0,0 +1,47 @@
1
+ import { getApplicationConfiguration } from "@vc-shell/config-generator";
2
+ import { VitePWA } from "vite-plugin-pwa";
3
+ import { splitVendorChunkPlugin } from "vite";
4
+
5
+ const mode = process.env.APP_ENV as string;
6
+
7
+ export default getApplicationConfiguration({
8
+ plugins: [
9
+ VitePWA({
10
+ includeAssets: ["favicon.ico", "apple-touch-icon.png"],
11
+ manifest: {
12
+ name: "<%= appName %>",
13
+ theme_color: "#319ED4",
14
+ display: "fullscreen",
15
+ start_url: "/index.html",
16
+ icons: [
17
+ {
18
+ src: "./img/icons/pwa-192x192.png",
19
+ sizes: "192x192",
20
+ type: "image/png",
21
+ },
22
+ {
23
+ src: "./img/icons/pwa-512x512.png",
24
+ sizes: "512x512",
25
+ type: "image/png",
26
+ },
27
+ {
28
+ src: "./img/icons/pwa-192x192.png",
29
+ sizes: "192x192",
30
+ type: "image/png",
31
+ purpose: "maskable",
32
+ },
33
+ {
34
+ src: "./img/icons/pwa-512x512.png",
35
+ sizes: "512x512",
36
+ type: "image/png",
37
+ purpose: "maskable",
38
+ },
39
+ ],
40
+ },
41
+ }),
42
+ splitVendorChunkPlugin(),
43
+ ],
44
+ optimizeDeps: {
45
+ include: mode === "development" ? ["ace-builds", "client-oauth2", "quill-delta", "quill", "url-pattern"] : [],
46
+ },
47
+ });
@@ -0,0 +1 @@
1
+ export { default as useDefault } from "./useDefault";
@@ -0,0 +1,9 @@
1
+ import { ref } from "vue";
2
+
3
+ export default () => {
4
+ const data = ref();
5
+
6
+ return {
7
+ data,
8
+ };
9
+ };
@@ -0,0 +1,9 @@
1
+ import * as pages from "./pages";
2
+ import * as locales from "./locales";
3
+ import { createAppModule } from "@vc-shell/framework";
4
+
5
+ export default createAppModule(pages, locales);
6
+
7
+ export * from "./pages";
8
+ export * from "./composables";
9
+ //export * from "./components";
@@ -0,0 +1,40 @@
1
+ {
2
+ "<%= bladeModuleName.toUpperCase() %>": {
3
+ "MENU": {
4
+ "TITLE": "<%= bladeModuleName %>"
5
+ },
6
+ "PAGES": {
7
+ "LIST": {
8
+ "TITLE": "<%= bladeModuleName %> blade",
9
+ "TOOLBAR": {
10
+ "REFRESH": "Refresh",
11
+ "ADD": "Add",
12
+ "DELETE": "Delete selected"
13
+ },
14
+ "SEARCH": {
15
+ "PLACEHOLDER": "Search keywords"
16
+ },
17
+ "TABLE": {
18
+ "TOTALS": "Count:",
19
+ "HEADER": {
20
+ "PRODUCT_IMAGE": "Pic",
21
+ "PRODUCT_NAME": "Name",
22
+ "CREATED_DATE": "Created"
23
+ },
24
+ "EMPTY": {
25
+ "TITLE": "There are no content yet",
26
+ "ACTION": "Add content"
27
+ },
28
+ "NOT_FOUND": {
29
+ "TITLE": "No content found.",
30
+ "ACTION": "Reset search"
31
+ },
32
+ "ACTIONS": {
33
+ "UNPUBLISH": "Unpublish",
34
+ "PUBLISH": "Publish"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,2 @@
1
+ import * as en from "./en.json";
2
+ export { en };
@@ -0,0 +1,197 @@
1
+ <template>
2
+ <VcBlade
3
+ :title="$t('<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TITLE')"
4
+ width="50%"
5
+ :expanded="expanded"
6
+ :closable="closable"
7
+ :toolbar-items="bladeToolbar"
8
+ @close="$emit('close:blade')"
9
+ @expand="$emit('expand:blade')"
10
+ @collapse="$emit('collapse:blade')"
11
+ >
12
+ <!-- Blade contents -->
13
+ <VcTable
14
+ :expanded="expanded"
15
+ :empty="empty"
16
+ :notfound="notfound"
17
+ class="tw-grow tw-basis-0"
18
+ :multiselect="true"
19
+ :columns="columns"
20
+ :item-action-builder="actionBuilder"
21
+ :sort="sort"
22
+ :search-value="searchValue"
23
+ :search-placeholder="$t('<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.SEARCH.PLACEHOLDER')"
24
+ :total-label="$t('<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.TOTALS')"
25
+ :selected-item-id="selectedItemId"
26
+ state-key="<%= bladeModuleName.toLowerCase() %>"
27
+ @item-click="onItemClick"
28
+ @header-click="onHeaderClick"
29
+ >
30
+ </VcTable>
31
+ </VcBlade>
32
+ </template>
33
+
34
+ <script lang="ts" setup>
35
+ import { computed, inject, reactive, ref, markRaw } from "vue";
36
+ import {
37
+ IBladeEvent,
38
+ IBladeToolbar,
39
+ IParentCallArgs,
40
+ useFunctions,
41
+ IActionBuilderResult,
42
+ ITableColumns,
43
+ } from "@vc-shell/framework";
44
+ import moment from "moment";
45
+ // eslint-disable-next-line import/no-unresolved
46
+ import emptyImage from "/assets/empty.png";
47
+ import { useI18n } from "vue-i18n";
48
+
49
+ export interface Props {
50
+ expanded?: boolean;
51
+ closable?: boolean;
52
+ param?: string;
53
+ options?: Record<string, unknown>;
54
+ }
55
+
56
+ export interface Emits {
57
+ (event: "parent:call", args: IParentCallArgs): void;
58
+ (event: "collapse:blade"): void;
59
+ (event: "expand:blade"): void;
60
+ (event: "open:blade", blade: IBladeEvent);
61
+ (event: "close:blade"): void;
62
+ }
63
+
64
+ defineOptions({
65
+ url: "/<%= bladeModuleName.toLowerCase() %>",
66
+ })
67
+
68
+ const props = withDefaults(defineProps<Props>(), {
69
+ expanded: true,
70
+ closable: true,
71
+ });
72
+
73
+ const emit = defineEmits<Emits>();
74
+
75
+ const { t } = useI18n({ useScope: "global" });
76
+ const { debounce } = useFunctions();
77
+
78
+ const sort = ref("createdDate:DESC");
79
+ const searchValue = ref();
80
+ const selectedItemId = ref<string>();
81
+ const isDesktop = inject("isDesktop");
82
+
83
+ const bladeToolbar = ref<IBladeToolbar[]>([
84
+ {
85
+ id: "refresh",
86
+ title: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TOOLBAR.REFRESH")),
87
+ icon: "fas fa-sync-alt",
88
+ // async clickHandler() {},
89
+ },
90
+ ]);
91
+
92
+ const tableColumns = ref<ITableColumns[]>([
93
+ {
94
+ id: "imgSrc",
95
+ title: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.HEADER.PRODUCT_IMAGE")),
96
+ width: 60,
97
+ alwaysVisible: true,
98
+ type: "image",
99
+ },
100
+ {
101
+ id: "name",
102
+ field: "name",
103
+ title: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.HEADER.PRODUCT_NAME")),
104
+ sortable: true,
105
+ alwaysVisible: true,
106
+ },
107
+ {
108
+ id: "createdDate",
109
+ title: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.HEADER.CREATED_DATE")),
110
+ width: 140,
111
+ sortable: true,
112
+ type: "date-ago",
113
+ },
114
+ ]);
115
+
116
+ const empty = reactive({
117
+ image: emptyImage,
118
+ text: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.EMPTY.TITLE")),
119
+ action: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.EMPTY.ACTION")),
120
+ // clickHandler: () => {},
121
+ });
122
+
123
+ const notfound = reactive({
124
+ image: emptyImage,
125
+ text: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.NOT_FOUND.TITLE")),
126
+ action: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.NOT_FOUND.ACTION")),
127
+ clickHandler: async () => {
128
+ searchValue.value = "";
129
+ },
130
+ });
131
+
132
+ const columns = computed(() => {
133
+ if (props.expanded) {
134
+ return tableColumns.value;
135
+ } else {
136
+ return tableColumns.value.filter((item) => item.alwaysVisible === true);
137
+ }
138
+ });
139
+
140
+ const title = computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TITLE"));
141
+
142
+ const onItemClick = (item: { id: string }) => {
143
+ // openBlade({
144
+ // blade: markRaw(),
145
+ // param: item.id,
146
+ // onOpen() {},
147
+ // onClose() {},
148
+ // });
149
+ };
150
+
151
+ const onHeaderClick = (item: ITableColumns) => {
152
+ const sortOptions = ["DESC", "ASC", ""];
153
+
154
+ if (item.sortable) {
155
+ if (sort.value.split(":")[0] === item.id) {
156
+ const index = sortOptions.findIndex((x) => {
157
+ const sorting = sort.value.split(":")[1];
158
+ if (sorting) {
159
+ return x === sorting;
160
+ } else {
161
+ return x === "";
162
+ }
163
+ });
164
+
165
+ if (index !== -1) {
166
+ const newSort = sortOptions[(index + 1) % sortOptions.length];
167
+
168
+ if (newSort === "") {
169
+ sort.value = `${item.id}`;
170
+ } else {
171
+ sort.value = `${item.id}:${newSort}`;
172
+ }
173
+ }
174
+ } else {
175
+ sort.value = `${item.id}:${sortOptions[0]}`;
176
+ }
177
+ }
178
+ };
179
+
180
+ const actionBuilder = (item: { status: string }): IActionBuilderResult[] => {
181
+ const result = [];
182
+
183
+ result.push({
184
+ icon: "fas fa-trash",
185
+ title: "Delete",
186
+ variant: "danger",
187
+ leftActions: true,
188
+ // clickHandler() {},
189
+ });
190
+
191
+ return result;
192
+ };
193
+
194
+ defineExpose({
195
+ title,
196
+ });
197
+ </script>
@@ -0,0 +1 @@
1
+ export { default as DefaultList } from "./default-list.vue";
@@ -0,0 +1 @@
1
+ export { default as useLogin } from "./useLogin";
@@ -0,0 +1,16 @@
1
+ interface IUseLogin {
2
+ forgotPassword: (args: { loginOrEmail: string }) => void;
3
+ }
4
+
5
+ export default (): IUseLogin => {
6
+ /**
7
+ * @description Forgot password functionality
8
+ */
9
+ async function forgotPassword(args: { loginOrEmail: string }) {
10
+ console.log("Forgot password click");
11
+ }
12
+
13
+ return {
14
+ forgotPassword,
15
+ };
16
+ };
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <VcContainer class="dashboard tw-w-full tw-h-full tw-box-border">
3
+ <div
4
+ v-if="$isDesktop.value"
5
+ class="dashboard-header"
6
+ >
7
+ {{ $t("SHELL.DASHBOARD.TITLE") }}
8
+ </div>
9
+ </VcContainer>
10
+ </template>
11
+
12
+ <script lang="ts" setup>
13
+ import { notification, useErrorHandler } from "@vc-shell/framework";
14
+ import { watch } from "vue";
15
+
16
+ const { error, reset } = useErrorHandler(true);
17
+
18
+ watch(error, (newVal) => {
19
+ if (newVal) {
20
+ notification.error(newVal, {
21
+ timeout: 5000,
22
+ onOpen() {
23
+ reset();
24
+ },
25
+ });
26
+ }
27
+ });
28
+ </script>
29
+
30
+ <style lang="scss">
31
+ .dashboard {
32
+ --card-header-background: transparent;
33
+
34
+ &-header {
35
+ @apply tw-text-[25px] tw-text-[#333333] tw-my-3 tw-px-2;
36
+ }
37
+ }
38
+ </style>