mktcms 0.1.21 → 0.1.22

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 (80) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +11 -6
  3. package/dist/runtime/app/components/admin.vue +1 -1
  4. package/dist/runtime/app/components/content/breadcrumb.d.vue.ts +1 -4
  5. package/dist/runtime/app/components/content/breadcrumb.vue +25 -9
  6. package/dist/runtime/app/components/content/breadcrumb.vue.d.ts +1 -4
  7. package/dist/runtime/app/components/content/delete.vue +69 -0
  8. package/dist/runtime/app/components/content/dirs.d.vue.ts +0 -1
  9. package/dist/runtime/app/components/content/dirs.vue +19 -3
  10. package/dist/runtime/app/components/content/dirs.vue.d.ts +0 -1
  11. package/dist/runtime/app/components/content/editor/csv.vue +284 -0
  12. package/dist/runtime/app/components/content/editor/image.vue +27 -0
  13. package/dist/runtime/app/components/content/editor/{text/markdown.vue → markdown.vue} +30 -8
  14. package/dist/runtime/app/components/content/editor/pdf.d.vue.ts +3 -0
  15. package/dist/runtime/app/components/content/editor/pdf.vue +26 -0
  16. package/dist/runtime/app/components/content/editor/pdf.vue.d.ts +3 -0
  17. package/dist/runtime/app/components/content/editor/txt.d.vue.ts +3 -0
  18. package/dist/runtime/app/components/content/editor/txt.vue +24 -0
  19. package/dist/runtime/app/components/content/editor/txt.vue.d.ts +3 -0
  20. package/dist/runtime/app/components/content/fileButtons.d.vue.ts +6 -0
  21. package/dist/runtime/app/components/content/fileButtons.vue +73 -0
  22. package/dist/runtime/app/components/content/fileButtons.vue.d.ts +6 -0
  23. package/dist/runtime/app/components/content/fileIcon.d.vue.ts +6 -0
  24. package/dist/runtime/app/components/content/fileIcon.vue +80 -0
  25. package/dist/runtime/app/components/content/fileIcon.vue.d.ts +6 -0
  26. package/dist/runtime/app/components/content/files.d.vue.ts +0 -1
  27. package/dist/runtime/app/components/content/files.vue +10 -91
  28. package/dist/runtime/app/components/content/files.vue.d.ts +0 -1
  29. package/dist/runtime/app/components/content/index.vue +3 -8
  30. package/dist/runtime/app/components/content/saved.d.vue.ts +3 -0
  31. package/dist/runtime/app/components/content/saved.vue +19 -0
  32. package/dist/runtime/app/components/content/saved.vue.d.ts +3 -0
  33. package/dist/runtime/app/components/content/upload.vue +18 -12
  34. package/dist/runtime/app/components/header.vue +55 -25
  35. package/dist/runtime/app/composables/useFileType.d.ts +7 -0
  36. package/dist/runtime/app/composables/useFileType.js +14 -0
  37. package/dist/runtime/app/composables/usePathParam.d.ts +9 -0
  38. package/dist/runtime/app/composables/usePathParam.js +16 -0
  39. package/dist/runtime/app/composables/useSaveContent.d.ts +7 -0
  40. package/dist/runtime/app/composables/useSaveContent.js +31 -0
  41. package/dist/runtime/app/pages/admin/delete/[path].d.vue.ts +3 -0
  42. package/dist/runtime/app/pages/admin/delete/[path].vue +14 -0
  43. package/dist/runtime/app/pages/admin/delete/[path].vue.d.ts +3 -0
  44. package/dist/runtime/app/pages/admin/edit/[path].d.vue.ts +3 -0
  45. package/dist/runtime/app/pages/admin/edit/[path].vue +24 -0
  46. package/dist/runtime/app/pages/admin/edit/[path].vue.d.ts +3 -0
  47. package/dist/runtime/app/pages/admin/index.vue +2 -0
  48. package/dist/runtime/app/pages/admin/login.vue +68 -21
  49. package/dist/runtime/app/styles/admin.css +1 -0
  50. package/dist/runtime/app/styles/admin.min.css +1 -0
  51. package/dist/runtime/app/util/csv.d.ts +13 -0
  52. package/dist/runtime/app/util/csv.js +38 -0
  53. package/dist/runtime/server/api/admin/content/[path].delete.d.ts +4 -0
  54. package/dist/runtime/server/api/admin/content/[path].delete.js +14 -0
  55. package/dist/runtime/server/api/admin/content/[path].js +0 -5
  56. package/dist/runtime/server/api/admin/content/list.js +0 -7
  57. package/dist/runtime/server/api/content/[path].js +0 -5
  58. package/dist/runtime/server/api/content/list.js +0 -7
  59. package/dist/runtime/server/plugins/storage.js +0 -3
  60. package/package.json +10 -2
  61. package/dist/runtime/app/components/content/editor/blob/image.d.vue.ts +0 -10
  62. package/dist/runtime/app/components/content/editor/blob/image.vue +0 -12
  63. package/dist/runtime/app/components/content/editor/blob/image.vue.d.ts +0 -10
  64. package/dist/runtime/app/components/content/editor/blob/index.vue +0 -41
  65. package/dist/runtime/app/components/content/editor/text/csv.d.vue.ts +0 -10
  66. package/dist/runtime/app/components/content/editor/text/csv.vue +0 -235
  67. package/dist/runtime/app/components/content/editor/text/csv.vue.d.ts +0 -10
  68. package/dist/runtime/app/components/content/editor/text/index.vue +0 -58
  69. package/dist/runtime/app/components/content/editor/text/markdown.d.vue.ts +0 -10
  70. package/dist/runtime/app/components/content/editor/text/markdown.vue.d.ts +0 -10
  71. package/dist/runtime/app/pages/admin/edit/blob/[path].vue +0 -12
  72. package/dist/runtime/app/pages/admin/edit/text/[path].vue +0 -12
  73. /package/dist/runtime/app/components/content/{editor/blob/index.d.vue.ts → delete.d.vue.ts} +0 -0
  74. /package/dist/runtime/app/components/content/{editor/blob/index.vue.d.ts → delete.vue.d.ts} +0 -0
  75. /package/dist/runtime/app/components/content/editor/{text/index.d.vue.ts → csv.d.vue.ts} +0 -0
  76. /package/dist/runtime/app/components/content/editor/{text/index.vue.d.ts → csv.vue.d.ts} +0 -0
  77. /package/dist/runtime/app/{pages/admin/edit/blob/[path].d.vue.ts → components/content/editor/image.d.vue.ts} +0 -0
  78. /package/dist/runtime/app/{pages/admin/edit/blob/[path].vue.d.ts → components/content/editor/image.vue.d.ts} +0 -0
  79. /package/dist/runtime/app/{pages/admin/edit/text/[path].d.vue.ts → components/content/editor/markdown.d.vue.ts} +0 -0
  80. /package/dist/runtime/app/{pages/admin/edit/text/[path].vue.d.ts → components/content/editor/markdown.vue.d.ts} +0 -0
@@ -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,24 @@
1
+ <script setup>
2
+ import Saved from "../saved.vue";
3
+ import useSaveContent from "../../../composables/useSaveContent";
4
+ const { content, saveContent, isSaving, savingSuccessful } = await useSaveContent();
5
+ </script>
6
+
7
+ <template>
8
+ <div>
9
+ <textarea
10
+ v-model="content"
11
+ class="w-full h-24 resize-y border border-gray-300 p-2 box-border font-mono"
12
+ />
13
+
14
+ <button
15
+ type="button"
16
+ class="button w-full justify-center mt-3"
17
+ @click="saveContent"
18
+ >
19
+ <span v-if="isSaving">Speichern...</span>
20
+ <span v-else>Speichern</span>
21
+ </button>
22
+ <Saved v-if="savingSuccessful" />
23
+ </div>
24
+ </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,6 @@
1
+ type __VLS_Props = {
2
+ filePath: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,73 @@
1
+ <script setup>
2
+ import { useRuntimeConfig } from "#app";
3
+ import useFileType from "../../composables/useFileType";
4
+ import { useClipboard } from "@vueuse/core";
5
+ const { filePath } = defineProps({
6
+ filePath: { type: String, required: true }
7
+ });
8
+ const { public: { mktcms: { siteUrl } } } = useRuntimeConfig();
9
+ const { isImage, isPdf } = useFileType(filePath);
10
+ const { copy, copied } = useClipboard();
11
+ </script>
12
+
13
+ <template>
14
+ <div class="flex gap-2">
15
+ <NuxtLink
16
+ v-if="isImage || isPdf"
17
+ class="button secondary"
18
+ title="Link kopieren"
19
+ @click.prevent="copy(siteUrl + '/api/content/' + filePath)"
20
+ >
21
+ <svg
22
+ v-if="copied"
23
+ xmlns="http://www.w3.org/2000/svg"
24
+ fill="none"
25
+ viewBox="0 0 24 24"
26
+ stroke-width="1.5"
27
+ stroke="currentColor"
28
+ class="size-4"
29
+ >
30
+ <path
31
+ stroke-linecap="round"
32
+ stroke-linejoin="round"
33
+ d="m4.5 12.75 6 6 9-13.5"
34
+ />
35
+ </svg>
36
+ <svg
37
+ v-else
38
+ xmlns="http://www.w3.org/2000/svg"
39
+ fill="none"
40
+ viewBox="0 0 24 24"
41
+ stroke-width="1.5"
42
+ stroke="currentColor"
43
+ class="size-4"
44
+ >
45
+ <path
46
+ stroke-linecap="round"
47
+ stroke-linejoin="round"
48
+ d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
49
+ />
50
+ </svg>
51
+ </NuxtLink>
52
+ <NuxtLink
53
+ :to="`/admin/delete/${filePath}`"
54
+ class="button secondary"
55
+ title="löschen"
56
+ >
57
+ <svg
58
+ xmlns="http://www.w3.org/2000/svg"
59
+ fill="none"
60
+ viewBox="0 0 24 24"
61
+ stroke-width="1.5"
62
+ stroke="currentColor"
63
+ class="size-4"
64
+ >
65
+ <path
66
+ stroke-linecap="round"
67
+ stroke-linejoin="round"
68
+ d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
69
+ />
70
+ </svg>
71
+ </NuxtLink>
72
+ </div>
73
+ </template>
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ filePath: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ filePath: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,80 @@
1
+ <script setup>
2
+ import { useRuntimeConfig } from "#app";
3
+ import useFileType from "../../composables/useFileType";
4
+ const { filePath } = defineProps({
5
+ filePath: { type: String, required: true }
6
+ });
7
+ const { public: { mktcms: { siteUrl } } } = useRuntimeConfig();
8
+ const { isImage, isCsv, isMarkdown, isText, isPdf } = useFileType(filePath);
9
+ </script>
10
+
11
+ <template>
12
+ <img
13
+ v-if="isImage"
14
+ :src="`${siteUrl}/api/content/${filePath}`"
15
+ alt="Vorschaubild"
16
+ class="size-6 rounded-sm object-cover mr-1"
17
+ >
18
+ <svg
19
+ v-if="isCsv"
20
+ xmlns="http://www.w3.org/2000/svg"
21
+ width="24"
22
+ height="24"
23
+ viewBox="0 0 24 24"
24
+ fill="none"
25
+ stroke="currentColor"
26
+ stroke-width="2"
27
+ stroke-linecap="round"
28
+ stroke-linejoin="round"
29
+ class="size-6 opacity-20"
30
+ >
31
+ <path d="M12 3v18" />
32
+ <rect
33
+ width="18"
34
+ height="18"
35
+ x="3"
36
+ y="3"
37
+ rx="2"
38
+ />
39
+ <path d="M3 9h18" />
40
+ <path d="M3 15h18" />
41
+ </svg>
42
+ <svg
43
+ v-if="isMarkdown || isText"
44
+ xmlns="http://www.w3.org/2000/svg"
45
+ width="24"
46
+ height="24"
47
+ viewBox="0 0 24 24"
48
+ fill="none"
49
+ stroke="currentColor"
50
+ stroke-width="2"
51
+ stroke-linecap="round"
52
+ stroke-linejoin="round"
53
+ class="size-6 opacity-20"
54
+ >
55
+ <path
56
+ d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"
57
+ />
58
+ <path d="M14 2v5a1 1 0 0 0 1 1h5" />
59
+ <path d="M10 9H8" />
60
+ <path d="M16 13H8" />
61
+ <path d="M16 17H8" />
62
+ </svg>
63
+ <svg
64
+ v-if="isPdf"
65
+ xmlns="http://www.w3.org/2000/svg"
66
+ width="24"
67
+ height="24"
68
+ viewBox="0 0 24 24"
69
+ class="size-6 opacity-20"
70
+ >
71
+ <path
72
+ fill="none"
73
+ stroke="currentColor"
74
+ stroke-linecap="round"
75
+ stroke-linejoin="round"
76
+ stroke-width="2"
77
+ d="M10 8v8h2a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2zm-7 4h2a2 2 0 1 0 0-4H3v8m14-4h3m1-4h-4v8"
78
+ />
79
+ </svg>
80
+ </template>
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ filePath: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -1,5 +1,4 @@
1
1
  type __VLS_Props = {
2
- path: string;
3
2
  files: string[];
4
3
  };
5
4
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,109 +1,28 @@
1
1
  <script setup>
2
+ import usePathParam from "../../composables/usePathParam";
3
+ import FileIcon from "./fileIcon.vue";
4
+ import FileButtons from "./fileButtons.vue";
2
5
  defineProps({
3
- path: { type: String, required: true },
4
6
  files: { type: Array, required: true }
5
7
  });
8
+ const { path } = usePathParam();
6
9
  </script>
7
10
 
8
11
  <template>
9
- <div class="files">
12
+ <div>
10
13
  <div
11
14
  v-for="file in files"
12
15
  :key="file"
13
- style="display: flex; align-items: center;"
16
+ class="flex gap-2 mb-2"
14
17
  >
15
18
  <NuxtLink
16
- :to="`/admin/edit/${file.match(/\.md$|\.csv$|\.txt$|\.json$/i) ? 'text' : 'blob'}/${path ? path + ':' : ''}${file}`"
17
- style="flex-grow: 1;"
19
+ :to="`/admin/edit/${path ? path + ':' : ''}${file}`"
20
+ class="flex-1 button secondary"
18
21
  >
19
- <img
20
- v-if="file.match(/\.png$|\.jpg$|\.jpeg$|\.gif$|\.svg$|\.webp$/i)"
21
- :src="`/api/content/${path ? path + ':' : ''}${file}`"
22
- alt="Vorschaubild"
23
- style="width: 64px; height: 64px; vertical-align: middle; margin-right: 4px; object-fit: cover;"
24
- >
22
+ <FileIcon :file-path="`${path ? path + ':' : ''}${file}`" />
25
23
  {{ file }}
26
24
  </NuxtLink>
27
- <NuxtLink
28
- v-if="file.match(/\.png$|\.jpg$|\.jpeg$|\.gif$|\.svg$|\.webp$/i)"
29
- style="margin-left: 8px;"
30
- title="Link kopieren"
31
- >
32
- <svg
33
- xmlns="http://www.w3.org/2000/svg"
34
- fill="none"
35
- viewBox="0 0 24 24"
36
- stroke-width="1.5"
37
- stroke="currentColor"
38
- class="button-icon"
39
- >
40
- <path
41
- stroke-linecap="round"
42
- stroke-linejoin="round"
43
- d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
44
- />
45
- </svg>
46
- </NuxtLink>
47
- <NuxtLink
48
- :to="`/admin/move/${path ? path + ':' : ''}${file}`"
49
- style="margin-left: 8px;"
50
- title="verschieben / umbenennen"
51
- >
52
- <svg
53
- xmlns="http://www.w3.org/2000/svg"
54
- fill="none"
55
- viewBox="0 0 24 24"
56
- stroke-width="1.5"
57
- stroke="currentColor"
58
- class="button-icon"
59
- >
60
- <path
61
- stroke-linecap="round"
62
- stroke-linejoin="round"
63
- d="M3.75 9.776c.112-.017.227-.026.344-.026h15.812c.117 0 .232.009.344.026m-16.5 0a2.25 2.25 0 0 0-1.883 2.542l.857 6a2.25 2.25 0 0 0 2.227 1.932H19.05a2.25 2.25 0 0 0 2.227-1.932l.857-6a2.25 2.25 0 0 0-1.883-2.542m-16.5 0V6A2.25 2.25 0 0 1 6 3.75h3.879a1.5 1.5 0 0 1 1.06.44l2.122 2.12a1.5 1.5 0 0 0 1.06.44H18A2.25 2.25 0 0 1 20.25 9v.776"
64
- />
65
- </svg>
66
- </NuxtLink>
67
- <NuxtLink
68
- :to="`/admin/copy/${path ? path + ':' : ''}${file}`"
69
- style="margin-left: 8px;"
70
- title="kopieren"
71
- >
72
- <svg
73
- xmlns="http://www.w3.org/2000/svg"
74
- fill="none"
75
- viewBox="0 0 24 24"
76
- stroke-width="1.5"
77
- stroke="currentColor"
78
- class="button-icon"
79
- >
80
- <path
81
- stroke-linecap="round"
82
- stroke-linejoin="round"
83
- d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
84
- />
85
- </svg>
86
- </NuxtLink>
87
- <NuxtLink
88
- :to="`/admin/delete/${path ? path + ':' : ''}${file}`"
89
- style="margin-left: 8px;"
90
- title="löschen"
91
- >
92
- <svg
93
- xmlns="http://www.w3.org/2000/svg"
94
- fill="none"
95
- viewBox="0 0 24 24"
96
- stroke-width="1.5"
97
- stroke="currentColor"
98
- class="button-icon"
99
- >
100
- <path
101
- stroke-linecap="round"
102
- stroke-linejoin="round"
103
- d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
104
- />
105
- </svg>
106
- </NuxtLink>
25
+ <FileButtons :file-path="`${path ? path + ':' : ''}${file}`" />
107
26
  </div>
108
27
  </div>
109
28
  </template>
@@ -1,5 +1,4 @@
1
1
  type __VLS_Props = {
2
- path: string;
3
2
  files: string[];
4
3
  };
5
4
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,11 +1,10 @@
1
1
  <script setup>
2
- import { useFetch, useRoute } from "#app";
2
+ import { useFetch } from "#app";
3
3
  import { computed } from "vue";
4
- import Breadcrumb from "./breadcrumb.vue";
5
4
  import Files from "./files.vue";
6
5
  import Dirs from "./dirs.vue";
7
- const path = useRoute().params.path || "";
8
- const pathParts = path.split(":");
6
+ import usePathParam from "../../composables/usePathParam";
7
+ const { path, pathParts } = usePathParam();
9
8
  const { data: keys } = await useFetch("/api/admin/content/list", {
10
9
  query: { path }
11
10
  });
@@ -33,17 +32,13 @@ const dirs = computed(() => {
33
32
 
34
33
  <template>
35
34
  <div>
36
- <Breadcrumb :parts="pathParts" />
37
-
38
35
  <Files
39
36
  v-if="files.length"
40
- :path="path"
41
37
  :files="files"
42
38
  />
43
39
 
44
40
  <Dirs
45
41
  v-if="dirs.length"
46
- :path="path"
47
42
  :dirs="dirs"
48
43
  style="margin-top: 8px;"
49
44
  />
@@ -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,19 @@
1
+ <template>
2
+ <div class="text-emerald-700 text-center my-3 flex items-center justify-center gap-2">
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ fill="none"
6
+ viewBox="0 0 24 24"
7
+ stroke-width="1.5"
8
+ stroke="currentColor"
9
+ class="size-6"
10
+ >
11
+ <path
12
+ stroke-linecap="round"
13
+ stroke-linejoin="round"
14
+ d="m4.5 12.75 6 6 9-13.5"
15
+ />
16
+ </svg>
17
+ Gespeichert
18
+ </div>
19
+ </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;
@@ -25,14 +25,14 @@ onMounted(() => {
25
25
  </script>
26
26
 
27
27
  <template>
28
- <div style="display: flex; flex-direction: column; gap: 8px; margin: 16px 0;">
29
- <h1 style="margin-bottom: 0;">
28
+ <div class="flex flex-col gap-2 my-4">
29
+ <h1 class="my-6">
30
30
  Datei hochladen
31
31
  </h1>
32
32
 
33
- <div style="display: flex; gap: 16px; align-items: center;">
34
- <div style="flex-grow: 1;">
35
- <h3 style="margin-bottom: 4px;">
33
+ <div class="flex gap-4 items-center">
34
+ <div class="flex-1">
35
+ <h3 class="mb-1">
36
36
  Ordner
37
37
  </h3>
38
38
  <select
@@ -51,32 +51,38 @@ onMounted(() => {
51
51
  </option>
52
52
  </select>
53
53
  </div>
54
- <div style="flex-grow: 1;">
55
- <h3 style="margin-bottom: 4px;">
56
- Neuen Unterordner erstellen
54
+ <div class="flex-1">
55
+ <h3 class="mb-1">
56
+ Unterordner erstellen
57
57
  </h3>
58
58
  <input
59
59
  v-model="newSubdir"
60
60
  type="text"
61
- placeholder="Unterordner (z.B. 'Produkte')"
61
+ placeholder="z.B. Produkte"
62
62
  @change="path = dir ? dir.replace(/\//g, ':') + ':' + newSubdir : newSubdir"
63
63
  >
64
64
  </div>
65
65
  </div>
66
66
 
67
67
  <button
68
+ type="button"
69
+ class="button"
68
70
  :disabled="isUploading"
69
71
  @click="fileInputImg?.click()"
70
72
  >
71
73
  Bild hochladen
72
74
  </button>
73
75
  <button
76
+ type="button"
77
+ class="button"
74
78
  :disabled="isUploading"
75
79
  @click="fileInputPdf?.click()"
76
80
  >
77
81
  PDF hochladen
78
82
  </button>
79
83
  <button
84
+ type="button"
85
+ class="button"
80
86
  :disabled="isUploading"
81
87
  @click="fileInput?.click()"
82
88
  >
@@ -84,7 +90,7 @@ onMounted(() => {
84
90
  </button>
85
91
  <input
86
92
  ref="fileInput"
87
- style="display: none"
93
+ class="hidden"
88
94
  type="file"
89
95
  accept=".pdf,.jpg,.jpeg,.png,.gif,.svg,.webp,.md,.docx,.txt"
90
96
  @change="async (e) => {
@@ -93,7 +99,7 @@ onMounted(() => {
93
99
  >
94
100
  <input
95
101
  ref="fileInputImg"
96
- style="display: none"
102
+ class="hidden"
97
103
  type="file"
98
104
  accept=".jpg,.jpeg,.png,.gif,.svg,.webp"
99
105
  @change="async (e) => {
@@ -102,7 +108,7 @@ onMounted(() => {
102
108
  >
103
109
  <input
104
110
  ref="fileInputPdf"
105
- style="display: none"
111
+ class="hidden"
106
112
  type="file"
107
113
  accept=".pdf"
108
114
  @change="async (e) => {
@@ -1,15 +1,41 @@
1
1
  <script setup>
2
- import { useRoute, useRuntimeConfig } from "#imports";
2
+ import { useRuntimeConfig } from "#imports";
3
3
  const { public: { mktcms: { siteUrl } } } = useRuntimeConfig();
4
- const route = useRoute();
5
4
  </script>
6
5
 
7
6
  <template>
8
- <div style="display: flex; justify-content: space-between; align-items: center; gap: 8px;">
7
+ <div class="flex items-start justify-between gap-2">
8
+ <div class="flex flex-col gap-1 items-start">
9
+ <NuxtLink
10
+ to="/admin"
11
+ class="font-bold text-xl"
12
+ >
13
+ {{ siteUrl.replace(/https?:\/\//, "") }}
14
+ </NuxtLink>
15
+ <NuxtLink
16
+ :to="siteUrl"
17
+ class="font-bold button small secondary justify-between"
18
+ >
19
+ zur Website
20
+ <svg
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ fill="none"
23
+ viewBox="0 0 24 24"
24
+ stroke-width="1.5"
25
+ stroke="currentColor"
26
+ class="size-4"
27
+ >
28
+ <path
29
+ stroke-linecap="round"
30
+ stroke-linejoin="round"
31
+ d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"
32
+ />
33
+ </svg>
34
+ </NuxtLink>
35
+ </div>
9
36
  <NuxtLink
10
- v-if="route.fullPath != '/admin'"
11
- to="/admin"
12
- class="button soft"
37
+ to="/admin/new"
38
+ class="button small ml-auto"
13
39
  >
14
40
  <svg
15
41
  xmlns="http://www.w3.org/2000/svg"
@@ -17,36 +43,40 @@ const route = useRoute();
17
43
  viewBox="0 0 24 24"
18
44
  stroke-width="1.5"
19
45
  stroke="currentColor"
20
- class="button-icon"
46
+ class="size-4"
21
47
  >
22
48
  <path
23
49
  stroke-linecap="round"
24
50
  stroke-linejoin="round"
25
- d="M15.75 19.5 8.25 12l7.5-7.5"
51
+ d="M12 4.5v15m7.5-7.5h-15"
26
52
  />
27
53
  </svg>
28
- </NuxtLink>
29
- <NuxtLink
30
- to="/admin/new"
31
- class="button"
32
- style="margin-left: auto;"
33
- >
34
- Datei hochladen
35
- </NuxtLink>
36
- <NuxtLink
37
- :to="siteUrl"
38
- external
39
- target="_blank"
40
- class="button soft"
41
- >
42
- zur Website
54
+ <span class="hidden sm:inline">
55
+ Datei hochladen
56
+ </span>
43
57
  </NuxtLink>
44
58
  <NuxtLink
45
59
  external
46
60
  to="/api/admin/logout"
47
- class="button soft"
61
+ class="button small secondary"
48
62
  >
49
- Abmelden
63
+ <span class="hidden sm:inline">
64
+ abmelden
65
+ </span>
66
+ <svg
67
+ xmlns="http://www.w3.org/2000/svg"
68
+ width="24"
69
+ height="24"
70
+ viewBox="0 0 24 24"
71
+ fill="none"
72
+ stroke="currentColor"
73
+ stroke-width="2"
74
+ stroke-linecap="round"
75
+ stroke-linejoin="round"
76
+ class="size-4"
77
+ >
78
+ <path d="m16 17 5-5-5-5" /><path d="M21 12H9" /><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
79
+ </svg>
50
80
  </NuxtLink>
51
81
  </div>
52
82
  </template>
@@ -0,0 +1,7 @@
1
+ export default function useFileType(path: string): {
2
+ isImage: boolean;
3
+ isPdf: boolean;
4
+ isMarkdown: boolean;
5
+ isCsv: boolean;
6
+ isText: boolean;
7
+ };
@@ -0,0 +1,14 @@
1
+ export default function useFileType(path) {
2
+ const isImage = path.match(/\.(png|jpg|jpeg|gif|svg|webp)$/i) !== null;
3
+ const isPdf = path.endsWith(".pdf");
4
+ const isMarkdown = path.endsWith(".md");
5
+ const isCsv = path.endsWith(".csv");
6
+ const isText = path.match(/\.(txt|json)$/i) !== null;
7
+ return {
8
+ isImage,
9
+ isPdf,
10
+ isMarkdown,
11
+ isCsv,
12
+ isText
13
+ };
14
+ }
@@ -0,0 +1,9 @@
1
+ export default function usePathParam(): {
2
+ path: string;
3
+ pathParts: string[];
4
+ isImage: boolean;
5
+ isPdf: boolean;
6
+ isMarkdown: boolean;
7
+ isCsv: boolean;
8
+ isText: boolean;
9
+ };