Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into feed
  • Loading branch information
lisaress committed Jan 18, 2024
2 parents 7026c0d + fdf82fc commit e61fe92
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 86 deletions.
3 changes: 3 additions & 0 deletions src/lib/types/User.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { UUID } from 'crypto';

export type User = {
username: string;
nickname: string;
Expand All @@ -6,6 +8,7 @@ export type User = {
follower: number;
following: number;
posts: number;
subscriptionId: UUID | string;
};

export type UserFetchResponse = {
Expand Down
219 changes: 136 additions & 83 deletions src/routes/profile/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,30 @@
import type { UserPostFetchResponse } from '$lib/types/Post';
import PostUserProfil from '../../components/PostUserProfil.svelte';
import { onMount } from 'svelte';
import { getProfileDetails, getProfilePosts, loadPosts, updateUserDetails } from './requests';
import {
followUser,
getProfileDetails,
getProfilePosts,
loadPosts,
unfollowUser,
updateUserDetails
} from './requests';
import { get } from 'svelte/store';
import { token } from '$lib/Store';
import type { UserFetchResponse } from '$lib/types/User';
import Icon from '@iconify/svelte';
import ModalChangePwd from '../../components/modals/ModalChangePwd.svelte';
import { t } from '../../i18n';
// import { page } from '$app/stores';
import { createToast } from '$lib/Toasts';
let editMode: boolean = false;
let nickname: string = '';
let userStatus: string = '';
let maxPostCounter: number = 0;
// let username: string = '';
let username: string = '';
let usernameParams: string = '';
let subscribed: boolean = false;
const toastStore = getToastStore();
Expand All @@ -53,7 +61,8 @@
profilePictureUrl: '',
follower: 0,
following: 0,
posts: 0
posts: 0,
subscriptionId: ''
},
statusCode: 0
};
Expand All @@ -68,16 +77,25 @@
};
onMount(async () => {
// const url = $page.route;
profileData = await getProfileDetails(get(token), 'mabu2807');
nickname = profileData.user.nickname;
userStatus = profileData.user.status;
const url = window.location.search;
usernameParams = url.split('=')[1];
if (usernameParams == undefined) {
username = 'mabu2807';
} else {
username = usernameParams;
}
profileData = await getProfileDetails(get(token), username);
if (profileData.statusCode == 500) {
toastStore.trigger(createToast('User details could not be loaded', 'error'));
}
nickname = profileData.user.nickname;
userStatus = profileData.user.status;
if (profileData.user.subscriptionId != '') {
subscribed = true;
}
postData = await getProfilePosts(get(token), 'mabu2807');
postData = await getProfilePosts(get(token), username);
maxPostCounter = postData.pagination.limit;
});
Expand All @@ -99,89 +117,124 @@
}
async function loadMorePosts() {
postData = await loadPosts(get(token), postData, 'mabu2807');
console.log('MaxPostCounter: ' + maxPostCounter);
maxPostCounter = Number(maxPostCounter) + Number(postData.pagination.limit);
console.log('MaxPostCounter: ' + maxPostCounter);
console.log('Postdata: ' + postData.records.length);
}
async function subscribe() {
const followStatus = await followUser(get(token), profileData.user.subscriptionId);
if (followStatus == 200) {
subscribed = true;
toastStore.trigger(createToast('User was followed', 'success'));
} else {
toastStore.trigger(createToast('User was not followed', 'error'));
}
}
async function unsubscribe() {
const unfollowStatus = await unfollowUser(get(token), profileData.user.subscriptionId);
if (unfollowStatus == 200) {
subscribed = false;
toastStore.trigger(createToast('User was unfollowed', 'success'));
} else {
toastStore.trigger(createToast('User was not unfollowed', 'error'));
}
}
</script>

<Toast />
<Modal />
<main class=" flex flex-col items-center justify-start">
<div
class=" w-full h-[35vh] flex flex-row justify-center items-center border-b-4 border-indigo-800"
>
<div class="h-[20vh] w-[20vh] rounded-full">
<Avatar class="w-full h-full" src={profileData.user.profilePictureUrl} initials="" />
</div>
<div class="h-[20vh] w-[50vw] p-6">
<div class="flex col-row">
<h3 class="h3 mr-4">{profileData.user.username}</h3>
{#if editMode == true}
<button on:click={handleDetailSubmit} class=""
><Icon class="w-7 h-7" icon="material-symbols:save-outline"></Icon></button
>
<button on:click={changeEditMode} class="ml-2"
><Icon class="w-7 h-7" icon="material-symbols:cancel-outline"></Icon></button
>
{#if profileData.statusCode == 200}
<main class=" flex flex-col items-center justify-start">
<div
class=" w-full h-[35vh] flex flex-row justify-center items-center border-b-4 border-indigo-800"
>
<div class="h-[20vh] w-[20vh] rounded-full">
<Avatar class="w-full h-full" src={profileData.user.profilePictureUrl} initials="" />
</div>
<div class="h-[20vh] w-[50vw] p-6">
<div class="flex col-row">
<h3 class="h3 mr-4">{profileData.user.username}</h3>
{#if usernameParams == undefined}
{#if editMode == true}
<button on:click={handleDetailSubmit} class=""
><Icon class="w-7 h-7" icon="material-symbols:save-outline"></Icon></button
>
<button on:click={changeEditMode} class="ml-2"
><Icon class="w-7 h-7" icon="material-symbols:cancel-outline"></Icon></button
>
{:else}
<button on:click={changeEditMode} class="">
<Icon class="w-7 h-7" icon="material-symbols:edit-outline"></Icon></button
>
{/if}
{/if}
</div>
{#if editMode}
<input
bind:value={nickname}
class="mb-4 input w-[15vw]"
type="text"
placeholder="new nickname"
/>
<textarea
bind:value={userStatus}
maxlength="128"
class="textarea"
placeholder="new Status"
/>
{:else}
<button on:click={changeEditMode} class="">
<Icon class="w-7 h-7" icon="material-symbols:edit-outline"></Icon></button
>
<p class="opacity-70 mb-4">{nickname}</p>
<p>{userStatus}</p>
{/if}
</div>
{#if editMode}
<input
bind:value={nickname}
class="mb-4 input w-[15vw]"
type="text"
placeholder="new nickname"
/>
<textarea
bind:value={userStatus}
maxlength="128"
class="textarea"
placeholder="new Status"
/>
{:else}
<p class="opacity-70 mb-4">{nickname}</p>
<p>{userStatus}</p>
{/if}
</div>
<div class="h-[20vh] w-[22vw] flex flex-row justify-around items-center">
<div class="flex flex-col items-center justify-center">
<h2 class="h2">{profileData.user.posts}</h2>
<p>{$t('profile.posts')}</p>
</div>
<a href="/followers">
<div class="flex flex-col items-center justify-center">
<h2 class="h2">{profileData.user.follower}</h2>
<p>{$t('profile.followers')}</p>
<div class="flex flex-col justify-center items-center">
<div class="h-[20vh] w-[22vw] flex flex-row justify-around items-center">
<div class="flex flex-col items-center justify-center">
<h2 class="h2">{profileData.user.posts}</h2>
<p>{$t('profile.posts')}</p>
</div>
<a href="/followers">
<div class="flex flex-col items-center justify-center">
<h2 class="h2">{profileData.user.follower}</h2>
<p>{$t('profile.followers')}</p>
</div>
</a>
<a href="/following">
<div class="flex flex-col items-center justify-center">
<h2 class="h2">{profileData.user.following}</h2>
<p>{$t('profile.following')}</p>
</div>
</a>
{#if usernameParams == undefined}
<button on:click={openChangePwdModal} class="ml-2"
><Icon class="w-10 h-10" icon="mdi:password-reset"></Icon></button
>
{/if}
</div>
</a>
<a href="/following">
<div class="flex flex-col items-center justify-center">
<h2 class="h2">{profileData.user.following}</h2>
<p>{$t('profile.following')}</p>
</div>
</a>
<button on:click={openChangePwdModal} class="ml-2"
><Icon class="w-10 h-10" icon="mdi:password-reset"></Icon></button
>
{#if usernameParams != undefined}
{#if subscribed}
<button on:click={unsubscribe} class="btn bg-red-500">{$t('profile.unfollow')}</button>
{:else}
<button on:click={subscribe} class="btn variant-filled-primary"
>{$t('profile.follow')}</button
>
{/if}
{/if}
</div>
</div>
</div>
<div class="flex flex-col items-center justify-start mt-3 mb-3 w-full">
{#if postData.records.length == 0}
<p class="text-2xl">{$t('profile.noPosts')}</p>
{:else}
{#each postData.records as Post}
<PostUserProfil bind:postData={Post} />
{/each}
{#if maxPostCounter == postData.records.length}
<button on:click={loadMorePosts} class="btn variant-filled">{$t('profile.loadMore')}</button
>
<div class="flex flex-col items-center justify-start mt-3 mb-3 w-full">
{#if postData.records.length == 0}
<p class="text-2xl">{$t('profile.noPosts')}</p>
{:else}
{#each postData.records as Post}
<PostUserProfil bind:postData={Post} />
{/each}
{#if maxPostCounter == postData.records.length}
<button on:click={loadMorePosts} class="btn variant-filled"
>{$t('profile.loadMore')}</button
>
{/if}
{/if}
{/if}
</div>
</main>
</div>
</main>
{:else}
<p class="text-2xl">{$t('profile.noUser')}</p>
{/if}
28 changes: 27 additions & 1 deletion src/routes/profile/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export async function getProfileDetails(token: string, username: string) {
profilePictureUrl: '/default-avatar.png',
follower: 0,
following: 0,
posts: 0
posts: 0,
subscriptionId: ''
};

const serverUrl = get(serverURL);
Expand Down Expand Up @@ -77,3 +78,28 @@ export async function loadPosts(token: string, postData: UserPostFetchResponse,

return postData;
}

export async function followUser(token: string, following: string) {
const serverUrl = get(serverURL) + '/subscriptions';

const response = await fetch(serverUrl, {
method: 'POST',
mode: 'cors',
body: JSON.stringify({
following: following
})
});

return response.status;
}

export async function unfollowUser(token: string, subscriptionId: string) {
const serverUrl = get(serverURL) + '/subscriptions/' + subscriptionId;

const response = await fetch(serverUrl, {
method: 'DELETE',
mode: 'cors'
});

return response.status;
}
22 changes: 20 additions & 2 deletions src/translation.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,16 @@ export default {
'profile.noPosts': 'User has no posts yet',
'profile.loadMore': 'Load more',
'toast.internalError': 'Internal Server Error! Please try again later!',
'toast.sometingWrong': 'Something went wrong!'
'toast.sometingWrong': 'Something went wrong!',
'profile.follow': 'Follow',
'profile.unfollow': 'Unfollow',
'profile.noUser': 'User does not exist',
'toastmessage.profile.follow.success': 'user successfully followed',
'toastmessage.profile.follow.error': 'user unsuccessfully followed',
'toastmessage.profile.unfollow.success': 'User successfully unfollowed',
'toastmessage.profile.unfollow.error': 'User unsuccessfully unfollowed',
'toastmessage.profile.changeUserDetails.success': 'Userdetails successfully changed',
'toastmessage.profile.changeUserDetails.error': 'Userdetails unsuccessfully changed'
},
de: {
'imprint.frontend.header': 'Impressum Frontend',
Expand Down Expand Up @@ -137,6 +146,15 @@ export default {
'profile.noPosts': 'Der Nutzer hat noch keine Beiträge erstellt',
'profile.loadMore': 'Mehr laden',
'toast.internalError': 'Interner Serverfehler! Probier es später noch einmal!',
'toast.sometingWrong': 'Da ist etwas schief gelaufen!'
'toast.sometingWrong': 'Da ist etwas schief gelaufen!',
'profile.follow': 'Abonnieren',
'profile.unfollow': 'Deabonnieren',
'profile.noUser': 'User existiert nicht',
'toastmessage.profile.follow.success': 'User erfolgreich abonniert',
'toastmessage.profile.follow.error': 'Fehler beim Abonnieren des Users',
'toastmessage.profile.unfollow.success': 'User erfolgreich abonniert',
'toastmessage.profile.unfollow.error': 'Fehler beim Deabonnieren des Users',
'toastmessage.profile.changeUserDetails.success': 'Userdetails erfolgreich geändert',
'toastmessage.profile.changeUserDetails.error': 'Userdetails konnten nicht geändert werden'
}
};

0 comments on commit e61fe92

Please sign in to comment.