erp-blocks 1.0.1

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 (42) hide show
  1. package/README.md +94 -0
  2. package/dist/module.d.mts +5 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +38 -0
  5. package/dist/runtime/app.d.vue.ts +3 -0
  6. package/dist/runtime/app.vue +7 -0
  7. package/dist/runtime/app.vue.d.ts +3 -0
  8. package/dist/runtime/components/CollapsibleSidebar.d.vue.ts +3 -0
  9. package/dist/runtime/components/CollapsibleSidebar.vue +31 -0
  10. package/dist/runtime/components/CollapsibleSidebar.vue.d.ts +3 -0
  11. package/dist/runtime/components/ColorModeButton.d.vue.ts +3 -0
  12. package/dist/runtime/components/ColorModeButton.vue +28 -0
  13. package/dist/runtime/components/ColorModeButton.vue.d.ts +3 -0
  14. package/dist/runtime/components/ConfirmationModal.d.vue.ts +24 -0
  15. package/dist/runtime/components/ConfirmationModal.vue +58 -0
  16. package/dist/runtime/components/ConfirmationModal.vue.d.ts +24 -0
  17. package/dist/runtime/components/DataTable.d.vue.ts +25 -0
  18. package/dist/runtime/components/DataTable.vue +32 -0
  19. package/dist/runtime/components/DataTable.vue.d.ts +25 -0
  20. package/dist/runtime/components/FiltersModal.d.vue.ts +27 -0
  21. package/dist/runtime/components/FiltersModal.vue +48 -0
  22. package/dist/runtime/components/FiltersModal.vue.d.ts +27 -0
  23. package/dist/runtime/components/MainMenu.d.vue.ts +3 -0
  24. package/dist/runtime/components/MainMenu.vue +13 -0
  25. package/dist/runtime/components/MainMenu.vue.d.ts +3 -0
  26. package/dist/runtime/components/NavigationHeader.d.vue.ts +3 -0
  27. package/dist/runtime/components/NavigationHeader.vue +27 -0
  28. package/dist/runtime/components/NavigationHeader.vue.d.ts +3 -0
  29. package/dist/runtime/components/NewSlider.d.vue.ts +22 -0
  30. package/dist/runtime/components/NewSlider.vue +22 -0
  31. package/dist/runtime/components/NewSlider.vue.d.ts +22 -0
  32. package/dist/runtime/components/SidebarTrigger.d.vue.ts +3 -0
  33. package/dist/runtime/components/SidebarTrigger.vue +18 -0
  34. package/dist/runtime/components/SidebarTrigger.vue.d.ts +3 -0
  35. package/dist/runtime/composables/useCountFetch.d.ts +11 -0
  36. package/dist/runtime/composables/useCountFetch.js +40 -0
  37. package/dist/runtime/index.d.ts +15 -0
  38. package/dist/runtime/layouts/dashboard-layout.d.vue.ts +13 -0
  39. package/dist/runtime/layouts/dashboard-layout.vue +15 -0
  40. package/dist/runtime/layouts/dashboard-layout.vue.d.ts +13 -0
  41. package/dist/types.d.mts +7 -0
  42. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # ERP Blocks for Nuxt 4
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![License][license-src]][license-href]
6
+ [![Nuxt][nuxt-src]][nuxt-href]
7
+
8
+ A collection of ready-to-use UI layouts and components designed as ERP system elements for Nuxt 4 applications.
9
+
10
+ ## Features
11
+
12
+ - 🏗️ **Dashboard Layout** - Responsive dashboard layout with collapsible sidebar
13
+ - 🔄 **Data Fetching** - Enhanced `useCountFetch` composable for handling paginated data
14
+ - 🎨 **Pre-styled Components** - Common ERP components with consistent styling
15
+ - 🧩 **Modular Design** - Easy to customize and extend for your needs
16
+ - 🚀 **Nuxt 4 Ready** - Built with Nuxt 4 and Vue 3 Composition API
17
+
18
+ ## Installation
19
+
20
+ 1. Add `erp-blocks` dependency to your project:
21
+
22
+ ```bash
23
+ npm install erp-blocks
24
+ # or
25
+ yarn add erp-blocks
26
+ # or
27
+ pnpm add erp-blocks
28
+ ```
29
+
30
+ 2. Add `erp-blocks` to the `modules` section of `nuxt.config.ts`:
31
+
32
+ ```ts
33
+ export default defineNuxtConfig({
34
+ modules: ['erp-blocks']
35
+ })
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ ### Dashboard Layout
41
+
42
+ Use the provided dashboard layout in your pages:
43
+
44
+ ```vue
45
+ <template>
46
+ <div>
47
+ <!-- Your page content -->
48
+ </div>
49
+ </template>
50
+
51
+ <script setup>
52
+ definePageMeta({
53
+ layout: 'dashboard'
54
+ })
55
+ </script>
56
+ ```
57
+
58
+ ### useCountFetch Composable
59
+
60
+ The `useCountFetch` composable extends Nuxt's `useFetch` with count tracking capabilities, useful for paginated data:
61
+
62
+ ```ts
63
+ const { data, pending, error, count } = useCountFetch('/api/items', {
64
+ count: {
65
+ source: 'header', // or 'key' for JSON response
66
+ name: 'X-Total-Count' // header name or object key
67
+ },
68
+ // Standard useFetch options
69
+ query: {
70
+ page: 1,
71
+ limit: 10
72
+ }
73
+ })
74
+ ```
75
+
76
+ ### Available Components
77
+
78
+ - `CollapsibleSidebar` - A responsive, collapsible sidebar component
79
+ - `NavigationHeader` - Top navigation bar component
80
+
81
+ </details>
82
+
83
+ <!-- Badges -->
84
+ [npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=020420&colorB=00DC82
85
+ [npm-version-href]: https://npmjs.com/package/my-module
86
+
87
+ [npm-downloads-src]: https://img.shields.io/npm/dm/my-module.svg?style=flat&colorA=020420&colorB=00DC82
88
+ [npm-downloads-href]: https://npm.chart.dev/my-module
89
+
90
+ [license-src]: https://img.shields.io/npm/l/my-module.svg?style=flat&colorA=020420&colorB=00DC82
91
+ [license-href]: https://npmjs.com/package/my-module
92
+
93
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
94
+ [nuxt-href]: https://nuxt.com
@@ -0,0 +1,5 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ declare const _default: _nuxt_schema.NuxtModule<_nuxt_schema.ModuleOptions, _nuxt_schema.ModuleOptions, false>;
4
+
5
+ export { _default as default };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "erp-blocks",
3
+ "configKey": "erp",
4
+ "version": "1.0.1",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "3.6.1"
8
+ }
9
+ }
@@ -0,0 +1,38 @@
1
+ import { defineNuxtModule, createResolver, addTemplate, addComponentsDir, addLayout, addImports } from '@nuxt/kit';
2
+
3
+ const module$1 = defineNuxtModule({
4
+ meta: {
5
+ name: "erp-blocks",
6
+ configKey: "erp"
7
+ },
8
+ defaults: {},
9
+ setup(_options, nuxt) {
10
+ const { resolve } = createResolver(import.meta.url);
11
+ nuxt.options.css.push(resolve("./assets/css/main.css"));
12
+ nuxt.options.build.transpile.push(resolve("./runtime"));
13
+ addTemplate({
14
+ filename: "app.vue",
15
+ src: resolve("./runtime/app.vue")
16
+ });
17
+ addTemplate({
18
+ filename: "index.d.ts",
19
+ src: resolve("./runtime/index.d.ts")
20
+ });
21
+ addComponentsDir({
22
+ path: resolve("./runtime/components")
23
+ });
24
+ addLayout({
25
+ src: resolve("./runtime/layouts/dashboard-layout.vue")
26
+ }, "dashboard");
27
+ addImports([
28
+ { name: "useCountFetch", from: resolve("./runtime/composables/useCountFetch.ts") }
29
+ ]);
30
+ },
31
+ moduleDependencies: {
32
+ "@nuxt/ui": {
33
+ version: ">=4.0.0"
34
+ }
35
+ }
36
+ });
37
+
38
+ export { module$1 as default };
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <UApp>
3
+ <NuxtLayout>
4
+ <NuxtPage />
5
+ </NuxtLayout>
6
+ </UApp>
7
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <!-- TODO: Change UCollapsible to UDrawer in mobile -->
3
+ <UCollapsible
4
+ v-model:open="sidebarOpen"
5
+ :ui="{
6
+ content: 'max-lg:fixed z-40 max-lg:bg-white left-0 top-0 data-[state=open]:animate-collapsible-right data-[state=closed]:animate-collapsible-left border-r border-scn-sidebar-border dark:border-default'
7
+ }"
8
+ >
9
+ <template #content>
10
+ <div class="relative h-screen w-3xs bg-scn-sidebar">
11
+ <UIcon
12
+ name="i-lucide-x"
13
+ class="size-5 absolute z-50 top-4 right-4 cursor-pointer lg:hidden"
14
+ @click="closeSidebar"
15
+ />
16
+ <MainMenu />
17
+ </div>
18
+ </template>
19
+ </UCollapsible>
20
+ </template>
21
+
22
+ <script setup>
23
+ import { useCookie } from "#app";
24
+ import MainMenu from "./MainMenu.vue";
25
+ const sidebarOpen = useCookie("sidebarOpen", {
26
+ default: () => true
27
+ });
28
+ function closeSidebar() {
29
+ sidebarOpen.value = false;
30
+ }
31
+ </script>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,28 @@
1
+ <script setup>
2
+ import { useColorMode } from "#imports";
3
+ import { computed } from "vue";
4
+ const colorMode = useColorMode();
5
+ const isDark = computed({
6
+ get() {
7
+ return colorMode.value === "dark";
8
+ },
9
+ set(_isDark) {
10
+ colorMode.preference = _isDark ? "dark" : "light";
11
+ }
12
+ });
13
+ </script>
14
+
15
+ <template>
16
+ <ClientOnly v-if="!colorMode?.forced">
17
+ <UButton
18
+ :icon="isDark ? 'i-lucide-moon' : 'i-lucide-sun'"
19
+ color="neutral"
20
+ variant="ghost"
21
+ @click="isDark = !isDark"
22
+ />
23
+
24
+ <template #fallback>
25
+ <div class="size-8" />
26
+ </template>
27
+ </ClientOnly>
28
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,24 @@
1
+ import type { ModalProps, ButtonProps } from '@nuxt/ui';
2
+ type __VLS_Props = {
3
+ modalProps?: ModalProps;
4
+ buttonProps?: ButtonProps;
5
+ confirmAction?: () => void;
6
+ };
7
+ declare var __VLS_13: {}, __VLS_21: {};
8
+ type __VLS_Slots = {} & {
9
+ body?: (props: typeof __VLS_13) => any;
10
+ } & {
11
+ footer?: (props: typeof __VLS_21) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
14
+ modalProps: ModalProps;
15
+ buttonProps: ButtonProps;
16
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
20
+ type __VLS_WithSlots<T, S> = T & {
21
+ new (): {
22
+ $slots: S;
23
+ };
24
+ };
@@ -0,0 +1,58 @@
1
+ <template>
2
+ <UModal v-bind="modalProps">
3
+ <UButton
4
+ v-bind="buttonProps"
5
+ />
6
+
7
+ <template #body>
8
+ <slot name="body">
9
+ <div class="flex flex-col items-center text-center gap-2">
10
+ <UIcon
11
+ name="i-lucide:help-circle"
12
+ class="text-3xl text-neutral-500"
13
+ />
14
+ <p class="text-base sm:text-lg">
15
+ Are you sure you want to perform this action?
16
+ </p>
17
+ </div>
18
+ </slot>
19
+ </template>
20
+
21
+ <template #footer="{ close }">
22
+ <slot
23
+ name="footer"
24
+ >
25
+ <UButton
26
+ label="Cancel"
27
+ color="neutral"
28
+ variant="outline"
29
+ @click="close"
30
+ />
31
+ <UButton
32
+ type="submit"
33
+ label="Accept"
34
+ color="neutral"
35
+ @click="confirmAction"
36
+ />
37
+ </slot>
38
+ </template>
39
+ </UModal>
40
+ </template>
41
+
42
+ <script setup>
43
+ defineProps({
44
+ modalProps: { type: Object, required: false, default: () => ({
45
+ ui: {
46
+ body: "p-4 sm:p-6 text-center",
47
+ footer: "justify-end gap-2"
48
+ }
49
+ }) },
50
+ buttonProps: { type: Object, required: false, default: () => ({
51
+ icon: "i-lucide:check",
52
+ color: "neutral",
53
+ variant: "solid",
54
+ class: "cursor-pointer"
55
+ }) },
56
+ confirmAction: { type: Function, required: false }
57
+ });
58
+ </script>
@@ -0,0 +1,24 @@
1
+ import type { ModalProps, ButtonProps } from '@nuxt/ui';
2
+ type __VLS_Props = {
3
+ modalProps?: ModalProps;
4
+ buttonProps?: ButtonProps;
5
+ confirmAction?: () => void;
6
+ };
7
+ declare var __VLS_13: {}, __VLS_21: {};
8
+ type __VLS_Slots = {} & {
9
+ body?: (props: typeof __VLS_13) => any;
10
+ } & {
11
+ footer?: (props: typeof __VLS_21) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
14
+ modalProps: ModalProps;
15
+ buttonProps: ButtonProps;
16
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
20
+ type __VLS_WithSlots<T, S> = T & {
21
+ new (): {
22
+ $slots: S;
23
+ };
24
+ };
@@ -0,0 +1,25 @@
1
+ import type { TableColumn } from '@nuxt/ui';
2
+ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ props: __VLS_PrettifyLocal<({
4
+ data: T[] | undefined;
5
+ columns: TableColumn<T>[];
6
+ loading?: boolean;
7
+ totalRows?: number;
8
+ itemsPerPage?: number;
9
+ } & {
10
+ page?: number;
11
+ }) & {
12
+ "onUpdate:page"?: ((value: number | undefined) => any) | undefined;
13
+ }> & import("vue").PublicProps;
14
+ expose: (exposed: {}) => void;
15
+ attrs: any;
16
+ slots: {};
17
+ emit: (evt: "update:page", value: number | undefined) => void;
18
+ }>) => import("vue").VNode & {
19
+ __ctx?: Awaited<typeof __VLS_setup>;
20
+ };
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
23
+ type __VLS_PrettifyLocal<T> = {
24
+ [K in keyof T as K]: T[K];
25
+ } & {};
@@ -0,0 +1,32 @@
1
+ <script setup>
2
+ defineProps({
3
+ data: { type: null, required: true },
4
+ columns: { type: Array, required: true },
5
+ loading: { type: Boolean, required: false },
6
+ totalRows: { type: Number, required: false },
7
+ itemsPerPage: { type: Number, required: false, default: 5 }
8
+ });
9
+ const page = defineModel("page", { type: Number });
10
+ </script>
11
+
12
+ <template>
13
+ <div class="flex flex-col size-full space-y-4 py-4">
14
+ <UTable
15
+ :loading="loading"
16
+ :data="data"
17
+ :columns="columns"
18
+ class="flex-1 border border-default rounded-lg grow"
19
+ />
20
+ <div class="flex items-center justify-between">
21
+ <span class="text-base text-dimmed">
22
+ {{ data?.length ?? 0 }} of {{ totalRows ?? 0 }} rows
23
+ </span>
24
+ <UPagination
25
+ v-model:page="page"
26
+ active-color="neutral"
27
+ :total="totalRows"
28
+ :items-per-page="itemsPerPage"
29
+ />
30
+ </div>
31
+ </div>
32
+ </template>
@@ -0,0 +1,25 @@
1
+ import type { TableColumn } from '@nuxt/ui';
2
+ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
+ props: __VLS_PrettifyLocal<({
4
+ data: T[] | undefined;
5
+ columns: TableColumn<T>[];
6
+ loading?: boolean;
7
+ totalRows?: number;
8
+ itemsPerPage?: number;
9
+ } & {
10
+ page?: number;
11
+ }) & {
12
+ "onUpdate:page"?: ((value: number | undefined) => any) | undefined;
13
+ }> & import("vue").PublicProps;
14
+ expose: (exposed: {}) => void;
15
+ attrs: any;
16
+ slots: {};
17
+ emit: (evt: "update:page", value: number | undefined) => void;
18
+ }>) => import("vue").VNode & {
19
+ __ctx?: Awaited<typeof __VLS_setup>;
20
+ };
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
23
+ type __VLS_PrettifyLocal<T> = {
24
+ [K in keyof T as K]: T[K];
25
+ } & {};
@@ -0,0 +1,27 @@
1
+ import type { ModalProps } from '@nuxt/ui';
2
+ type __VLS_Props = {
3
+ modalProps?: ModalProps;
4
+ };
5
+ declare var __VLS_7: {}, __VLS_15: {}, __VLS_18: {};
6
+ type __VLS_Slots = {} & {
7
+ trigger?: (props: typeof __VLS_7) => any;
8
+ } & {
9
+ body?: (props: typeof __VLS_15) => any;
10
+ } & {
11
+ footer?: (props: typeof __VLS_18) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
+ reset: (...args: any[]) => void;
15
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
16
+ onReset?: ((...args: any[]) => any) | undefined;
17
+ }>, {
18
+ modalProps: ModalProps;
19
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
20
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
23
+ type __VLS_WithSlots<T, S> = T & {
24
+ new (): {
25
+ $slots: S;
26
+ };
27
+ };
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <UModal v-bind="modalProps">
3
+ <slot name="trigger">
4
+ <UButton
5
+ icon="i-lucide:filter"
6
+ label="Filters"
7
+ color="neutral"
8
+ variant="solid"
9
+ class="cursor-pointer"
10
+ />
11
+ </slot>
12
+
13
+ <template #body>
14
+ <slot name="body" />
15
+ </template>
16
+
17
+ <template #footer>
18
+ <slot
19
+ name="footer"
20
+ >
21
+ <UButton
22
+ label="Reset"
23
+ color="neutral"
24
+ variant="outline"
25
+ @click="emit('reset')"
26
+ />
27
+ <UButton
28
+ type="submit"
29
+ label="Apply"
30
+ color="neutral"
31
+ />
32
+ </slot>
33
+ </template>
34
+ </UModal>
35
+ </template>
36
+
37
+ <script setup>
38
+ defineProps({
39
+ modalProps: { type: Object, required: false, default: () => ({
40
+ title: "Filters",
41
+ scrollable: true,
42
+ ui: {
43
+ footer: "justify-end"
44
+ }
45
+ }) }
46
+ });
47
+ const emit = defineEmits(["reset"]);
48
+ </script>
@@ -0,0 +1,27 @@
1
+ import type { ModalProps } from '@nuxt/ui';
2
+ type __VLS_Props = {
3
+ modalProps?: ModalProps;
4
+ };
5
+ declare var __VLS_7: {}, __VLS_15: {}, __VLS_18: {};
6
+ type __VLS_Slots = {} & {
7
+ trigger?: (props: typeof __VLS_7) => any;
8
+ } & {
9
+ body?: (props: typeof __VLS_15) => any;
10
+ } & {
11
+ footer?: (props: typeof __VLS_18) => any;
12
+ };
13
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
+ reset: (...args: any[]) => void;
15
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
16
+ onReset?: ((...args: any[]) => any) | undefined;
17
+ }>, {
18
+ modalProps: ModalProps;
19
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
20
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
23
+ type __VLS_WithSlots<T, S> = T & {
24
+ new (): {
25
+ $slots: S;
26
+ };
27
+ };
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <UNavigationMenu
3
+ orientation="vertical"
4
+ :items="items"
5
+ class="data-[orientation=vertical]:w-full py-12 px-2 gap-2"
6
+ />
7
+ </template>
8
+
9
+ <script setup>
10
+ import { useAppConfig } from "#app";
11
+ const appConfig = useAppConfig();
12
+ const items = appConfig.erp && appConfig.erp.menuItems ? appConfig.erp.menuItems : [];
13
+ </script>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <nav
3
+ class="flex items-center pl-8 pt-6 pb-4 pr-8 w-full border-b border-scn-sidebar-border dark:border-default justify-between"
4
+ >
5
+ <div class="flex items-center space-x-6">
6
+ <SidebarTrigger />
7
+ <h1
8
+ :class="{
9
+ 'text-2xl font-bold font-zinc-950': true,
10
+ 'opacity-0': false
11
+ }"
12
+ >
13
+ {{ route.meta.dashboardTitle }}
14
+ </h1>
15
+ </div>
16
+ <div class="space-x-6 flex items-center">
17
+ <ColorModeButton />
18
+ </div>
19
+ </nav>
20
+ </template>
21
+
22
+ <script setup>
23
+ import { useRoute } from "#app";
24
+ import ColorModeButton from "./ColorModeButton.vue";
25
+ import SidebarTrigger from "./SidebarTrigger.vue";
26
+ const route = useRoute();
27
+ </script>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,22 @@
1
+ type __VLS_Props = {
2
+ label?: string;
3
+ icon?: string;
4
+ title?: string;
5
+ };
6
+ declare var __VLS_13: {};
7
+ type __VLS_Slots = {} & {
8
+ content?: (props: typeof __VLS_13) => any;
9
+ };
10
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
11
+ label: string;
12
+ title: string;
13
+ icon: string;
14
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
18
+ type __VLS_WithSlots<T, S> = T & {
19
+ new (): {
20
+ $slots: S;
21
+ };
22
+ };
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <USlideover :title="title">
3
+ <UButton
4
+ :label="label"
5
+ color="neutral"
6
+ variant="solid"
7
+ :icon="icon"
8
+ />
9
+
10
+ <template #content>
11
+ <slot name="content" />
12
+ </template>
13
+ </USlideover>
14
+ </template>
15
+
16
+ <script setup>
17
+ defineProps({
18
+ label: { type: String, required: false, default: "New" },
19
+ icon: { type: String, required: false, default: "i-lucide:plus" },
20
+ title: { type: String, required: false, default: "New record" }
21
+ });
22
+ </script>
@@ -0,0 +1,22 @@
1
+ type __VLS_Props = {
2
+ label?: string;
3
+ icon?: string;
4
+ title?: string;
5
+ };
6
+ declare var __VLS_13: {};
7
+ type __VLS_Slots = {} & {
8
+ content?: (props: typeof __VLS_13) => any;
9
+ };
10
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
11
+ label: string;
12
+ title: string;
13
+ icon: string;
14
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
18
+ type __VLS_WithSlots<T, S> = T & {
19
+ new (): {
20
+ $slots: S;
21
+ };
22
+ };
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <div>
3
+ <UButton
4
+ :icon="
5
+ sidebarOpen ? 'i-lucide:arrow-left-from-line' : 'i-lucide:arrow-right-from-line'
6
+ "
7
+ color="neutral"
8
+ size="xl"
9
+ variant="ghost"
10
+ @click="sidebarOpen = !sidebarOpen"
11
+ />
12
+ </div>
13
+ </template>
14
+
15
+ <script setup>
16
+ import { useCookie } from "#app";
17
+ const sidebarOpen = useCookie("sidebarOpen");
18
+ </script>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import { type UseFetchOptions, type AsyncData } from '#app';
2
+ import type { Ref } from 'vue';
3
+ export type CountFetchOptions<T> = UseFetchOptions<T> & {
4
+ count?: {
5
+ source: 'header' | 'key';
6
+ name: string;
7
+ };
8
+ };
9
+ export declare function useCountFetch<T>(url: string | (() => string), options: CountFetchOptions<T>): AsyncData<T, Error | null> & {
10
+ count: Ref<number | undefined>;
11
+ };
@@ -0,0 +1,40 @@
1
+ import { useFetch, useState } from "#app";
2
+ export function useCountFetch(url, options) {
3
+ const defaultCount = options.count ?? {
4
+ source: "header",
5
+ name: "X-Total-Count"
6
+ };
7
+ const mergedOptions = {
8
+ ...options,
9
+ count: defaultCount
10
+ };
11
+ const { count: countOpt, ...fetchOptions } = mergedOptions;
12
+ const count = useState(() => void 0);
13
+ const userOnResponse = mergedOptions.onResponse;
14
+ const fetch = useFetch(url, {
15
+ ...fetchOptions,
16
+ onResponse(ctx) {
17
+ const { response } = ctx;
18
+ if (countOpt) {
19
+ const { source, name } = countOpt;
20
+ if (source === "header") {
21
+ const headerValue = response.headers.get(name);
22
+ count.value = headerValue ? Number.parseInt(headerValue, 10) : void 0;
23
+ }
24
+ if (source === "key") {
25
+ const raw = response._data;
26
+ if (raw && typeof raw === "object" && name in raw) {
27
+ count.value = Number(raw[name]);
28
+ }
29
+ }
30
+ }
31
+ if (typeof userOnResponse === "function") {
32
+ return userOnResponse(ctx);
33
+ }
34
+ }
35
+ });
36
+ return {
37
+ ...fetch,
38
+ count
39
+ };
40
+ }
@@ -0,0 +1,15 @@
1
+ declare module '#app' {
2
+ interface PageMeta {
3
+ dashboardTitle?: string
4
+ }
5
+ }
6
+
7
+ declare module 'nuxt/schema' {
8
+ interface AppConfigInput {
9
+ erp?: {
10
+ menuItems?: NavigationMenuItem[][]
11
+ }
12
+ }
13
+ }
14
+
15
+ export {}
@@ -0,0 +1,13 @@
1
+ declare var __VLS_11: {};
2
+ type __VLS_Slots = {} & {
3
+ default?: (props: typeof __VLS_11) => any;
4
+ };
5
+ declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
6
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
9
+ type __VLS_WithSlots<T, S> = T & {
10
+ new (): {
11
+ $slots: S;
12
+ };
13
+ };
@@ -0,0 +1,15 @@
1
+ <script setup>
2
+ import { CollapsibleSidebar, NavigationHeader } from "#components";
3
+ </script>
4
+
5
+ <template>
6
+ <div class="w-screen h-screen flex">
7
+ <CollapsibleSidebar />
8
+ <main class="max-w-screen h-screen w-full flex flex-col overflow-hidden">
9
+ <NavigationHeader />
10
+ <div class="grow p-4 overflow-y-auto flex flex-col">
11
+ <slot />
12
+ </div>
13
+ </main>
14
+ </div>
15
+ </template>
@@ -0,0 +1,13 @@
1
+ declare var __VLS_11: {};
2
+ type __VLS_Slots = {} & {
3
+ default?: (props: typeof __VLS_11) => any;
4
+ };
5
+ declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
6
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
9
+ type __VLS_WithSlots<T, S> = T & {
10
+ new (): {
11
+ $slots: S;
12
+ };
13
+ };
@@ -0,0 +1,7 @@
1
+ import type { NuxtModule } from '@nuxt/schema'
2
+
3
+ import type { default as Module } from './module.mjs'
4
+
5
+ export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
+
7
+ export { default } from './module.mjs'
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "erp-blocks",
3
+ "version": "1.0.1",
4
+ "description": "Ready-to-use UI layouts and components designed as ERP system elements ",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/Davvii1/erp-blocks-nuxt.git"
8
+ },
9
+ "license": "MIT",
10
+ "type": "module",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/types.d.mts",
14
+ "import": "./dist/module.mjs"
15
+ }
16
+ },
17
+ "main": "./dist/module.mjs",
18
+ "typesVersions": {
19
+ "*": {
20
+ ".": [
21
+ "./dist/types.d.mts"
22
+ ]
23
+ }
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "scripts": {
29
+ "prepack": "nuxt-module-build build",
30
+ "dev": "npm run dev:prepare && nuxi dev playground",
31
+ "dev:build": "nuxi build playground",
32
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
33
+ "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
34
+ "lint": "eslint .",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest watch",
37
+ "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
38
+ },
39
+ "dependencies": {
40
+ "@nuxt/kit": "^4.2.1"
41
+ },
42
+ "devDependencies": {
43
+ "@nuxt/content": "3.8.1",
44
+ "@nuxt/devtools": "^3.1.0",
45
+ "@nuxt/eslint": "1.10.0",
46
+ "@nuxt/eslint-config": "^1.10.0",
47
+ "@nuxt/image": "2.0.0",
48
+ "@nuxt/module-builder": "^1.0.2",
49
+ "@nuxt/schema": "^4.2.1",
50
+ "@nuxt/test-utils": "^3.20.1",
51
+ "@nuxt/ui": "4.2.0",
52
+ "@types/node": "latest",
53
+ "changelogen": "^0.6.2",
54
+ "eslint": "^9.39.1",
55
+ "nuxt": "^4.2.1",
56
+ "typescript": "~5.9.3",
57
+ "vitest": "^4.0.10",
58
+ "vue-tsc": "^3.1.4"
59
+ }
60
+ }