Colors + profile mapping + socialNetworks urls. Missing images

This commit is contained in:
Dominic Villemure
2024-06-30 15:47:43 -04:00
parent 3ce1c0013a
commit 169e2cc160
11 changed files with 119 additions and 61 deletions

View File

@@ -1,5 +1,5 @@
<template> <template>
<v-app> <v-app v-if="isUserLoaded">
<div class="m-0 flex flex-column h-screen"> <div class="m-0 flex flex-column h-screen">
<Header @toggle-sidebar="toggleSidebar" class="fixed w-full z-50 top-0 p-2"></Header> <Header @toggle-sidebar="toggleSidebar" class="fixed w-full z-50 top-0 p-2"></Header>
<div class="flex flex-row relative"> <div class="flex flex-row relative">
@@ -27,20 +27,30 @@
</v-app> </v-app>
</template> </template>
<script setup> <script async setup>
import Header from "@/views/main/Header.vue"; import Header from "@/views/main/Header.vue";
import Footer from "@/views/main/Footer.vue"; import Footer from "@/views/main/Footer.vue";
import SideBar from "@/views/main/SideBar.vue"; import SideBar from "@/views/main/SideBar.vue";
import {ref, onMounted, onUnmounted} from 'vue'; import {ref, onMounted, onUnmounted, onBeforeMount} from 'vue';
import StripePayment from "@/views/StripePayment.vue";
import {eventBus} from '@/eventBus.js'; import {eventBus} from '@/eventBus.js';
import {useUserStore} from "@/stores/user.js";
import {useClient} from "@/plugins/api.js";
const hideSideBar = ref(false); const hideSideBar = ref(false);
const isUserLoaded = ref(false);
const showPopup = ref(false); const showPopup = ref(false);
const popup = ref(null); const popup = ref(null);
const popupButton = ref(null); const popupButton = ref(null);
let closeSidebarTimer = null; let closeSidebarTimer = null;
let client = useClient();
let userStore = useUserStore();
onBeforeMount(async () => {
await userStore.setCurrentUser(client);
isUserLoaded.value = true;
});
const toggleSidebar = () => { const toggleSidebar = () => {
hideSideBar.value = !hideSideBar.value; hideSideBar.value = !hideSideBar.value;
}; };

View File

@@ -1,5 +1,7 @@
import UserTransactionsModel from "@/models/userTransactionsModel.js"; import UserTransactionsModel from "@/models/userTransactionsModel.js";
import SocialNetworksModel from "@/models/socialNetworksModel.js"; import SocialNetworksModel from "@/models/socialNetworksModel.js";
import ProfileColorsModel from "@/models/profileColorsModel.js";
import StoredDataUrlsModel from "@/models/storedDataUrlsModel.js";
export default class MyUserModel export default class MyUserModel
{ {
@@ -9,7 +11,7 @@ export default class MyUserModel
userName = ""; userName = "";
occupation = ""; occupation = "";
email = ""; email = "";
phone = ""; phoneNumber = "";
birthDate = ""; birthDate = "";
country = ""; country = "";
city = ""; city = "";
@@ -17,6 +19,8 @@ export default class MyUserModel
about = ""; about = "";
description = ""; description = "";
socialNetworks = new SocialNetworksModel(); socialNetworks = new SocialNetworksModel();
profileColors = new ProfileColorsModel();
storedDataUrlsModel = new StoredDataUrlsModel();
totalBalance = ""; totalBalance = "";
userTransactions = []; userTransactions = [];
@@ -32,4 +36,11 @@ export default class MyUserModel
return userModel; return userModel;
} }
static getDefaultUser(){
const defaultUser = new MyUserModel();
defaultUser.userName = "Anonymous"
return defaultUser;
}
} }

View File

@@ -0,0 +1,11 @@
export default class ProfileColorsModel
{
bannerTop = "";
bannerBottom = "";
accent = "";
menu = "";
static createFromApiResult(apiResult){
return Object.assign(new ProfileColorsModel(), apiResult)
}
}

View File

@@ -0,0 +1,10 @@
export default class StoredDataUrlsModel
{
bannerPictureUrl = "";
profilePictureUrl = "";
websiteIconUrl = "";
static createFromApiResult(apiResult){
return Object.assign(new StoredDataUrlsModel(), apiResult)
}
}

View File

@@ -3,15 +3,25 @@ import { defineStore } from 'pinia'
import MyUserModel from "@/models/myUserModel.js"; import MyUserModel from "@/models/myUserModel.js";
export const useUserStore = defineStore('user', () => { export const useUserStore = defineStore('user', () => {
const user = ref(MyUserModel) const user = ref({});
async function getCurrentUser(client) {
function getCurrentUser() {
return this.user.value;
}
async function setCurrentUser(client) {
try {
const myUser = await client.get("/api/GetMyUser"); const myUser = await client.get("/api/GetMyUser");
return MyUserModel.createFromApiResult(myUser.data); this.user.value = MyUserModel.createFromApiResult(myUser.data);
} catch (e){
this.user.value = MyUserModel.getDefaultUser();
console.log("User not logged.")
}
} }
async function updateCurrentUser(client, myUserModel) { async function updateCurrentUser(client, myUserModel) {
this.user.value = myUserModel;
await client.patch("/api/UpdateMyUser/profile", myUserModel) await client.patch("/api/UpdateMyUser/profile", myUserModel)
} }
return { user, getCurrentUser, updateCurrentUser } return { user, getCurrentUser, setCurrentUser, updateCurrentUser }
}) })

View File

@@ -28,14 +28,14 @@
<div class="flex justify-between items-center mb-2"> <div class="flex justify-between items-center mb-2">
<label class="text-lg">Courriel</label> <label class="text-lg">Courriel</label>
</div> </div>
<v-text-field v-model="user.email" label="Courriel" variant="outlined"></v-text-field> <v-text-field disabled v-model="user.email" label="Courriel" variant="outlined"></v-text-field>
</div> </div>
<div> <div>
<div class="flex justify-between items-center mb-2"> <div class="flex justify-between items-center mb-2">
<label class="text-lg">Téléphone</label> <label class="text-lg">Téléphone</label>
</div> </div>
<v-text-field v-model="user.phone" label="Téléphone" variant="outlined"></v-text-field> <v-text-field v-model="user.phoneNumber" label="Téléphone" variant="outlined"></v-text-field>
</div> </div>
<div> <div>

View File

@@ -101,7 +101,6 @@
</template> </template>
<script setup> <script setup>
import {useClient} from "@/plugins/api.js";
import {ref, onMounted, onBeforeUnmount} from "vue"; import {ref, onMounted, onBeforeUnmount} from "vue";
import {eventBus} from '@/eventBus.js'; import {eventBus} from '@/eventBus.js';
import {useRouter} from 'vue-router'; import {useRouter} from 'vue-router';
@@ -112,7 +111,6 @@ const currentUserName = ref("Anonyme");
const searchQuery = ref(""); const searchQuery = ref("");
const showSearch = ref(false); const showSearch = ref(false);
let currentUser = null; let currentUser = null;
const client = useClient();
const userStore = useUserStore(); const userStore = useUserStore();
const toggleSidebar = () => { const toggleSidebar = () => {
@@ -152,13 +150,10 @@ const logout = () => {
window.location.reload(); window.location.reload();
}; };
onMounted(async () => { onMounted( () => {
try { currentUser = userStore.getCurrentUser();
currentUser = await userStore.getCurrentUser(client);
currentUserName.value = currentUser.userName; currentUserName.value = currentUser.userName;
} catch (error) {
console.log("User not logged");
}
document.addEventListener('click', handleClickOutside); document.addEventListener('click', handleClickOutside);
}); });

View File

@@ -2,49 +2,66 @@
<div class="px-2"> <div class="px-2">
<div class="flex flex-col max-w-2xl mx-auto rounded-3xl shadow-2xl mt-2 mb-16"> <div class="flex flex-col max-w-2xl mx-auto rounded-3xl shadow-2xl mt-2 mb-16">
<H1 class="text-center text-4xl bg-fuchsia-900 p-3 w-full rounded-t-3xl border-b-4 border-b-gray-200 font-sans text-white"> <h1 class="text-center text-4xl bg-fuchsia-900 p-3 w-full rounded-t-3xl border-b-4 border-b-gray-200 font-sans text-white">
Personnaliser votre profil Personnaliser votre profil
</h1> </h1>
<ProfileBanner :user="currentUser"></ProfileBanner> <ProfileBanner :user="currentUser"></ProfileBanner>
<Aboutyou :user="currentUser"></Aboutyou> <AboutYou :user="currentUser"></AboutYou>
<SocialLinks :social-networks="currentUser.socialNetworks"></SocialLinks> <SocialLinks :social-networks="currentUser.socialNetworks"></SocialLinks>
<div class="sticky inset-x-0 bottom-0 flex justify-center px-4 pb-4"> <div class="sticky inset-x-0 bottom-0 flex justify-center px-4 pb-4">
<div class="flex space-x-2"> <div class="flex space-x-2">
<v-btn class="save-btn" @click="saveAll">Enregistrer</v-btn> <v-btn class="save-btn" @click="saveForm">Enregistrer</v-btn>
<router-link :to="`/${currentUserName}`"> <router-link :to="`/${currentUser.userName}`">
<v-btn class="save-btn">Retour</v-btn> <v-btn class="save-btn">Retour</v-btn>
</router-link> </router-link>
</div> </div>
</div> </div>
<v-snackbar v-model="snackbar" :timeout="1000">
Sauvegarde
<template v-slot:actions>
<v-btn color="green" variant="text" @click="snackbar = false">
Fermer
</v-btn>
</template>
</v-snackbar>
</div> </div>
</div> </div>
</template> </template>
<script async setup> <script async setup>
import Aboutyou from "@/views/main/Aboutyou.vue"; import AboutYou from "@/views/main/Aboutyou.vue";
import SocialLinks from "@/views/main/SocialLinks.vue"; import SocialLinks from "@/views/main/SocialLinks.vue";
import ProfileBanner from "@/views/main/ProfileBanner.vue"; import ProfileBanner from "@/views/main/ProfileBanner.vue";
import DonationPopup from "@/views/main/DonationPopup.vue";
import {onBeforeMount, ref} from "vue"; import {onBeforeMount, ref} from "vue";
import {useClient} from "@/plugins/api.js";
import {useUserStore} from "@/stores/user.js"; import {useUserStore} from "@/stores/user.js";
import MyUserModel from "@/models/myUserModel.js"; import MyUserModel from "@/models/myUserModel.js";
const client = useClient(); import {useClient} from "@/plugins/api.js";
const userStore = useUserStore(); const userStore = useUserStore();
const client = useClient();
const currentUser = ref(MyUserModel) const currentUser = ref(MyUserModel)
const snackbar = ref(false);
onBeforeMount(async () => { onBeforeMount( () => {
try { try {
currentUser.value = await userStore.getCurrentUser(client); currentUser.value = userStore.getCurrentUser();
} catch(error) { } catch(error) {
console.log("User not logged") console.log("User not logged")
} }
}) })
async function saveForm(){
snackbar.value = true;
await userStore.updateCurrentUser(client, currentUser.value);
}
</script> </script>

View File

@@ -1,28 +1,28 @@
<template> <template>
<div> <div>
<div> <div>
<div class="px-5 py-2 bg-fuchsia-800 text-white" :style="{ backgroundColor: accent2Color }" > <div class="px-5 py-2 bg-fuchsia-800 text-white" :style="{ backgroundColor: user.profileColors.menu }" >
<div class="flex justify-center text-2xl">Photo de couverture</div> <div class="flex justify-center text-2xl">Photo de couverture</div>
</div> </div>
<div> <div>
<div :style="{ backgroundColor: topColor }" class="flex h-4"></div> <div :style="{ backgroundColor: user.profileColors.bannerTop }" class="flex h-4"></div>
<img :src="bannerImageUrl" alt="Banner Image" class="w-full object-cover"> <img :src="bannerImageUrl" alt="Banner Image" class="w-full object-cover">
<div :style="{ backgroundColor: bottomColor }" class="h-4"> <div :style="{ backgroundColor: user.profileColors.bannerBottom }" class="h-4">
</div> </div>
<div> <div>
<div class="space-x-4 flex justify-center py-2"> <div class="space-x-4 flex justify-center py-2">
<v-btn @click="openColorPicker('top')" <v-btn @click="openColorPicker('top')"
:style="{ backgroundColor: topColor, color: getTextColor(topColor) }">Haut :style="{ backgroundColor: user.profileColors.bannerTop, color: getTextColor(user.profileColors.bannerTop) }">Haut
</v-btn> </v-btn>
<v-btn @click="openColorPicker('bottom')" <v-btn @click="openColorPicker('bottom')"
:style="{ backgroundColor: bottomColor, color: getTextColor(bottomColor) }">Bas :style="{ backgroundColor: user.profileColors.bannerBottom, color: getTextColor(user.profileColors.bannerBottom) }">Bas
</v-btn> </v-btn>
<v-btn @click="openColorPicker('accent')" <v-btn @click="openColorPicker('accent')"
:style="{ backgroundColor: accentColor, color: getTextColor(accentColor) }">Accent1 :style="{ backgroundColor: user.profileColors.accent, color: getTextColor(user.profileColors.accent) }">Accent1
</v-btn> </v-btn>
<v-btn @click="openColorPicker('accent2')" <v-btn @click="openColorPicker('menu')"
:style="{ backgroundColor: accent2Color, color: getTextColor(accent2Color) }">Menu :style="{ backgroundColor: user.profileColors.menu, color: getTextColor(user.profileColors.menu) }">Menu
</v-btn> </v-btn>
</div> </div>
</div> </div>
@@ -41,7 +41,7 @@
</div> </div>
<div class="flex justify-center py-4"> <div class="flex justify-center py-4">
<img :src="profilePictureUrl" <img :src="profilePictureUrl"
:style="{ borderColor: accentColor, borderWidth: '3px', borderStyle: 'solid' }" :style="{ borderColor: user.profileColors.accent, borderWidth: '3px', borderStyle: 'solid' }"
class="rounded-full max-w-48 max-w-48" class="rounded-full max-w-48 max-w-48"
alt="Profile Image"> alt="Profile Image">
</div> </div>
@@ -72,20 +72,11 @@
import MyUserModel from "@/models/myUserModel.js"; import MyUserModel from "@/models/myUserModel.js";
const props = defineProps({ const props = defineProps({
initialTopColor: { type: String, default: '#6B0065' },
initialBottomColor: { type: String, default: '#A30E79' },
initialAccentColor: { type: String, default: '#282286' },
initialAccent2Color: { type: String, default: '#A526B6' },
initialBannerImageUrl: { type: String, default: '/images/usersmedia/HutopyProfile/banners/banner01.png' }, initialBannerImageUrl: { type: String, default: '/images/usersmedia/HutopyProfile/banners/banner01.png' },
initialProfilePictureUrl: { type: String, default: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png' }, initialProfilePictureUrl: { type: String, default: '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png' },
user: { type: MyUserModel }, user: { type: MyUserModel },
}); });
const topColor = ref(props.initialTopColor);
const bottomColor = ref(props.initialBottomColor);
const accentColor = ref(props.initialAccentColor);
const accent2Color = ref(props.initialAccent2Color);
const bannerImageUrl = ref(props.initialBannerImageUrl); const bannerImageUrl = ref(props.initialBannerImageUrl);
const profilePictureUrl = ref(props.initialProfilePictureUrl); const profilePictureUrl = ref(props.initialProfilePictureUrl);
@@ -125,13 +116,13 @@
const applyColor = () => { const applyColor = () => {
if (colorTarget.value === 'top') { if (colorTarget.value === 'top') {
topColor.value = selectedColor.value; props.user.profileColors.bannerTop = selectedColor.value;
} else if (colorTarget.value === 'bottom') { } else if (colorTarget.value === 'bottom') {
bottomColor.value = selectedColor.value; props.user.profileColors.bannerBottom = selectedColor.value;
} else if (colorTarget.value === 'accent') { } else if (colorTarget.value === 'accent') {
accentColor.value = selectedColor.value; props.user.profileColors.accent = selectedColor.value;
} else if (colorTarget.value === 'accent2') { } else if (colorTarget.value === 'menu') {
accent2Color.value = selectedColor.value; props.user.profileColors.menu = selectedColor.value;
} }
showColorPicker.value = false; showColorPicker.value = false;
}; };

View File

@@ -23,10 +23,9 @@
<script setup> <script setup>
import {defineProps, ref} from 'vue'; import {defineProps, ref} from 'vue';
import SocialNetworksModel from "@/models/socialNetworksModel.js";
const props = defineProps({ const props = defineProps({
socialNetworks: { type: SocialNetworksModel }, socialNetworks: { type: Object },
}); });
const socialNetworks = ref([ const socialNetworks = ref([

View File

@@ -47,10 +47,8 @@
<script async setup> <script async setup>
import { onBeforeMount, ref, computed } from 'vue'; import { onBeforeMount, ref, computed } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useClient } from "@/plugins/api.js";
import {useUserStore} from "@/stores/user.js"; import {useUserStore} from "@/stores/user.js";
const client = useClient();
const userStore = useUserStore(); const userStore = useUserStore();
const router = useRouter(); const router = useRouter();
@@ -74,11 +72,17 @@ const formattedBalance = computed(() => {
const transactionCount = computed(() => userTransactions.value.length); const transactionCount = computed(() => userTransactions.value.length);
onBeforeMount(async () => { onBeforeMount( () => {
try { try {
const myUser = await userStore.getCurrentUser(client); const myUser = userStore.getCurrentUser();
userTransactions.value = myUser.userTransactions; userTransactions.value = myUser.userTransactions;
totalBalance.value = myUser.totalBalance; totalBalance.value = myUser.totalBalance;
console.log(userTransactions.value);
console.log(totalBalance.value);
console.log(formattedTransactions);
console.log(formattedBalance);
} catch (error) { } catch (error) {
navigateToHome(); navigateToHome();
} }