Add profile picture removal
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { Form, Head, Link, usePage } from '@inertiajs/vue3';
|
||||
import { Form, Head, Link, useForm, usePage } from '@inertiajs/vue3';
|
||||
import { Trash2 } from 'lucide-vue-next';
|
||||
import { computed, onBeforeUnmount, ref } from 'vue';
|
||||
import ProfileController from '@/actions/App/Http/Controllers/Settings/ProfileController';
|
||||
import DeleteUser from '@/components/DeleteUser.vue';
|
||||
@@ -28,28 +29,41 @@ const breadcrumbItems: BreadcrumbItem[] = [
|
||||
const page = usePage();
|
||||
const user = computed(() => page.props.auth.user);
|
||||
const avatarPreview = ref<string | null>(null);
|
||||
const avatarDeleteForm = useForm({});
|
||||
const displayedAvatar = computed(
|
||||
() => avatarPreview.value ?? user.value.avatar,
|
||||
);
|
||||
const canRemoveAvatar = computed(
|
||||
() => user.value.avatar !== null && !user.value.avatar_is_generated,
|
||||
);
|
||||
|
||||
const clearAvatarPreview = (): void => {
|
||||
if (avatarPreview.value) {
|
||||
URL.revokeObjectURL(avatarPreview.value);
|
||||
avatarPreview.value = null;
|
||||
}
|
||||
};
|
||||
|
||||
const handleAvatarChange = (event: Event) => {
|
||||
const input = event.target as HTMLInputElement;
|
||||
const file = input.files?.[0];
|
||||
|
||||
if (avatarPreview.value) {
|
||||
URL.revokeObjectURL(avatarPreview.value);
|
||||
avatarPreview.value = null;
|
||||
}
|
||||
clearAvatarPreview();
|
||||
|
||||
if (file) {
|
||||
avatarPreview.value = URL.createObjectURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const removeAvatar = (): void => {
|
||||
avatarDeleteForm.delete(ProfileController.destroyAvatar.url(), {
|
||||
preserveScroll: true,
|
||||
onSuccess: clearAvatarPreview,
|
||||
});
|
||||
};
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (avatarPreview.value) {
|
||||
URL.revokeObjectURL(avatarPreview.value);
|
||||
}
|
||||
clearAvatarPreview();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -93,13 +107,26 @@ onBeforeUnmount(() => {
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div class="grid flex-1 gap-2">
|
||||
<Input
|
||||
id="avatar"
|
||||
name="avatar"
|
||||
type="file"
|
||||
accept="image/png,image/jpeg,image/webp"
|
||||
@change="handleAvatarChange"
|
||||
/>
|
||||
<div class="flex flex-col gap-2 sm:flex-row">
|
||||
<Input
|
||||
id="avatar"
|
||||
name="avatar"
|
||||
type="file"
|
||||
accept="image/png,image/jpeg,image/webp"
|
||||
@change="handleAvatarChange"
|
||||
/>
|
||||
<Button
|
||||
v-if="canRemoveAvatar"
|
||||
type="button"
|
||||
variant="outline"
|
||||
:disabled="avatarDeleteForm.processing"
|
||||
data-test="delete-profile-picture-button"
|
||||
@click="removeAvatar"
|
||||
>
|
||||
<Trash2 class="size-4" />
|
||||
Remove
|
||||
</Button>
|
||||
</div>
|
||||
<p class="text-muted-foreground text-sm">
|
||||
PNG, JPG, or WebP up to 2 MB.
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user