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

all funksjonalitet og filopplasting på plass

parent 930313f7
No related branches found
No related tags found
1 merge request!15all funksjonalitet og filopplasting på plass
Pipeline #224155 failed
...@@ -5,134 +5,158 @@ import router from "@/router/index"; ...@@ -5,134 +5,158 @@ 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( return axios.post(
`${import.meta.env.VITE_BACKEND_URL}/login`, `${import.meta.env.VITE_BACKEND_URL}/login`,
request, request,
) )
.then(async (response) => { .then(async (response) => {
token = response.data; token = response.data;
const id = (jwt_decode(token)).id; const id = (jwt_decode(token)).id;
return API.getAccount(id, token) return API.getAccount(id, token)
.then((user) => { .then((user) => {
authStore.setAccount(user); authStore.setAccount(user);
authStore.setToken(token); authStore.setToken(token);
API.getProfiles() API.getProfiles()
.then(response => {authStore.setProfiles(response)}) .then(response => { authStore.setProfiles(response) })
.catch(() => {throw new Error()}) .catch(() => { throw new Error() })
return; return;
})
.catch(() => {
throw new Error();
});
})
.catch(() => {
throw new Error();
});
},
/**
* API method to get a account by their ID
* @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(() => { .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(() => {
throw new Error("Profile not found or not accessible")
})
/**
* API method to get a account by their ID
* @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("/")
/** })
* Sends a request to create a new profile on the currently logged in account .catch(() => {
* throw new Error("Profile not found or not accessible")
* @typedef {{name: string, profileImageUrl: string, isRestricted: boolean}} ProfileType })
* @param {ProfileType} profile },
* @returns
*/ /**
addProfile: async (profile) => { * Upload profile image
const authStore = useAuthStore(); *
if (!authStore.isLoggedIn) { * @param {Blob} image - the image file contents to upload. Must be a JPEG no bigger than 512kB
throw new Error(); * @param {Number} profileId - the ID of the profile to upload this image to
} * @returns {Promise<String>} A Promise that resolves to the URL of the uploaded image
*/
uploadProfileImage: async (image, profileId) => {
const authStore = useAuthStore();
return axios.post(import.meta.env.VITE_BACKEND_URL + '/profile', { let fd = new FormData();
headers: { Authorization: "Bearer " + authStore.token }, fd.append("file", image);
body: profile fd.append("profileId", profileId);
return axios.post(`${import.meta.env.VITE_BACKEND_URL}/img`, fd, {
headers: {
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(() => {
API.login({email: request.email, password: request.password}) API.login({ email: request.email, password: request.password })
.catch(err => {console.log(err)}) .catch(err => { console.log(err) })
}) })
.catch(() => {throw new Error()}) .catch(() => { throw new Error() })
} }
} }
\ No newline at end of file
<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