Files
classroomio/apps/dashboard/src/routes/profile/[id]/+page.svelte
T
9c066c79be feat: [lw] free tools (#297)
* checkpoint

* checkpoint

* feat: Create free tools page

* responsiveness fix

* rename free-tools to tools

* add slug

* feat: Random name picker

* quick fix

* PR Fixes

* PR Fixes

* - adjustments

* update env example

* remove base url

* remove base url in .env.example

* fix type errors

* add og images

* add signup cta to /tools layout

* update cta

* add socials avatar

* add meta tags

* feat: tic tac toe (#307)

* Feat: tic tac toe

* PR Adjustments

* feat: Implement Timed Activity Tool (#316)

* chore: update verification email content

* chore: landing page improvements

* feat: grade exercise with AI (#296)

* working on the UI of the grading

* working on the grading function of the radio and checkboxes

* ai grading fully implemented with dummy functions for generating scores

* working on the openai response

* working on the openai response

* finished with the ai_grading

* finished with the ai_grading

* creating new migration file

* working on reviews

* updated the translations

* improvements

---------

Co-authored-by: Rotimi Best <[email protected]>

* feat: selfhost tinymce

* fix: logo resolution error in manifest.json

* feat: move from gpt3.5 to gpt-4o

* feat: customize the LMS from dashboard (#304)

* Done with the customization of the LMS task

* generated custom_lms migration file

* updated the migration file

* copy improvements

* update wording

* made updates based on reviews,i hope i didnt miss anything

* updated the translations and migration files

* refactoring

* disabled improvements for apps

* more improvements

* more custom improvements

* pr refactoring

---------

Co-authored-by: Rotimi Best <[email protected]>

* fix: CustomizeLMS not found

* fix: CustomizeLms wrong path

* setup

* docs: update short hero tagline

* debug: courses not showing on vercel

* more debugging

* i think this fixes it

* fix: phew, clean up debug cause it works

* fix: move RBS into coursecontainer on marks page

* chore: cleaner way to implement redirect if role permission denied

* docs: update tagline

* fix: delete /org/# route

* checkpoint

* add reusable header component

* fix: empty lesson title bug (#314)

* finished the lesson title bug

* made chnages based on review

* Update +page.svelte

---------

Co-authored-by: Rotimi Best <[email protected]>

* feat: add sound cdn

* remove console.log

* feat: course types - self paced and live class (#309)

* working on the course type

* trying to mark it persist

* almost done here

* fixed sendig emtpy options bug

* created migration file

* created migration file

* made updates based on PR review

* merge

* update course type card

* add redirect logic with classroomio.com/new

* make new course modal only open/close with url

* feat: page active state (#315)

* finished the active link state

* updated the active link state based on review

* simplify code

---------

Co-authored-by: Rotimi Best <[email protected]>

* add type to course card

---------

Co-authored-by: Rotimi Best <[email protected]>

* general improvements to free tools

* fix timer and styling issues

---------

Co-authored-by: Rotimi Best <[email protected]>
Co-authored-by: Em_Dev <[email protected]>

* update tagline for tools page

* feat: Add Free Section to Landing Page (#332)

* feat: Add Free Section to Landing Page

* PR Fixes

* refactor

* PR Fixes

* restructure

* improve cursor UX

---------

Co-authored-by: Rotimi Best <[email protected]>

* feat: Progress Report Tool (#329)

* checkpoint

* fix: corrections

* finalization

* improve ux of progress tool

* more styling improvements

* PR Fixes

* PR Fixes

* fix: mood bg on report

* fix: generate exercise with AI bug (#331)

* fix: enable lesson cascade delete (#335)

* styling improvements

* chore: hide course grading toggle in settings (#338)

* feat: reset select in community page (#339)

* Feat: Add Reset for comminity dropdown

* - add translation

* refactor

---------

Co-authored-by: Rotimi Best <[email protected]>

* fix: prevent hypen at start or end of organzation or domain name (#340)

* fix: adding hypen to start or end of org or domain name

* fix: add org name validation to settings page

* chore: remove unnecessary variable use

* chore: remove error reset function

* Update OrgSettings.svelte

---------

Co-authored-by: Rotimi Best <[email protected]>

* fix: full screen

* fix: pnpm version error & add top level .nvmrc (#343)

* update name of tool

* chore: add translations for validation messages (#345)

* chore: add validation texts to locale file

* feat: switch all validations from plain text to use i18n locale

* feat: switch review form validations from plain text to use locale file

* run translation script

* chore: add translations for validation messages (#345) (#347)

* chore: add translations for validation messages (#345)

* chore: add validation texts to locale file

* feat: switch all validations from plain text to use i18n locale

* feat: switch review form validations from plain text to use locale file

* run translation script

---------

Co-authored-by: Iniubong Obonguko <[email protected]>

* PR Fixes

* Bug fixes on mobile

* Final bug fix

* code improvements

* PR Fixes

* Merge Fix

* PR Fixes

* fix: width

* code cleanup

* feat: Promodo Tool (tracks tim spent)

* feat: Pomodoro timer (without tracking feature)

* fix:
- change pause functionality to next
- correct spelling of pomodoro

* fix: pomodoro logo rename

* styling improvements

---------

Co-authored-by: Rotimi Best <[email protected]>
Co-authored-by: Em_Dev <[email protected]>
Co-authored-by: Iniubong Obonguko <[email protected]>
Co-authored-by: Iniubong Obonguko <[email protected]>
Co-authored-by: Aditya Deshlahre <[email protected]>

* feat: Implement Bottom menu (#341)

* popup logic done

* popup UI first phase done

* finished the menupop up for both lms and admin

* finished the menupop up for both lms and admin

* done

* cleanup

* fixed popover position

* still working on the routing

* i think that is it for the day

* updated the menupopup currentorgdomain

* rename popup to bottomMenu

* refactoring

---------

Co-authored-by: Rotimi Best <[email protected]>

* remove logout

* change tagline

* feat: Store todolist to localStorage (#375)

* feat: Save todo to localStorage

* remove fly animation to todos

* feat:  Progress Report avatar update (#376)

* feat: Reorder Avatar list

* quick fix

* change avatar url

* more improvements

* quick background fix

* fix: white background

* body background fix

* update lock

---------

Co-authored-by: Rotimi Best <[email protected]>
Co-authored-by: Em_Dev <[email protected]>
Co-authored-by: Iniubong Obonguko <[email protected]>
Co-authored-by: Iniubong Obonguko <[email protected]>
Co-authored-by: Aditya Deshlahre <[email protected]>
2024-09-30 01:36:12 +01:00

215 lines
6.4 KiB
Svelte

<script>
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 UploadImage from '$lib/components/UploadImage/index.svelte';
import { supabase } from '$lib/utils/functions/supabase';
import { user, profile } from '$lib/utils/store/user';
export let data;
const { profileId } = data;
let avatar;
let loading = false;
let currentProfile = {};
let isOwner = false;
let initialValueOfUserName, initialValueOfFullName, initialValueOfAvatar;
async function getProfile(profileId) {
loading = true;
// Get user profile
// Check if user has profile
let {
data: profileData,
error,
status
} = 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,
username: currentProfile.username
};
if (avatar) {
const filename = `user/${currentProfile.username + Date.now()}.webp`;
const { data } = await supabase.storage.from('avatars').upload(filename, avatar, {
cacheControl: '3600',
upsert: false
});
if (data) {
const { data: response } = supabase.storage.from('avatars').getPublicUrl(filename);
updates.avatar_url = response.publicUrl;
currentProfile.avatar_url = response.publicUrl;
}
avatar = undefined;
}
let { error } = await supabase.from('profile').update(updates).match({ id: profileId });
if (isOwner) {
profile.update((_profile) => ({
..._profile,
...updates
}));
}
if (error) throw error;
} catch (error) {
alert(error.message);
loading = false;
} finally {
loading = false;
initialValueOfUserName = currentProfile.username;
initialValueOfFullName = currentProfile.fullname;
}
}
$: isDirty =
avatar ||
initialValueOfUserName !== currentProfile.username ||
initialValueOfFullName !== currentProfile.fullname;
$: isOwner = $profile.id === profileId;
$: getProfile(profileId);
$: if (avatar) {
updateProfile();
}
</script>
<svelte:head>
<title>Profile of {currentProfile.username}</title>
</svelte:head>
<section class="root w-11/12 mt-3 m-auto flex items-start justify-between flex-col lg:flex-row">
{#if currentProfile.id}
<div class="w-full lg:w-1/4 flex items-center flex-col">
<!-- <img
alt={currentProfile.username}
src={currentProfile.avatar_url}
height="260"
width="260"
class="rounded-full bg-primary-100 mb-4"
/> -->
<UploadImage bind:avatar src={currentProfile.avatar_url} widthHeight="w-60 h-60" />
{#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"
/>
<TextField
label="Email"
bind:value={currentProfile.email}
className="w-60 mb-4"
inputClassName="rounded-md"
isDisabled={true}
/>
{#if isDirty}
<PrimaryButton
label={loading ? 'Updating...' : 'Update profile'}
onClick={updateProfile}
isDisabled={loading}
/>
{/if}
{:else}
<h3 class="dark:text-white text-xl">{currentProfile.username}</h3>
{/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>
<p class="dark:text-white text-gray-500 text-sm">This are the organizations you work at</p>
<div class="hidden my-3 py-3 px-4 border shadow-sm rounded-md">
<h4 class="dark:text-white m-0 font-normal">
<a class="text-primary-700 font-bold" href="/courses"> CitiBim </a>
</h4>
<p class="dark:text-white text-gray-500">
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.
</p>
<div class="mt-2 flex items-center">
<span class="flex mr-2 items-center">
<UserAvatarIcon size={16} class="mr-2" /> 5
</span>
<span class="flex mr-2 items-center">
<BookIcon size={16} class="mr-2" /> 5
</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">
<a class="text-primary-700 font-bold" href="/courses"> Climate Change Group </a>
</h4>
<p class="dark:text-white text-gray-500">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo quasi autem quo possimus
illum consequuntur repudiandae nobis error, porro
</p>
<div class="mt-2 flex items-center">
<span class="flex mr-2 items-center">
<UserAvatarIcon size={16} class="mr-2" /> 30
</span>
<span class="flex mr-2 items-center">
<BookIcon size={16} class="mr-2" /> 3
</span>
</div>
</div>
</div>
</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>
</Box> -->
{/if}
</section>
<style>
.root {
max-width: 1204px;
}
</style>