feat: Integrate official drive_provider, update user profile features & UI improvements
All checks were successful
CI / container-job (push) Successful in 41s
All checks were successful
CI / container-job (push) Successful in 41s
- adonisrc.ts: Load official drive_provider and unload custom driver_provider. - packages.json: Add @headlessui/vue dependency for tab components. - AvatarController.ts: Rewrite avatar generation logic to always return the same avatar per user. - auth/UserController.ts: Add profile and profileUpdate methods to support user profile editing. - Submitter/datasetController.ts & app/models/file.ts: Adapt code to use the official drive_provider. - app/models/user.ts: Introduce “isAdmin” getter. - config/drive.ts: Create new configuration for the official drive_provider. - providers/vinejs_provider.ts: Adapt allowedExtensions control to use provided options or database enabled extensions. - resource/js/app.ts: Load default Head and Link components. - resources/js/menu.ts: Add settings-profile.edit menu point. - resources/js/Components/action-message.vue: Add new component for improved user feedback after form submissions. - New avatar-input.vue component: Enable profile picture selection. - Components/CardBox.vue: Alter layout to optionally show HeaderIcon in title bar. - FormControl.vue: Define a readonly prop for textareas. - Improve overall UI with updates to NavBar.vue, UserAvatar.vue, UserAvatarCurrentUser.vue, and add v-model support to password-meter.vue. - Remove profile editing logic from AccountInfo.vue and introduce new profile components (show.vue, update-password-form.vue, update-profile-information.vue). - app.edge: Modify page (add @inertiaHead tag) for better meta management. - routes.ts: Add new routes for editing user profiles. - General npm updates.
This commit is contained in:
parent
a41b091214
commit
36cd7a757b
34 changed files with 1396 additions and 407 deletions
79
resources/js/Components/avatar-input.vue
Normal file
79
resources/js/Components/avatar-input.vue
Normal file
|
@ -0,0 +1,79 @@
|
|||
<template>
|
||||
<div class="relative inline-block overflow-hidden rounded-full">
|
||||
<input type="file" ref="avatarInput" @change="onChangeFile" class="hidden" accept="image/*">
|
||||
|
||||
<img :src="avatarUrl" alt="Avatar" class="h-full w-full object-cover">
|
||||
<div class="absolute top-0 h-full w-full bg-black bg-opacity-25 flex items-center justify-center">
|
||||
<button @click.prevent="browse"
|
||||
class="rounded-full hover:bg-white hover:bg-opacity-25 p-2 focus:outline-none text-white transition-colors duration-300">
|
||||
<IconRounded :icon="mdiCameraEnhanceOutline" class="bg-transparent h-6 w-6" />
|
||||
</button>
|
||||
<button v-if="file" @click.prevent="reset"
|
||||
class="rounded-full hover:bg-white hover:bg-opacity-25 p-2 focus:outline-none text-white transition-colors duration-300">
|
||||
<IconRounded :icon="mdiAlphaXCircleOutline " class="bg-transparent h-6 w-6" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, defineEmits } from 'vue';
|
||||
import { mdiCameraEnhanceOutline, mdiAlphaXCircleOutline } from '@mdi/js';
|
||||
import IconRounded from './IconRounded.vue';
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
modelValue: File,
|
||||
defaultSrc: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
// vue data properties
|
||||
const file = ref<File | null>(null);
|
||||
const avatarUrl = ref<string>(props.defaultSrc);
|
||||
const avatarInput = ref<HTMLInputElement | null>(null);
|
||||
|
||||
|
||||
// const avatarUrl = computed({
|
||||
// get: () => props.modelValue ? props.modelValue : props.defaultSrc,
|
||||
// set: (value: string) => {
|
||||
// emit('update:modelValue', value);
|
||||
// },
|
||||
// });
|
||||
|
||||
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', file: File | null): void; (e: 'input', file: File | null): void }>();
|
||||
|
||||
// const avatarInput = ref<HTMLInputElement | null>(null);
|
||||
|
||||
const browse = () => {
|
||||
avatarInput.value?.click();
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
file.value = null;
|
||||
avatarUrl.value = props.defaultSrc;
|
||||
emit('input', file.value);
|
||||
};
|
||||
|
||||
const onChangeFile = (e: Event) => {
|
||||
// const target = (<HTMLInputElement>e.target)
|
||||
const target = e.target as HTMLInputElement;
|
||||
if (target.files && target.files[0]) {
|
||||
file.value = target.files[0];
|
||||
}
|
||||
if (file.value) {
|
||||
emit('input', file.value);
|
||||
emit('update:modelValue', file.value);
|
||||
let reader = new FileReader();
|
||||
reader.readAsDataURL(file.value);
|
||||
reader.onload = (e) => {
|
||||
avatarUrl.value = e.target?.result as string;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue