Files
classroomio/src/routes/profile/[id]/+page.svelte
T

224 lines
6.7 KiB
Svelte
Raw Normal View History

2021-08-18 19:47:02 +03:00
<script>
import { goto } from '$app/navigation';
import UserAvatarIcon from 'carbon-icons-svelte/lib/UserAvatar.svelte';
import BookIcon from 'carbon-icons-svelte/lib/Book.svelte';
import TextField from '$lib/components/Form/TextField.svelte';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
import UploadImage from '$lib/components/UploadImage/index.svelte';
import { supabase } from '$lib/utils/functions/supabase';
import { user, profile } from '$lib/utils/store/user';
2021-08-18 19:47:02 +03:00
export let data;
const { profileId } = data;
2021-08-18 19:47:02 +03:00
2021-08-26 13:35:56 +03:00
let avatar;
2021-08-18 19:47:02 +03:00
let loading = false;
let currentProfile = {};
let isOwner = false;
2021-08-26 13:35:56 +03:00
let initialValueOfUserName, initialValueOfFullName, initialValueOfAvatar;
2021-08-18 19:47:02 +03:00
async function getProfile(profileId) {
loading = true;
// Get user profile
// Check if user has profile
let {
data: profileData,
error,
2023-08-05 04:44:32 +01:00
status
2021-08-18 19:47:02 +03:00
} = await supabase.from('profile').select(`*`).eq('id', profileId).single();
if (error && !profileData && status === 406 && $user.currentSession) {
// Not found
} else if (profileData) {
// Profile exists, go to profile page
currentProfile = profileData;
initialValueOfUserName = currentProfile.username;
initialValueOfFullName = currentProfile.fullname;
}
loading = false;
}
async function updateProfile() {
try {
loading = true;
const updates = {
fullname: currentProfile.fullname,
2023-08-05 04:44:32 +01:00
username: currentProfile.username
2021-08-18 19:47:02 +03:00
};
2021-08-26 13:35:56 +03:00
if (avatar) {
const filename = `user/${currentProfile.username + Date.now()}.webp`;
2023-08-05 04:44:32 +01:00
const { data } = await supabase.storage.from('avatars').upload(filename, avatar, {
cacheControl: '3600',
upsert: false
});
2021-08-26 13:35:56 +03:00
if (data && data.Key) {
2023-08-05 04:44:32 +01:00
const { publicURL } = supabase.storage.from('avatars').getPublicUrl(filename);
2021-08-26 13:35:56 +03:00
updates.avatar_url = publicURL;
2021-09-11 22:15:15 +03:00
currentProfile.avatar_url = publicURL;
2021-08-26 13:35:56 +03:00
}
avatar = undefined;
}
2023-08-05 04:44:32 +01:00
let { error } = await supabase.from('profile').update(updates).match({ id: profileId });
2021-08-18 19:47:02 +03:00
2021-08-26 13:35:56 +03:00
if (isOwner) {
profile.update((_profile) => ({
..._profile,
2023-08-05 04:44:32 +01:00
...updates
2021-08-26 13:35:56 +03:00
}));
}
2021-08-18 19:47:02 +03:00
if (error) throw error;
} catch (error) {
alert(error.message);
loading = false;
} finally {
loading = false;
initialValueOfUserName = currentProfile.username;
initialValueOfFullName = currentProfile.fullname;
}
}
2022-11-26 21:09:57 +01:00
async function logout() {
const { error } = await supabase.auth.signOut();
console.log('error logout', error);
goto('/login');
}
2021-09-11 22:15:15 +03:00
$: isDirty =
avatar ||
initialValueOfUserName !== currentProfile.username ||
initialValueOfFullName !== currentProfile.fullname;
2021-08-18 19:47:02 +03:00
$: isOwner = $profile.id === profileId;
2021-08-26 13:35:56 +03:00
$: getProfile(profileId);
2021-09-11 22:15:15 +03:00
$: if (avatar) {
updateProfile();
}
2021-08-18 19:47:02 +03:00
</script>
<svelte:head>
<title>Profile of {currentProfile.username}</title>
</svelte:head>
2023-08-05 04:44:32 +01:00
<section class="root w-11/12 mt-3 m-auto flex items-start justify-between flex-col lg:flex-row">
2021-08-18 19:47:02 +03:00
{#if currentProfile.id}
2021-09-17 06:33:49 +03:00
<div class="w-full lg:w-1/4 flex items-center flex-col">
2021-08-26 13:35:56 +03:00
<!-- <img
2021-08-18 19:47:02 +03:00
alt={currentProfile.username}
src={currentProfile.avatar_url}
height="260"
width="260"
class="rounded-full bg-light-blue-100 mb-4"
2021-08-26 13:35:56 +03:00
/> -->
2023-08-05 04:44:32 +01:00
<UploadImage bind:avatar src={currentProfile.avatar_url} widthHeight="w-60 h-60" />
2021-08-18 19:47:02 +03:00
{#if isOwner}
<TextField
label="Full name"
bind:value={currentProfile.fullname}
className="w-60 mb-4"
inputClassName="rounded-md"
/>
<TextField
label="Username"
bind:value={currentProfile.username}
className="w-60 mb-4"
inputClassName="rounded-md"
/>
2021-08-28 22:44:06 +03:00
<TextField
label="Email"
bind:value={currentProfile.email}
className="w-60 mb-4"
inputClassName="rounded-md"
isDisabled={true}
/>
2021-08-18 19:47:02 +03:00
2021-09-11 22:15:15 +03:00
{#if isDirty}
2021-08-18 19:47:02 +03:00
<PrimaryButton
label={loading ? 'Updating...' : 'Update profile'}
onClick={updateProfile}
isDisabled={loading}
/>
{/if}
{:else}
<h3 class="dark:text-white text-xl">{currentProfile.username}</h3>
2021-08-18 19:47:02 +03:00
{/if}
</div>
<div class="flex-grow" />
<div class="flex-grow flex flex-wrap mx-3 w-3/5">
<div class="mb-3 w-full">
<h3 class="dark:text-white font-bold text-md m-0">Organizations</h3>
2023-08-05 04:44:32 +01:00
<p class="dark:text-white text-gray-500 text-sm">This are the organizations you work at</p>
2021-08-18 19:47:02 +03:00
<div class="hidden my-3 py-3 px-4 border shadow-sm rounded-md">
<h4 class="dark:text-white m-0 font-normal">
2021-08-18 19:47:02 +03:00
<a class="text-blue-700 font-bold" href="/courses"> CitiBim </a>
</h4>
2023-05-20 23:53:28 +00:00
<p class="dark:text-white text-gray-500">
2023-08-05 04:44:32 +01:00
Lorem ipsum dolor sit amet consectetur adipisicing elit. Non aliquam tenetur magnam.
Alias cumque quaerat expedita dolores placeat laboriosam culpa, suscipit veritatis
adipisci eius magni obcaecati. Sequi doloremque blanditiis earum.
2021-08-18 19:47:02 +03:00
</p>
<div class="mt-2 flex items-center">
<span class="flex mr-2 items-center">
<UserAvatarIcon size={16} class="mr-2" /> 5
2021-08-18 19:47:02 +03:00
</span>
<span class="flex mr-2 items-center">
<BookIcon size={16} class="mr-2" /> 5
2021-08-18 19:47:02 +03:00
</span>
</div>
</div>
<div class="hidden my-2 py-3 px-4 border shadow-sm rounded-md">
<h4 class="dark:text-white m-0 font-normal">
2023-08-05 04:44:32 +01:00
<a class="text-blue-700 font-bold" href="/courses"> Climate Change Group </a>
2021-08-18 19:47:02 +03:00
</h4>
2023-05-20 23:53:28 +00:00
<p class="dark:text-white text-gray-500">
2023-08-05 04:44:32 +01:00
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo quasi autem quo possimus
illum consequuntur repudiandae nobis error, porro
2021-08-18 19:47:02 +03:00
</p>
<div class="mt-2 flex items-center">
<span class="flex mr-2 items-center">
<UserAvatarIcon size={16} class="mr-2" /> 30
2021-08-18 19:47:02 +03:00
</span>
<span class="flex mr-2 items-center">
<BookIcon size={16} class="mr-2" /> 3
2021-08-18 19:47:02 +03:00
</span>
</div>
</div>
</div>
2023-08-05 04:44:32 +01:00
<PrimaryButton variant={VARIANTS.CONTAINED_DANGER} label="Log out" onClick={logout} />
2021-08-18 19:47:02 +03:00
</div>
<!-- {:else if loading}
<Box>
<Chasing size="60" color="#ff3e00" unit="px" duration="1s" />
</Box>
{:else}
<Box>
<div>
<Search32 />
</div>
<h3 class="dark:text-white text-xxl">Profile not found</h3>
2021-08-18 19:47:02 +03:00
</Box> -->
{/if}
</section>
<style>
.root {
max-width: 1204px;
}
</style>