Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
import { goto } from '$app/navigation';
import { page } from '$app/state';
import { Camera, CommentsTwo, Home, Search } from '$lib/icons';
import { isNavigatingThroughNav, ownerId } from '$lib/store/store.svelte';
import { isNavigatingThroughNav } from '$lib/store/store.svelte';
import { uploadedImages } from '$lib/store/store.svelte';
import { revokeImageUrls } from '$lib/utils';
import { getAuthId, revokeImageUrls } from '$lib/utils';
import type { HTMLAttributes } from 'svelte/elements';

let ownerId: string | null = $state(null);


interface IBottomNavProps extends HTMLAttributes<HTMLElement> {
activeTab?: string;
profileSrc: string;
Expand Down Expand Up @@ -44,6 +47,7 @@
};

$effect(() => {
ownerId = getAuthId()
activeTab = _activeTab.split('/').pop() ?? '';
if (images && images.length > 0 && activeTab !== 'post' && previousTab === 'post' && !_activeTab.includes('post/audience')) {
if (uploadedImages.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<div class="flex flex-col gap-4 p-4">
<div class="flex items-center gap-4">
<img
src={profileData.avatar ?? 'https://picsum.photos/200/200'}
src={profileData.avatarUrl ?? 'https://picsum.photos/200/200'}
alt={profileData.username}
class="h-20 w-20 rounded-full object-cover"
/>
Expand Down
59 changes: 30 additions & 29 deletions platforms/pictique/src/lib/fragments/SideBar/SideBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import { goto } from '$app/navigation';
import { page } from '$app/state';
import Button from '$lib/ui/Button/Button.svelte';
import { cn } from '$lib/utils';
import { ownerId } from '$lib/store/store.svelte';
import { cn, getAuthId } from '$lib/utils';

let ownerId: string | null = $state(null);

interface ISideBarProps extends HTMLAttributes<HTMLElement> {
activeTab?: string;
Expand All @@ -20,6 +21,7 @@
}: ISideBarProps = $props();

$effect(() => {
ownerId = getAuthId();
const pathname = page.url.pathname;
if (pathname.includes('/home')) {
activeTab = 'home';
Expand Down Expand Up @@ -142,33 +144,32 @@
Settings
</h3>
</button>

<!-- <button -->
<!-- type="button" -->
<!-- class="flex items-center gap-2" -->
<!-- aria-current={activeTab === 'profile' ? 'page' : undefined} -->
<!-- onclick={() => { -->
<!-- activeTab = 'profile'; -->
<!-- goto(`/profile/${ownerId.value}`); -->
<!-- }} -->
<!-- > -->
<!-- <span -->
<!-- class={`inline-block w-full rounded-full border ${activeTab === 'profile' ? 'border-brand-burnt-orange' : 'border-transparent'}`} -->
<!-- > -->
<!-- <img -->
<!-- width="24px" -->
<!-- height="24px" -->
<!-- class="aspect-square rounded-full" -->
<!-- src={'https://picsum.photos/200/200'} -->
<!-- alt="profile" -->
<!-- /> -->
<!-- </span> -->
<!-- <h3 -->
<!-- class={`${activeTab === 'profile' ? 'text-brand-burnt-orange' : 'text-black-800'} mt-[4px]`} -->
<!-- > -->
<!-- Profile -->
<!-- </h3> -->
<!-- </button> -->
<button
type="button"
class="flex items-center gap-2"
aria-current={activeTab === 'profile' ? 'page' : undefined}
onclick={() => {
activeTab = 'profile';
goto(`/profile/${ownerId}`);
}}
>
<span
class={`inline-block w-full rounded-full border ${activeTab === 'profile' ? 'border-brand-burnt-orange' : 'border-transparent'}`}
>
<img
width="24px"
height="24px"
class="aspect-square rounded-full"
src={profileSrc}
alt="profile"
/>
</span>
<h3
class={`${activeTab === 'profile' ? 'text-brand-burnt-orange' : 'text-black-800'} mt-[4px]`}
>
Profile
</h3>
</button>
{#if handlePost}
<Button size="sm" variant="secondary" callback={handlePost}>Post a photo</Button>
{/if}
Expand Down
6 changes: 1 addition & 5 deletions platforms/pictique/src/lib/store/store.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ export const showComments = $state({
value: false,
});

export const ownerId = $state({
value: "1",
});

export const selectedPost: { value: PostData | null } = $state({
value: null,
});
Expand All @@ -22,4 +18,4 @@ export const uploadedImages: { value: Image[] | null } = $state({

export const audience: { value: string } = $state({
value: "Everyone",
});
});
2 changes: 1 addition & 1 deletion platforms/pictique/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export type PostData = {
export type userProfile = {
userId: string;
username: string;
avatar: string;
avatarUrl: string;
totalPosts: number;
followers: number;
following: number;
Expand Down
14 changes: 14 additions & 0 deletions platforms/pictique/src/lib/utils/axios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,17 @@ export function getAuthToken() {
export const removeAuthToken = (): void => {
localStorage.removeItem(TOKEN_KEY);
};

// Utility function to store auth id
export const setAuthId = (id: string): void => {
localStorage.setItem("ownerId", id);
};

export const getAuthId = () => {
return localStorage.getItem("ownerId");
};

// Utility function to remove auth token
export const removeAuthId = (): void => {
localStorage.removeItem("ownerId");
};
4 changes: 3 additions & 1 deletion platforms/pictique/src/routes/(auth)/auth/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { Qr } from '$lib/ui';
import { onMount } from 'svelte';
import { apiClient, setAuthToken } from '$lib/utils';
import { apiClient, setAuthId, setAuthToken } from '$lib/utils';
import { PUBLIC_PICTIQUE_BASE_URL } from '$env/static/public';
import { goto } from '$app/navigation';

Expand All @@ -21,6 +21,8 @@

eventSource.onmessage = function (e) {
const data = JSON.parse(e.data);
const {user} = data
setAuthId(user.id);
const { token } = data;
setAuthToken(token);
goto('/home');
Expand Down
24 changes: 20 additions & 4 deletions platforms/pictique/src/routes/(protected)/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import { openCreatePostModal, isCreatePostModalOpen } from '$lib/stores/posts';
import { comments, fetchComments, createComment, activePostId } from '$lib/stores/comments';
import CreatePostModal from '$lib/fragments/CreatePostModal/CreatePostModal.svelte';
import { onMount } from 'svelte';
import { apiClient, getAuthId } from '$lib/utils';
import type { userProfile } from '$lib/types';
import { heading } from '../store';

let { children } = $props();

let ownerId: string | null = $state(null);
let route = $derived(page.url.pathname);

let commentValue: string = $state('');
Expand All @@ -17,6 +20,7 @@
let idFromParams = $state();
let isCommentsLoading = $state(false);
let commentsError = $state<string | null>(null);
let profile = $state<userProfile | null>(null);

const handleSend = async () => {
console.log($activePostId, commentValue);
Expand Down Expand Up @@ -55,6 +59,7 @@

// Watch for changes in showComments to fetch comments when opened
$effect(() => {
ownerId = getAuthId();
if (showComments.value && activePostId) {
isCommentsLoading = true;
commentsError = null;
Expand All @@ -67,13 +72,24 @@
});
}
});

async function fetchProfile() {
try {
const response = await apiClient.get(`/api/users/${ownerId}`);
profile = response.data;
} catch (err) {
console.log(err instanceof Error ? err.message : 'Failed to load profile');
}
}

onMount(fetchProfile)
</script>

<main
class={`block h-[100dvh] ${route !== '/home' && route !== '/messages' && route !== '/profile' && route !== '/settings' && !route.includes('/profile') ? 'grid-cols-[20vw_auto]' : 'grid-cols-[20vw_auto_30vw]'} md:grid`}
class={`block h-[100dvh] ${route !== '/home' && route !== '/messages' && route !== '/profile' && !route.includes('settings') && !route.includes('/profile') ? 'grid-cols-[20vw_auto]' : 'grid-cols-[20vw_auto_30vw]'} md:grid`}
>
<SideBar
profileSrc="https://picsum.photos/200"
profileSrc={profile?.avatarUrl}
handlePost={async () => {
openCreatePostModal();
}}
Expand Down Expand Up @@ -149,7 +165,7 @@
{/if}

{#if route !== `/messages/${idFromParams}`}
<BottomNav class="btm-nav" profileSrc="https://picsum.photos/200" />
<BottomNav class="btm-nav" profileSrc={profile?.avatarUrl ?? ""} />
{/if}
</main>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
<script lang="ts">
<script>
</script>

Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@
import { goto } from '$app/navigation';
import { page } from '$app/state';
import { Profile } from '$lib/fragments';
import { ownerId, selectedPost } from '$lib/store/store.svelte';
import { selectedPost } from '$lib/store/store.svelte';
import type { userProfile, PostData } from '$lib/types';
import { apiClient } from '$lib/utils/axios';
import { apiClient, getAuthId } from '$lib/utils/axios';
import { onMount } from 'svelte';
import Post from '../../../../lib/fragments/Post/Post.svelte';
let profileId = $derived(page.params.id);
let profile = $state<userProfile | null>(null);
let error = $state<string | null>(null);
let loading = $state(true);
let ownerId: string | null = $state(null);
async function fetchProfile() {
try {
loading = true;
error = null;
const response = await apiClient.get(`/api/users/${profileId}`);
profile = response.data;
console.log(JSON.stringify(profile));
} catch (err) {
error = err instanceof Error ? err.message : 'Failed to load profile';
} finally {
Expand All @@ -38,7 +39,7 @@
async function handleMessage() {
try {
await apiClient.post(`/api/chats/`, {
name: profile.username,
name: profile?.username,
participantIds: [profileId]
});
goto('/messages');
Expand All @@ -52,6 +53,9 @@
selectedPost.value = post;
goto('/profile/post');
}
$effect(()=> {
ownerId = getAuthId();
})
onMount(fetchProfile);
</script>
Expand All @@ -67,7 +71,7 @@
</div>
{:else if profile}
<Profile
variant={ownerId.value === profileId ? 'user' : 'other'}
variant={ownerId === profileId ? 'user' : 'other'}
profileData={profile}
handleSinglePost={(post) => handlePostClick(post)}
{handleFollow}
Expand Down
49 changes: 36 additions & 13 deletions platforms/pictique/src/routes/(protected)/settings/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import { goto } from '$app/navigation';
import { page } from '$app/state';
import SettingsNavigationButton from '$lib/fragments/SettingsNavigationButton/SettingsNavigationButton.svelte';
import { apiClient } from '$lib/utils';
import type { userProfile } from '$lib/types';
import { apiClient, getAuthId } from '$lib/utils';
import {
DatabaseIcon,
Logout01Icon,
Expand All @@ -12,27 +13,49 @@
import { onMount } from 'svelte';

let route = $derived(page.url.pathname);
let username: string = $state('');
let userEmail: string = $state('');
let userImage: string = $state('');
let ownerId: string | null = $state(null);

onMount(async () => {
const { data } = await apiClient.get('/api/users');
username = data.displayName;
userEmail = data.handle;
userImage = data.avatarUrl;
});
let profile = $state<userProfile | null>(null);
let error = $state<string | null>(null);
let loading = $state(true);

async function fetchProfile() {
try {
loading = true;
error = null;
const response = await apiClient.get(`/api/users/${ownerId}`);
profile = response.data;
} catch (err) {
error = err instanceof Error ? err.message : 'Failed to load profile';
} finally {
loading = false;
}
}
$effect(()=> {
ownerId = getAuthId();
})
onMount(fetchProfile)
</script>

<div class="bg-grey rounded-xl p-3 md:p-5">
<SettingsNavigationButton onclick={() => goto(`/settings/account`)} profileSrc={userImage}>
{#if loading}
<div class="flex h-64 items-center justify-center">
<p class="text-gray-500">Loading profile...</p>
</div>
{:else if error}
<div class="flex h-64 items-center justify-center">
<p class="text-red-500">{error}</p>
</div>
{:else if profile}
<SettingsNavigationButton onclick={() => goto(`/settings/account`)} profileSrc={profile?.avatarUrl}>
{#snippet children()}
<div class="flex flex-col items-start">
<h2 class="text-lg">{username}</h2>
<p class="text-sm">{userEmail}</p>
<h2 class="text-lg">{profile?.handle}</h2>
<p class="text-sm">{profile?.description}</p>
</div>
{/snippet}
</SettingsNavigationButton>
{/if}
</div>
<hr class="text-grey" />
<div class="flex flex-col gap-3">
Expand Down
Loading
Loading