Skip to content

Commit

Permalink
completely redo social media section on profile page
Browse files Browse the repository at this point in the history
  • Loading branch information
3vorp committed Sep 22, 2024
1 parent b75a8c1 commit 6fec59b
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 180 deletions.
194 changes: 65 additions & 129 deletions pages/profile/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,104 +107,34 @@
<v-col>
<v-form lazy-validation>
<div class="text-h6">{{ $root.lang().profile.social.title }}</div>
<template v-if="localUser.media && Object.keys(localUser.media).length">
<v-row
v-for="(socialMedia, index) in localUser.media"
:key="socialMedia.type"
align="center"
:class="['mt-0', { 'mb-1': !$vuetify.breakpoint.mdAndUp }]"
>
<v-col class="py-0" :cols="$vuetify.breakpoint.mdAndUp ? false : 12">
<v-text-field
clearable
style="margin-bottom: 0px; margin-top: 12px"
v-model="socialMedia.link"
:rules="urlRules"
:label="
$root.lang().profile.social.edit.label.replace('%s', socialMedia.type)
"
/>
</v-col>
<v-col
class="py-0"
:cols="$vuetify.breakpoint.mdAndUp ? false : 12"
:style="[
{ 'max-width': $vuetify.breakpoint.mdAndUp ? '300px' : 'none' },
'margin-top: 10px',
]"
>
<v-row align="center">
<v-col
:style="{ 'max-width': $vuetify.breakpoint.mdAndUp ? '250px' : 'none' }"
>
<v-select
:items="media"
:label="$root.lang().profile.social.select.label"
v-model="socialMedia.type"
hide-details
solo
/>
</v-col>
<v-col class="flex-grow-0 flex-shrink-0">
<v-btn
icon
@click="removeSocialMedia(index)"
style="margin-right: 8px"
elevation="2"
>
<v-icon color="red lighten-1">mdi-delete</v-icon>
</v-btn>
</v-col>
</v-row>
</v-col>
</v-row>
</template>

<v-row class="mt-2" align="center">
<v-col class="py-0" :cols="$vuetify.breakpoint.mdAndUp ? false : 12">
<v-row v-for="(socialMedia, i) in localUser.media" :key="socialMedia.key">
<v-col cols="12" sm="8">
<v-text-field
clearable
:placeholder="$root.lang().profile.social.new.placeholder"
:label="$root.lang().profile.social.new.label"
style="margin-bottom: 0px; margin-top: 12px"
v-model="newMedia.link"
:rules="urlAddRules"
:placeholder="$root.lang().profile.social.placeholder"
:label="$root.lang().profile.social.link_label"
v-model="socialMedia.link"
:rules="urlRules"
/>
</v-col>
<v-col cols="12" sm="3">
<v-select
:items="mediaTypes"
:label="$root.lang().profile.social.type_label"
v-model="socialMedia.type"
:rules="mediaTypeRules"
/>
</v-col>
<v-col
class="py-0"
:cols="$vuetify.breakpoint.mdAndUp ? false : 12"
:style="[
{ 'max-width': $vuetify.breakpoint.mdAndUp ? '300px' : 'none' },
'margin-top: 10px',
]"
>
<v-row align="center">
<v-col
:style="{ 'max-width': $vuetify.breakpoint.mdAndUp ? '250px' : 'none' }"
>
<v-select
:items="media"
:label="$root.lang().profile.social.select.label"
v-model="newMedia.type"
hide-details
solo
/>
</v-col>
<v-col class="flex-grow-0 flex-shrink-0">
<v-btn
icon
@click="addSocialMedia()"
:disabled="isMediaOk()"
style="margin-right: 8px"
elevation="2"
>
<v-icon color="lighten-1">mdi-plus</v-icon>
</v-btn>
</v-col>
</v-row>
<v-col cols="12" sm="1">
<v-btn icon @click="removeSocialMedia(i)">
<v-icon color="red darken-1"> mdi-minus </v-icon>
</v-btn>
</v-col>
</v-row>
<v-btn block class="my-5" color="secondary" @click="addSocialMedia">
{{ $root.lang().profile.social.add }}
<v-icon right>mdi-plus</v-icon>
</v-btn>
</v-form>
</v-col>
</v-row>
Expand All @@ -214,7 +144,7 @@
<v-btn text color="error darken-1" @click="openDeleteModal">
{{ $root.lang().profile.delete.btn }}
</v-btn>
<v-btn text color="darken-1" @click="send" :disabled="!everythingIsOk">
<v-btn text color="darken-1" @click="send" :disabled="!canSubmit">
{{ $root.lang().profile.save_changes }}
</v-btn>
</div>
Expand Down Expand Up @@ -242,28 +172,38 @@ import axios from "axios";
import ModalForm from "@components/modal-form.vue";
const emptySocial = () => ({
key: crypto.randomUUID(),
type: "",
link: "",
});
export default {
name: "profile-page",
components: {
ModalForm,
},
data() {
return {
localUser: {},
uuidMaxLength: 36,
usernameMaxLength: 24,
everythingIsOk: false,
newMedia: {
type: "",
link: "",
},
media: settings.socials,
urlAddRules: [(u) => this.validForm(this.validURL(u) || u === "", "URL must be valid.")],
mediaTypes: settings.socials,
validationObject: {},
urlRules: [(u) => this.validForm(this.validURL(u), "URL must be valid.")],
mediaTypeRules: [
(u) =>
this.validForm(
u && typeof u === "string" && u.trim().length > 0,
"Social type is required.",
),
(u) => this.validForm(this.mediaTypes.includes(u), "Social type must be valid."),
],
uuidRules: [
(u) =>
this.validForm(
(u && u.length === this.uuidMaxLength) || !u,
"The UUID needs to be 36 characters long.",
"UUID needs to be 36 characters long.",
),
],
usernameRules: [
Expand All @@ -279,41 +219,24 @@ export default {
`Username must be less than ${this.usernameMaxLength} characters.`,
),
],
localUser: {},
deleteModalOpened: false,
};
},
methods: {
isMediaOk() {
if (this.newMedia.type !== "" && this.newMedia.link !== "") return false;
return true;
},
validURL(str) {
return String.urlRegex.test(str);
},
addSocialMedia() {
this.localUser.media ||= [];
this.localUser.media.push(emptySocial());
},
removeSocialMedia(index) {
this.localUser.media.splice(index, 1);
},
addSocialMedia() {
if (!this.localUser.media) this.localUser.media = [];
this.localUser.media.push({
type: this.newMedia.type,
link: this.newMedia.link,
});
this.newMedia = {
type: "",
link: "",
};
},
validForm(boolResult, sentence) {
if (boolResult) {
this.everythingIsOk = true;
return true;
}
this.everythingIsOk = false;
// use object to override existing result
this.$set(this.validationObject, sentence, boolResult);
if (boolResult) return true;
return sentence.toString();
},
send() {
Expand All @@ -323,7 +246,7 @@ export default {
const data = {
uuid: this.localUser.uuid || "",
username: this.localUser.username || "",
media: this.localUser.media || [],
media: this.cleanedMedia,
};
axios
Expand Down Expand Up @@ -361,9 +284,9 @@ export default {
this.localUser = res.data;
// fix if new user or empty user
this.localUser.uuid = this.localUser.uuid || "";
this.localUser.username = this.localUser.username || "";
this.localUser.media = this.localUser.media || [];
this.localUser.uuid ||= "";
this.localUser.username ||= "";
this.localUser.media ||= [];
})
.catch((err) => {
console.error(err);
Expand All @@ -375,6 +298,19 @@ export default {
this.$nextTick(() => this.getUserInfo());
},
},
computed: {
cleanedMedia() {
return (this.localUser.media || [])
.filter((m) => m.link && m.type)
.map((m) => {
delete m.key;
return m;
});
},
canSubmit() {
return Object.values(this.validationObject).every((val) => val === true);
},
},
mounted() {
this.$root.addAccessTokenListener(this.update);
},
Expand Down
11 changes: 1 addition & 10 deletions resources/strings/cs_CZ.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,16 +343,7 @@ export default {
},
social: {
title: "Odkazy na sociální sítě",
edit: {
label: "Upravit %s URL",
},
select: {
label: "Vybrat stránku",
},
new: {
placeholder: "https://www.příklad.cz/",
label: "Nová sociální síť",
},
placeholder: "https://www.příklad.cz/",
},
},
files: {
Expand Down
11 changes: 1 addition & 10 deletions resources/strings/de_DE.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,7 @@ export default {
},
social: {
title: "Soziale Links",
edit: {
label: "URL %s bearbeiten",
},
select: {
label: "Medien auswählen",
},
new: {
placeholder: "https://www.beispiel.de/",
label: "Neue soziale Medien",
},
placeholder: "https://www.beispiel.de/",
},
},
};
16 changes: 5 additions & 11 deletions resources/strings/en_US.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ export default {
title: "General",
uuid: {
label: "Minecraft profile UUID",
hint: "Your skin will be displayed in submissions you authored.",
hint: "Your skin will be displayed with add-ons you authored.",
},
username: {
label: "Username",
Expand All @@ -436,16 +436,10 @@ export default {
},
social: {
title: "Social Links",
edit: {
label: "Edit %s URL",
},
select: {
label: "Select media",
},
new: {
placeholder: "https://www.example.com/",
label: "New social media",
},
link_label: "Edit link",
type_label: "Select media type",
placeholder: "https://www.example.com/",
add: "Add social media",
},
save_changes: "Save changes",
delete: {
Expand Down
11 changes: 1 addition & 10 deletions resources/strings/fr_FR.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,16 +360,7 @@ export default {
},
social: {
title: "Réseaux Sociaux",
edit: {
label: "Éditer l'URL de %s",
},
select: {
label: "Sélectionner un média",
},
new: {
placeholder: "https://www.exemple.com/",
label: "Nouveau réseau social",
},
placeholder: "https://www.exemple.com/",
},
},
files: {
Expand Down
11 changes: 1 addition & 10 deletions resources/strings/pt_BR.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,16 +330,7 @@ export default {
},
social: {
title: "Links sociais",
edit: {
label: "Editar URL de %s",
},
select: {
label: "Selecionar site",
},
new: {
placeholder: "https://www.example.com/",
label: "Nova rede social",
},
placeholder: "https://www.example.com/",
},
},
gallery: {
Expand Down

0 comments on commit 6fec59b

Please sign in to comment.