-
Notifications
You must be signed in to change notification settings - Fork 1
feat: implement user profile page with info - [CU-869awe6gv] #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 64 commits
Commits
Show all changes
68 commits
Select commit
Hold shift + click to select a range
df20351
feat: add responsive layout with left and right sidebars
Hussein-Mohamed1 038e587
refactor: improve left sidebar with typed tabs and active state logic
Hussein-Mohamed1 4587167
test: add comprehensive test coverage for pages, components, and layouts
Hussein-Mohamed1 7aa022a
refactor: standardize theming and i18n configuration
Hussein-Mohamed1 f1b6e3c
fix(ui): improve sidebar styling and icon consistency
Hussein-Mohamed1 7a43041
feat: implement user profile page with cover, avatar, and details
Hussein-Mohamed1 eb62d45
feat: add responsive layout with left and right sidebars
Hussein-Mohamed1 bbed732
refactor: improve left sidebar with typed tabs and active state logic
Hussein-Mohamed1 bd9817a
test: add comprehensive test coverage for pages, components, and layouts
Hussein-Mohamed1 e0241e0
feat: implement user profile page with cover, avatar, and details
Hussein-Mohamed1 599c1f1
chore: resolve merge conflicts after rebase
Hussein-Mohamed1 710b90e
feat: create mock data and integrate /profile/:username API into the …
Hussein-Mohamed1 d113c5c
chore: resolve conflicts
Hussein-Mohamed1 bd1ed12
feat: add responsive layout with left and right sidebars
Hussein-Mohamed1 23a1b68
refactor: improve left sidebar with typed tabs and active state logic
Hussein-Mohamed1 a5d8026
test: add comprehensive test coverage for pages, components, and layouts
Hussein-Mohamed1 dd7929f
refactor: standardize theming and i18n configuration
Hussein-Mohamed1 5e89ceb
feat: implement user profile page with cover, avatar, and details
Hussein-Mohamed1 f548d58
feat(generic-ui): styled spinner - [CU-869aw1b8u] (#26)
habibayman 6139b8b
feat: profile layout - [CU-869aw1cfx] (#27)
habibayman 993b729
refactor: improve left sidebar with typed tabs and active state logic
Hussein-Mohamed1 7a41465
test: add comprehensive test coverage for pages, components, and layouts
Hussein-Mohamed1 64525bf
feat: implement user profile page with cover, avatar, and details
Hussein-Mohamed1 7d751aa
chore: resolve merge conflicts after rebase
Hussein-Mohamed1 9a42935
feat: create mock data and integrate /profile/:username API into the …
Hussein-Mohamed1 781b8cb
fix: resolve PR review comments and apply suggested improvements
Hussein-Mohamed1 5b64787
chore: merge with dev
Hussein-Mohamed1 1678cda
fix: likes tab appear again in profile tabs
Hussein-Mohamed1 c0c46fe
feat: add responsive layout with left and right sidebars
Hussein-Mohamed1 9a02cb4
refactor: improve left sidebar with typed tabs and active state logic
Hussein-Mohamed1 2192fc8
test: add comprehensive test coverage for pages, components, and layouts
Hussein-Mohamed1 d5ea848
refactor: standardize theming and i18n configuration
Hussein-Mohamed1 edfd1b4
fix(ui): improve sidebar styling and icon consistency
Hussein-Mohamed1 6f5f87d
feat: implement user profile page with cover, avatar, and details
Hussein-Mohamed1 ad34d1e
feat: add responsive layout with left and right sidebars
Hussein-Mohamed1 9d113db
refactor: improve left sidebar with typed tabs and active state logic
Hussein-Mohamed1 504ad3c
test: add comprehensive test coverage for pages, components, and layouts
Hussein-Mohamed1 c319507
feat: implement user profile page with cover, avatar, and details
Hussein-Mohamed1 18aacdd
chore: rebase with dev
Hussein-Mohamed1 5e2e2f1
feat: create mock data and integrate /profile/:username API into the …
Hussein-Mohamed1 6150901
chore: resolve conflicts
Hussein-Mohamed1 dd13b3c
feat: add responsive layout with left and right sidebars
Hussein-Mohamed1 011b6e2
refactor: improve left sidebar with typed tabs and active state logic
Hussein-Mohamed1 e950337
test: add comprehensive test coverage for pages, components, and layouts
Hussein-Mohamed1 4bfe417
refactor: standardize theming and i18n configuration
Hussein-Mohamed1 d03c821
feat: implement user profile page with cover, avatar, and details
Hussein-Mohamed1 9bd8658
feat(generic-ui): styled spinner - [CU-869aw1b8u] (#26)
habibayman 371d586
feat: profile layout - [CU-869aw1cfx] (#27)
habibayman c7cd750
refactor: improve left sidebar with typed tabs and active state logic
Hussein-Mohamed1 983a8dc
test: add comprehensive test coverage for pages, components, and layouts
Hussein-Mohamed1 ac67f42
feat: implement user profile page with cover, avatar, and details
Hussein-Mohamed1 fb34577
chore: resolve merge conflicts after rebase
Hussein-Mohamed1 1e51cf8
feat: create mock data and integrate /profile/:username API into the …
Hussein-Mohamed1 b04a710
fix: resolve PR review comments and apply suggested improvements
Hussein-Mohamed1 c8d81e8
chore: merge with dev
Hussein-Mohamed1 7b38d6a
fix: likes tab appear again in profile tabs
Hussein-Mohamed1 df72053
chore: solve merge conflicts
Hussein-Mohamed1 cbe7da0
chore: solve merge conflicts
Hussein-Mohamed1 4fcb302
chore: address issues mentioned in PR comments
Hussein-Mohamed1 157c4c4
test: increase test cov
Hussein-Mohamed1 86b2db0
chore: merge with dev
Hussein-Mohamed1 053d3f2
feat: create not logged in user profile
habibayman 8420265
feat: add dynamic username route in left side bar
habibayman 667f4d8
fix: show tweets back in user profile
habibayman bf36c4f
test: not logged in profile page
habibayman 3e05629
test: fix profile posts page
habibayman 63f21b8
test: remove duplicate & wrong test
habibayman b852cd1
fix: add back default user data
habibayman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,32 @@ | ||
| <script lang="ts" setup> | ||
| import { SIDEBAR_TABS } from '~/constants/leftsidebar'; | ||
| const userStore = useUserStore(); | ||
| </script> | ||
| <template> | ||
| <div class="flex h-screen flex-col items-center xl:items-start"> | ||
| <div class="hover:bg-accent my-2 w-min p-2 hover:rounded-full"> | ||
| <div class="hover:bg-foreground/10 my-2 w-min p-2 hover:rounded-full"> | ||
| <NuxtLink to="/"> | ||
| <LogoRaven class="h-8 w-8" /> | ||
| </NuxtLink> | ||
| </div> | ||
| <div class="mt-2 flex flex-col items-center space-y-3 xl:items-start"> | ||
| <SideBarLeftTab v-for="tab in SIDEBAR_TABS" :key="tab.label" :tab /> | ||
| <SideBarLeftTab :tab="{ label: 'home', icon: 'home', route: '/home' }"></SideBarLeftTab> | ||
| <SideBarLeftTab | ||
| :tab="{ label: 'explore', icon: 'search', route: '/explore' }" | ||
| ></SideBarLeftTab> | ||
| <SideBarLeftTab | ||
| :tab="{ label: 'notifications', icon: 'notifications', route: '/notifications' }" | ||
| ></SideBarLeftTab> | ||
| <SideBarLeftTab | ||
| :tab="{ label: 'messages', icon: 'chat', route: '/messages' }" | ||
| ></SideBarLeftTab> | ||
| <SideBarLeftTab | ||
| :tab="{ | ||
| label: 'profile', | ||
| icon: 'person', | ||
| route: `/profile/${userStore.user?.username || ''}`, | ||
| }" | ||
| ></SideBarLeftTab> | ||
| <SideBarLeftTab :tab="{ label: 'more', icon: 'more-horiz', route: '#' }"></SideBarLeftTab> | ||
| </div> | ||
| </div> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| <script lang="ts" setup></script> | ||
|
|
||
| <template> | ||
| <div class="border-border hover:bg-background cursor-pointer border-b p-3"> | ||
| <div class="border-border hover:bg-foreground/10 cursor-pointer border-b p-3"> | ||
| <slot /> | ||
| </div> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| <script lang="ts" setup> | ||
| defineProps<{ | ||
| profileImg: string; | ||
| }>(); | ||
| </script> | ||
| <template> | ||
| <div class="mx-4 flex flex-wrap items-center justify-between gap-4"> | ||
| <div> | ||
| <NuxtImg | ||
| :src="profileImg" | ||
| alt="Profile picture" | ||
| class="-mt-16 size-34 rounded-full border-4 object-contain" | ||
| loading="eager" | ||
| /> | ||
| </div> | ||
| <UiButton variant="outline">{{ $t('profile-info.edit-profile') }}</UiButton> | ||
| </div> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <script lang="ts" setup> | ||
| defineProps<{ | ||
| coverImg: string; | ||
| }>(); | ||
| </script> | ||
| <template> | ||
| <NuxtImg :src="coverImg" alt="Profile Cover" class="h-48 w-full object-cover" loading="eager" /> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,14 @@ | ||
| <script setup lang="ts"></script> | ||
| <script lang="ts" setup> | ||
| import type { UserProfile } from '~~/shared/types/user'; | ||
|
|
||
| defineProps<{ | ||
| userProfile: UserProfile; | ||
| }>(); | ||
| </script> | ||
| <template> | ||
| <div class="bg-accent/10 h-[460px]"></div> | ||
| <div> | ||
| <ProfileCover :cover-img="userProfile.bannerUrl" /> | ||
| <ProfileAvatarSection :profile-img="userProfile.avatarUrl" /> | ||
| <ProfileInfo :user-profile="userProfile" /> | ||
| </div> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <script lang="ts" setup> | ||
| import type { UserProfile } from '~~/shared/types/user'; | ||
| import { formatMonthYear } from '~/utils/date'; | ||
| const props = defineProps<{ | ||
| userProfile: UserProfile; | ||
| }>(); | ||
| const displayUrl = computed(() => { | ||
| if (props.userProfile.websiteUrl) { | ||
| const cleanedUrl = cleanUrl(props.userProfile.websiteUrl); | ||
| return cleanedUrl.length > 30 ? cleanedUrl.slice(0, 29) + '...' : cleanedUrl; | ||
| } | ||
| return ''; | ||
| }); | ||
| </script> | ||
| <template> | ||
| <div class="mt-2 flex flex-col"> | ||
| <div class="px-4"> | ||
| <h2 class="text-foreground text-2xl font-bold">{{ userProfile.displayName }}</h2> | ||
| <p class="text-muted-foreground">{{ userProfile.username }}</p> | ||
| <p class="mt-2">{{ userProfile.bio }}</p> | ||
| <div class="mt-2 flex flex-wrap"> | ||
| <a | ||
| :href="userProfile.websiteUrl" | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| class="text-brand-blue me-2 flex items-center gap-1 hover:underline" | ||
| > | ||
| <Icon class="text-muted-foreground" name="ic:sharp-link" size="18" /> | ||
| {{ displayUrl }} | ||
| </a> | ||
|
|
||
| <p class="text-muted-foreground flex items-center gap-1"> | ||
| <Icon name="ic:sharp-calendar-month" /> | ||
| {{ $t('profile-info.joined') }} | ||
| {{ formatMonthYear(userProfile.joinedAt) }} | ||
| </p> | ||
| </div> | ||
| <div class="mt-4 flex space-x-4"> | ||
| <span | ||
| ><strong>{{ userProfile.followingCount }}</strong> | ||
| <span class="text-muted-foreground ms-1"> {{ $t('profile-info.following') }} </span> | ||
| </span> | ||
| <span | ||
| ><strong>{{ userProfile.followersCount }}</strong> | ||
| <span class="text-muted-foreground ms-1"> {{ $t('profile-info.followers') }} </span> | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import type { UserProfile } from '~~/shared/types/user'; | ||
|
|
||
| export const useUserProfile = (username: string) => { | ||
| const { | ||
| data: userProfile, | ||
| error, | ||
| pending, | ||
| } = useFetch<UserProfile>(`/api/users/${username}/profile`, { | ||
| key: `user-profile-${username}`, | ||
| }); | ||
| return { | ||
| userProfile, | ||
| error, | ||
| loading: pending, | ||
| }; | ||
| }; | ||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| <script setup lang="ts"> | ||
| import type { Tweet } from '~~/shared/types/tweets'; | ||
| import TweetDefaultCard from '@/components/tweet/TweetDefaultCard.vue'; | ||
| definePageMeta({ | ||
| layout: 'profile', | ||
| }); | ||
|
|
||
| const tweets = ref<Tweet[]>([]); | ||
|
|
||
| const { data: tweetsData, error } = await useFetch<{ data: Tweet[] }>('/api/tweets'); | ||
| tweets.value = tweetsData.value?.data || []; | ||
|
|
||
| if (error.value) console.error(error.value); | ||
| </script> | ||
|
|
||
| <template> | ||
| <div class="p-2"> | ||
| <div v-if="tweets.length > 0" class="mb-4"> | ||
| <div class="mt-4 flex w-full max-w-[700px] flex-col gap-4"> | ||
| <TweetDefaultCard v-for="tweet in tweets" :key="tweet.id" :tweet="tweet" /> | ||
| </div> | ||
| </div> | ||
| <div v-else data-testid="empty-state" class="text-muted-foreground mt-10 text-center"> | ||
| <h1 class="text-xl font-semibold">{{ $t('testing.tweets.tweet-not-found') }}</h1> | ||
| </div> | ||
| </div> | ||
| </template> |
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,27 +1,29 @@ | ||
| <script setup lang="ts"> | ||
| import type { Tweet } from '~~/shared/types/tweets'; | ||
| import TweetDefaultCard from '../../components/tweet/TweetDefaultCard.vue'; | ||
| const { t } = useI18n(); | ||
|
|
||
| definePageMeta({ | ||
| layout: 'profile', | ||
| layout: 'default', | ||
| }); | ||
|
|
||
| const tweets = ref<Tweet[]>([]); | ||
|
|
||
| const { data: tweetsData, error } = await useFetch<{ data: Tweet[] }>('/api/tweets'); | ||
| tweets.value = tweetsData.value?.data || []; | ||
|
|
||
| if (error.value) console.error(error.value); | ||
| </script> | ||
|
|
||
| <template> | ||
| <div class="p-2"> | ||
| <div v-if="tweets.length > 0" class="mb-4"> | ||
| <div class="mt-4 flex w-full max-w-[700px] flex-col gap-4"> | ||
| <TweetDefaultCard v-for="tweet in tweets" :key="tweet.id" :tweet="tweet" /> | ||
| <div class="flex min-h-screen items-center justify-center p-6"> | ||
| <div class="text-center"> | ||
| <div class="mb-6"> | ||
| <LogoRaven class="text-primary mx-auto h-16 w-16" /> | ||
| </div> | ||
| <h1 class="mb-4 text-3xl font-bold">{{ t('profile.not-logged-in.title') }}</h1> | ||
| <p class="text-muted-foreground mb-8 text-lg"> | ||
| {{ t('profile.not-logged-in.description') }} | ||
| </p> | ||
| <div class="space-y-3"> | ||
| <NuxtLink | ||
| to="/" | ||
| class="bg-primary hover:bg-primary/90 inline-block rounded-full px-8 py-3 font-semibold text-white transition-colors" | ||
| > | ||
| {{ t('profile.not-logged-in.take-me-home') }} | ||
| </NuxtLink> | ||
| </div> | ||
| </div> | ||
| <div v-else data-testid="empty-state" class="text-muted-foreground mt-10 text-center"> | ||
| <h1 class="text-xl font-semibold">{{ $t('testing.tweets.tweet-not-found') }}</h1> | ||
| </div> | ||
| </div> | ||
| </template> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.