Initial commit

This commit is contained in:
root
2025-12-21 09:57:09 -05:00
committed by Sebastian Krupinski
commit 8ac20d8b45
38 changed files with 4677 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
<script setup lang="ts">
defineProps<{
modelValue: boolean
itemCount: number
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
'confirm': []
}>()
function handleClose() {
emit('update:modelValue', false)
}
</script>
<template>
<v-dialog :model-value="modelValue" @update:model-value="emit('update:modelValue', $event)" max-width="400">
<v-card>
<v-card-title>Delete</v-card-title>
<v-card-text>
Are you sure you want to delete {{ itemCount }} item(s)?
This action cannot be undone.
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn variant="text" @click="handleClose">Cancel</v-btn>
<v-btn color="error" variant="elevated" @click="emit('confirm')">Delete</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>

View File

@@ -0,0 +1,50 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
const props = defineProps<{
modelValue: boolean
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
'create': [name: string]
}>()
const folderName = ref('')
watch(() => props.modelValue, (isOpen) => {
if (isOpen) {
folderName.value = ''
}
})
function handleCreate() {
if (!folderName.value.trim()) return
emit('create', folderName.value.trim())
}
function handleClose() {
emit('update:modelValue', false)
}
</script>
<template>
<v-dialog :model-value="modelValue" @update:model-value="emit('update:modelValue', $event)" max-width="400">
<v-card>
<v-card-title>New Folder</v-card-title>
<v-card-text>
<v-text-field
v-model="folderName"
label="Folder name"
autofocus
@keyup.enter="handleCreate"
/>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn variant="text" @click="handleClose">Cancel</v-btn>
<v-btn color="primary" variant="elevated" @click="handleCreate">Create</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>

View File

@@ -0,0 +1,51 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
const props = defineProps<{
modelValue: boolean
currentName: string
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
'rename': [newName: string]
}>()
const newName = ref('')
watch(() => props.modelValue, (isOpen) => {
if (isOpen) {
newName.value = props.currentName
}
})
function handleRename() {
if (!newName.value.trim()) return
emit('rename', newName.value.trim())
}
function handleClose() {
emit('update:modelValue', false)
}
</script>
<template>
<v-dialog :model-value="modelValue" @update:model-value="emit('update:modelValue', $event)" max-width="400">
<v-card>
<v-card-title>Rename</v-card-title>
<v-card-text>
<v-text-field
v-model="newName"
label="New name"
autofocus
@keyup.enter="handleRename"
/>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn variant="text" @click="handleClose">Cancel</v-btn>
<v-btn color="primary" variant="elevated" @click="handleRename">Rename</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>

View File

@@ -0,0 +1,143 @@
<script setup lang="ts">
import type { FileUploadProgress } from '@/composables/useFileUpload'
import { formatSize, getUploadStatusIcon, getUploadStatusColor } from '@/utils/fileHelpers'
defineProps<{
modelValue: boolean
uploads: Map<string, FileUploadProgress>
totalProgress: number
isUploading: boolean
pendingCount: number
completedCount: number
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
'upload-all': []
'remove-upload': [id: string]
'retry-upload': [id: string]
'add-files': []
'close': []
}>()
function handleClose() {
emit('close')
}
</script>
<template>
<v-dialog :model-value="modelValue" @update:model-value="emit('update:modelValue', $event)" max-width="500" persistent>
<v-card>
<v-card-title class="d-flex align-center">
<v-icon class="mr-2">mdi-upload</v-icon>
Upload Files
</v-card-title>
<v-card-text>
<!-- Upload progress -->
<div v-if="totalProgress > 0 && isUploading" class="mb-4">
<v-progress-linear
:model-value="totalProgress"
color="primary"
height="8"
rounded
/>
<div class="text-caption text-center mt-1">
{{ totalProgress }}% complete
</div>
</div>
<!-- File list -->
<v-list density="compact" class="upload-file-list">
<v-list-item
v-for="[id, item] in uploads"
:key="id"
class="px-0"
>
<template #prepend>
<v-icon :color="getUploadStatusColor(item.status)" size="small">
{{ getUploadStatusIcon(item.status) }}
</v-icon>
</template>
<v-list-item-title class="text-body-2">
{{ item.relativePath || item.file.name }}
</v-list-item-title>
<v-list-item-subtitle>
{{ formatSize(item.file.size) }}
<span v-if="item.error" class="text-error"> {{ item.error }}</span>
</v-list-item-subtitle>
<template #append>
<v-btn
v-if="item.status === 'pending' || item.status === 'error'"
icon="mdi-close"
size="x-small"
variant="text"
@click="emit('remove-upload', id)"
/>
<v-btn
v-if="item.status === 'error'"
icon="mdi-refresh"
size="x-small"
variant="text"
color="primary"
@click="emit('retry-upload', id)"
/>
</template>
</v-list-item>
</v-list>
<!-- Empty state -->
<div v-if="uploads.size === 0" class="text-center py-8 text-grey">
<v-icon size="48" color="grey-lighten-1">mdi-file-upload-outline</v-icon>
<div class="mt-2">No files selected</div>
<v-btn
variant="tonal"
color="primary"
class="mt-4"
@click="emit('add-files')"
>
<v-icon start>mdi-plus</v-icon>
Add Files
</v-btn>
</div>
<!-- Add more files button -->
<div v-else class="text-center mt-4">
<v-btn
variant="text"
size="small"
@click="emit('add-files')"
>
<v-icon start>mdi-plus</v-icon>
Add More Files
</v-btn>
</div>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn
variant="text"
@click="handleClose"
:disabled="isUploading"
>
{{ completedCount > 0 ? 'Done' : 'Cancel' }}
</v-btn>
<v-btn
v-if="pendingCount > 0"
color="primary"
variant="elevated"
@click="emit('upload-all')"
:loading="isUploading"
>
Upload {{ pendingCount }} File(s)
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<style scoped>
.upload-file-list {
max-height: 300px;
overflow-y: auto;
}
</style>

View File

@@ -0,0 +1,4 @@
export { default as NewFolderDialog } from './NewFolderDialog.vue'
export { default as RenameDialog } from './RenameDialog.vue'
export { default as DeleteConfirmDialog } from './DeleteConfirmDialog.vue'
export { default as UploadDialog } from './UploadDialog.vue'