toolshed/frontend/src/views/settings/Account.vue
2026-09-06 03:57:24 +02:00

148 lines
No EOL
6.9 KiB
Vue

<template>
<div>
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Public info</h5>
</div>
<div class="card-body">
<form>
<div class="row">
<div class="col-md-8">
<div class="mb-3">
<label class="form-label"
for="inputUsername">Username</label>
<input type="text" class="form-control" id="inputUsername"
placeholder="Username">
</div>
<div class="mb-3">
<label class="form-label"
for="inputUsername">Biography</label>
<textarea rows="2" class="form-control" id="inputBio"
placeholder="Tell something about yourself"></textarea>
</div>
</div>
<div class="col-md-4">
<div class="text-center">
<authenticated-image :src="profilePictureSrc" :owner="user"
:refresh-key="profilePictureRefreshKey"
:alt="user" :title="user"
img-class="rounded-circle img-responsive mt-2"
:width="128" :height="128" fit="cover"/>
<div class="mt-2">
<fs-file-source @input="uploadPicture">
<span class="btn btn-primary"><b-icon-upload></b-icon-upload> Upload</span>
</fs-file-source>
<guarded-button class="btn btn-outline-secondary ml-2" type="button"
confirm-message="Are you sure you want to remove your profile picture?"
@confirm="removePicture">
Remove
</guarded-button>
</div>
<small>For best results, use an image at least 128px by
128px in .jpg format</small>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
</div>
</div>
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Private info</h5>
</div>
<div class="card-body">
<form>
<div class="row">
<div class="mb-3 col-md-6">
<label class="form-label" for="inputFirstName">First
name</label>
<input type="text" class="form-control" id="inputFirstName"
placeholder="First name">
</div>
<div class="mb-3 col-md-6">
<label class="form-label" for="inputLastName">Last name</label>
<input type="text" class="form-control" id="inputLastName"
placeholder="Last name">
</div>
</div>
<div class="mb-3">
<label class="form-label" for="inputEmail4">Email</label>
<input type="email" class="form-control" id="inputEmail4"
placeholder="Email">
</div>
<div class="mb-3">
<label class="form-label" for="inputAddress">Address</label>
<input type="text" class="form-control" id="inputAddress"
placeholder="1234 Main St">
</div>
<div class="mb-3">
<label class="form-label" for="inputAddress2">Address 2</label>
<input type="text" class="form-control" id="inputAddress2"
placeholder="Apartment, studio, or floor">
</div>
<div class="row">
<div class="mb-3 col-md-6">
<label class="form-label" for="inputCity">City</label>
<input type="text" class="form-control" id="inputCity">
</div>
<div class="mb-3 col-md-4">
<label class="form-label" for="inputState">State</label>
<select id="inputState" class="form-control">
<option selected>Choose...</option>
<option>...</option>
</select>
</div>
<div class="mb-3 col-md-2">
<label class="form-label" for="inputZip">Zip</label>
<input type="text" class="form-control" id="inputZip">
</div>
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
</div>
</div>
</div>
</template>
<script>
import * as BIcons from "bootstrap-icons-vue";
import {mapActions, mapState} from "vuex";
import AuthenticatedImage from "@/components/AuthenticatedImage.vue";
import FsFileSource from "@/components/inputs/FsFileSource.vue";
import GuardedButton from "@/components/GuardedButton.vue";
export default {
name: 'Account',
components: {AuthenticatedImage, FsFileSource, GuardedButton, ...BIcons},
computed: {
...mapState(['user', 'user_profile']),
profilePictureSrc() {
return this.user_profile?.profile_picture?.name || null;
},
profilePictureRefreshKey() {
return this.user_profile?.profile_picture?.id || 'none';
}
},
methods: {
...mapActions(['fetchUserProfile', 'updateUserProfilePicture']),
async uploadPicture(files) {
const image = files.find(file => file.mime_type?.startsWith('image/'))
if (!image) {
return;
}
await this.updateUserProfilePicture({file: image});
},
async removePicture() {
await this.updateUserProfilePicture({file: null});
}
},
mounted() {
this.fetchUserProfile();
}
}
</script>
<style scoped>
</style>