Skip to content
Snippets Groups Projects
Commit ae325e33 authored by Jakob Karevold Grønhaug's avatar Jakob Karevold Grønhaug
Browse files

Merge branch 'opprett-profil' into 'main'

all funksjonalitet og filopplasting på plass

See merge request !15
parents c2b3b8f4 6c058628
No related branches found
No related tags found
1 merge request!15all funksjonalitet og filopplasting på plass
Pipeline #224186 passed
...@@ -5,128 +5,152 @@ import router from "@/router/index"; ...@@ -5,128 +5,152 @@ import router from "@/router/index";
export const API = { export const API = {
/** /**
* API method to send a login request. * API method to send a login request.
* If login succeeds, the logged in User and their token * If login succeeds, the logged in User and their token
* is saved to the Pinia AuthStore * is saved to the Pinia AuthStore
* *
* @param email email address of the user to log in as * @param email email address of the user to log in as
* @param password password to log in with * @param password password to log in with
* @returns a Result with whether the login attempt succeeded * @returns a Result with whether the login attempt succeeded
*/ */
login: async (request) => { login: async (request) => {
const authStore = useAuthStore(); const authStore = useAuthStore();
let token; let token;
authStore.logout(); //in case someone for some reason is logged in authStore.logout(); //in case someone for some reason is logged in
return axios.post(
`${import.meta.env.VITE_BACKEND_URL}/login`,
request,
)
.then(async (response) => {
token = response.data;
const id = (jwt_decode(token)).id;
return API.getAccount(id, token)
.then((user) => {
authStore.setAccount(user);
authStore.setToken(token);
API.getProfiles()
.then(response => {authStore.setProfiles(response)})
.catch(() => {throw new Error()})
return;
})
.catch(() => {
throw new Error();
});
})
.catch(() => {
throw new Error();
});
},
return axios.post(
`${import.meta.env.VITE_BACKEND_URL}/login`,
request,
)
.then(async (response) => {
token = response.data;
const id = (jwt_decode(token)).id;
/** return API.getAccount(id, token)
* API method to get a account by their ID .then((user) => {
* @param id ID number of the account to retrieve authStore.setAccount(user);
* @returns A promise that resolves to a User if the API call succeeds, authStore.setToken(token);
* or is rejected if the API call fails API.getProfiles()
*/ .then(response => { authStore.setProfiles(response) })
getAccount: async (id, token) => { .catch(() => { throw new Error() })
return axios.get(`${import.meta.env.VITE_BACKEND_URL}/account/${id}`, { return;
headers: { Authorization: `Bearer ${token}` },
})
.then((response) => {
return response.data;
}) })
.catch(() => { .catch(() => {
throw new Error("Account not found or not accessible"); throw new Error();
}); });
}, })
.catch(() => {
throw new Error();
});
},
// Sends the user into the home page logged in as the profile they clicked on
selectProfile: async (id) => {
const authStore = useAuthStore()
return axios.get(`${import.meta.env.VITE_BACKEND_URL}/profile/${id}`, {
headers: { Authorization: `Bearer ${authStore.token}` },
})
.then((response) => {
authStore.setProfile(response.data)
router.push("/")
}) /**
.catch(() => { * API method to get a account by their ID
throw new Error("Profile not found or not accessible") * @param id ID number of the account to retrieve
}) * @returns A promise that resolves to a User if the API call succeeds,
* or is rejected if the API call fails
*/
getAccount: async (id, token) => {
return axios.get(`${import.meta.env.VITE_BACKEND_URL}/account/${id}`, {
headers: { Authorization: `Bearer ${token}` },
})
.then((response) => {
return response.data;
})
.catch(() => {
throw new Error("Account not found or not accessible");
});
},
// Sends the user into the home page logged in as the profile they clicked on
selectProfile: async (id) => {
const authStore = useAuthStore()
return axios.get(`${import.meta.env.VITE_BACKEND_URL}/profile/${id}`, {
headers: { Authorization: `Bearer ${authStore.token}` },
})
.then((response) => {
authStore.setProfile(response.data)
router.push("/")
}, })
.catch(() => {
throw new Error("Profile not found or not accessible")
})
},
/** /**
* Sends a request to create a new profile on the currently logged in account * Upload profile image
* *
* @typedef {{name: string, profileImageUrl: string, isRestricted: boolean}} ProfileType * @param {Blob} image - the image file contents to upload. Must be a JPEG no bigger than 512kB
* @param {ProfileType} profile * @param {Number} profileId - the ID of the profile to upload this image to
* @returns * @returns {Promise<String>} A Promise that resolves to the URL of the uploaded image
*/ */
addProfile: async (profile) => { uploadProfileImage: async (image, profileId) => {
const authStore = useAuthStore(); const authStore = useAuthStore();
if (!authStore.isLoggedIn) {
throw new Error(); let fd = new FormData();
} fd.append("file", image);
fd.append("profileId", profileId);
return axios.post(import.meta.env.VITE_BACKEND_URL + '/profile', { return axios.post(`${import.meta.env.VITE_BACKEND_URL}/img`, fd, {
headers: { Authorization: "Bearer " + authStore.token }, headers: {
body: profile Authorization: `Bearer ${authStore.token}`,
}
})
.then((response) => {
return response.data;
})
.catch(() => {
throw new Error();
}) })
},
/**
* Sends a request to create a new profile on the currently logged in account
*
* @typedef {{name: string, id?: number, accountId?: number, profileImageUrl: string, isRestricted: boolean}} ProfileType
* @param {ProfileType} profile - the partial data of profile to create
* @returns {Promise<ProfileType>} the full profile after saving, with id and account ID set
*/
addProfile: async (profile) => {
const authStore = useAuthStore();
if (!authStore.isLoggedIn) {
throw new Error();
}
return axios.post(import.meta.env.VITE_BACKEND_URL + '/profile', profile, {
headers: { Authorization: "Bearer " + authStore.token },
})
.then((response) => { .then((response) => {
return response.data; return response.data;
}).catch(() => { }).catch(() => {
throw new Error(); throw new Error();
}) })
}, },
// Returns all profiles to the logged in user // Returns all profiles to the logged in user
getProfiles: async () => { getProfiles: async () => {
const authStore = useAuthStore(); const authStore = useAuthStore();
if (!authStore.isLoggedIn) { if (!authStore.isLoggedIn) {
throw new Error(); throw new Error();
} }
return axios.get(import.meta.env.VITE_BACKEND_URL + '/profile', { return axios.get(import.meta.env.VITE_BACKEND_URL + '/profile', {
headers: { Authorization: "Bearer " + authStore.token }, headers: { Authorization: "Bearer " + authStore.token },
},
)
.then(response => {
return response.data
}).catch(() => {
throw new Error();
});
}, },
)
.then(response => {
return response.data
}).catch(() => {
throw new Error();
});
},
// Registers a new account and logs into it // Registers a new account and logs into it
addAccount: async (request) => { addAccount: async (request) => {
const authStore = useAuthStore(); const authStore = useAuthStore();
axios.post(import.meta.env.VITE_BACKEND_URL + '/account', request) axios.post(import.meta.env.VITE_BACKEND_URL + '/account', request)
.then(() => { .then(() => {
......
<script> <script>
import Toggle from '../components/Toggle.vue'; import { mapStores } from 'pinia';
import router from '../router'
import { API } from '../util/API'; import { API } from '../util/API';
import { useAuthStore } from '../stores/authStore'
export default { export default {
data: () => { data: () => {
...@@ -14,20 +16,33 @@ export default { ...@@ -14,20 +16,33 @@ export default {
}; };
}, },
methods: { methods: {
submit() { async submit() {
this.profile.isRestricted = this.$refs.toggle.state; await API.addProfile(this.profile)
API.addProfile(this.profile); .then((profile) => {
let id = profile.id;
let image = document.getElementById("profile_img").files[0];
API.uploadProfileImage(image, id)
.then((updatedProfile) => {
this.authStore.profile = updatedProfile;
router.push("/");
});
})
}, },
updateImg() { updateImg() {
let file = document.getElementById("avatar").files[0]; let file = document.getElementById("profile_img").files[0];
let reader = new FileReader(); let reader = new FileReader();
reader.onload = function (ev) { reader.onload = function (ev) {
document.getElementById("avatar_preview").src = ev.target.result; document.getElementById("profile_img_preview").src = ev.target.result;
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
}, },
components: { Toggle } computed: {
...mapStores(useAuthStore)
}
} }
</script> </script>
...@@ -36,20 +51,21 @@ export default { ...@@ -36,20 +51,21 @@ export default {
<h1>Ny profil</h1> <h1>Ny profil</h1>
<form action="todo" method="post"> <form action="todo" method="post">
<label for="avatar" id="avatar_label"> <label for="profile_img" id="profile_img_label">
<div class="img_hover"> <div class="img_hover">
<img :src="image" alt="fjes" id="avatar_preview"> <img :src="image" alt="fjes" id="profile_img_preview">
<p class="hover_text"> <p class="hover_text">
Klikk for å endre Klikk for å endre
</p> </p>
</div> </div>
</label> </label>
<input type="file" name="avatar" id="avatar" @change="updateImg"> <input @change="updateImg" type="file"
accept=".jpeg, .jpg" id="profile_img" name="profile_img">
<label for="name">Navn</label> <label for="name">Navn</label>
<input name="name" type="text" v-model="profile.name"> <input name="name" type="text" v-model="profile.name">
<div class="check_container"> <div class="check_container">
<label for="child">Begrenset:</label> <label for="limited">Begrenset:</label>
<Toggle ref="toggle" /> <input type="checkbox" name="limited" id="limited">
</div> </div>
</form> </form>
<button @click="submit">Opprett</button> <button @click="submit">Opprett</button>
...@@ -84,7 +100,7 @@ main { ...@@ -84,7 +100,7 @@ main {
} }
} }
#avatar_label { #profile_img_label {
display: flex; display: flex;
justify-content: center; justify-content: center;
width: 100%; width: 100%;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment