Refactor avatar components across the application to use the new UserAvatar component, replacing instances of the Avatar component for improved consistency and maintainability.
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import * as Table from '@cio/ui/base/table';
|
||||
import * as DropdownMenu from '@cio/ui/base/dropdown-menu';
|
||||
import * as Avatar from '@cio/ui/base/avatar';
|
||||
import { Checkbox } from '@cio/ui/base/checkbox';
|
||||
import { Badge } from '@cio/ui/base/badge';
|
||||
import UserIcon from '@lucide/svelte/icons/user';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import EllipsisVerticalIcon from '@lucide/svelte/icons/ellipsis-vertical';
|
||||
import type { OrganizationAudienceMember } from '$features/org/utils/types';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
@@ -40,26 +39,12 @@
|
||||
<Table.Cell>
|
||||
{#if memberDetailHref}
|
||||
<a href={memberDetailHref} class="ui:text-primary flex items-center gap-2 hover:underline">
|
||||
<Avatar.Root class="h-5 w-5">
|
||||
{#if row.avatarUrl}
|
||||
<Avatar.Image src={row.avatarUrl} alt={row.name ? row.name : 'User'} />
|
||||
{/if}
|
||||
<Avatar.Fallback>
|
||||
<UserIcon class="ui:size-3 ui:text-muted-foreground" />
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar src={row.avatarUrl} alt={row.name ?? 'User'} class="h-5 w-5" />
|
||||
{row.name}
|
||||
</a>
|
||||
{:else}
|
||||
<span class="flex items-center gap-2">
|
||||
<Avatar.Root class="h-5 w-5">
|
||||
{#if row.avatarUrl}
|
||||
<Avatar.Image src={row.avatarUrl} alt={row.name ? row.name : 'User'} />
|
||||
{/if}
|
||||
<Avatar.Fallback>
|
||||
<UserIcon class="ui:size-3 ui:text-muted-foreground" />
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar src={row.avatarUrl} alt={row.name ?? 'User'} class="h-5 w-5" />
|
||||
{row.name}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import * as Avatar from '@cio/ui/base/avatar';
|
||||
import TrashIcon from '@lucide/svelte/icons/trash';
|
||||
import UserIcon from '@lucide/svelte/icons/user';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import { calDateDiff } from '$lib/utils/functions/date';
|
||||
import { IconButton } from '@cio/ui/custom/icon-button';
|
||||
import { Vote } from '$features/ui';
|
||||
@@ -39,17 +38,7 @@
|
||||
<div class="border-gray w-full rounded-lg border">
|
||||
<header class="flex items-center justify-between p-2 leading-none">
|
||||
<div class="flex items-center text-black">
|
||||
<Avatar.Root class="size-7">
|
||||
{#if comment.author?.avatarUrl}
|
||||
<Avatar.Image
|
||||
src={comment.author.avatarUrl}
|
||||
alt={comment.author?.fullname ? comment.author.fullname : 'User'}
|
||||
/>
|
||||
{/if}
|
||||
<Avatar.Fallback>
|
||||
<UserIcon class="ui:size-3.5 ui:text-muted-foreground" />
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar src={comment.author?.avatarUrl} alt={comment.author?.fullname ?? 'User'} class="size-7" />
|
||||
|
||||
<p class="ml-2 text-sm dark:text-white">{comment.author?.fullname}</p>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
|
||||
import EmptyState from './empty-state.svelte';
|
||||
import * as Avatar from '@cio/ui/base/avatar';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import type { CourseAnalytics } from '$features/course/utils/types';
|
||||
|
||||
interface Props {
|
||||
@@ -80,17 +80,11 @@
|
||||
class="sticky left-0 z-10 min-w-[200px] bg-white px-4 py-3 transition-colors group-hover:bg-gray-50 dark:bg-neutral-800 dark:group-hover:bg-gray-700"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<Avatar.Root class="size-8">
|
||||
{#if student.profile.avatar_url}
|
||||
<Avatar.Image
|
||||
src={student.profile.avatar_url}
|
||||
alt={student.profile.fullname ? student.profile.fullname : $t('analytics.student')}
|
||||
/>
|
||||
{/if}
|
||||
<Avatar.Fallback>
|
||||
<UserIcon class="ui:size-4 ui:text-muted-foreground" />
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar
|
||||
src={student.profile.avatar_url}
|
||||
alt={student.profile.fullname ?? $t('analytics.student')}
|
||||
class="size-8"
|
||||
/>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="truncate font-medium text-gray-900 dark:text-white">
|
||||
{student.profile.fullname}
|
||||
|
||||
+4
-3
@@ -14,6 +14,7 @@
|
||||
import * as Dialog from '@cio/ui/base/dialog';
|
||||
import { TextareaField } from '@cio/ui/custom/textarea-field';
|
||||
import { Button } from '@cio/ui/base/button';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
|
||||
// import { useCompletion } from 'ai/svelte';
|
||||
// import { QUESTION_TYPE } from '$features/ui/question/constants';
|
||||
@@ -330,10 +331,10 @@
|
||||
</p>
|
||||
{#if data.student}
|
||||
<div class="flex flex-row items-center justify-center rounded-md bg-gray-100 p-[6px] dark:bg-neutral-700">
|
||||
<img
|
||||
alt={$t('course.navItem.submissions.grading_modal.student_avatar')}
|
||||
class="flex h-5 w-5 rounded-full"
|
||||
<UserAvatar
|
||||
src={data.student.avatarUrl}
|
||||
alt={$t('course.navItem.submissions.grading_modal.student_avatar')}
|
||||
class="h-5 w-5"
|
||||
/>
|
||||
<p class="ml-2 line-clamp-1 text-sm font-semibold dark:text-white">
|
||||
{data.student.fullname}
|
||||
|
||||
+4
-6
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Spinner } from '@cio/ui/base/spinner';
|
||||
import { ExerciseQuestion } from '@cio/ui';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
|
||||
import { submissions } from './store';
|
||||
import { questionnaire } from '../store';
|
||||
@@ -17,9 +18,6 @@
|
||||
|
||||
let { isLoading = $bindable(false) }: Props = $props();
|
||||
|
||||
const defaultImg =
|
||||
'https://images.unsplash.com/photo-1599566150163-29194dcaad36?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8YXZhdGFyc3xlbnwwfHwwfHx8Mg%3D%3D';
|
||||
|
||||
let studentSelected = $state(0);
|
||||
const questionLabels = $derived(getExerciseQuestionLabels());
|
||||
|
||||
@@ -57,10 +55,10 @@
|
||||
studentSelected == i ? 'border-primary-700 border-[3px]' : ''
|
||||
}`}
|
||||
>
|
||||
<img
|
||||
src={student.groupmember?.profile.avatarUrl ? student.groupmember.profile.avatarUrl : defaultImg}
|
||||
<UserAvatar
|
||||
src={student.groupmember?.profile.avatarUrl}
|
||||
alt={$t('course.navItem.lessons.exercises.all_exercises.analytics.individual.student_avatar')}
|
||||
class="m-1 max-h-10 w-10 rounded-full bg-white"
|
||||
class="m-1 size-10"
|
||||
/>
|
||||
</div>
|
||||
<p class="line-clamp-2 w-20 leading-4 whitespace-pre-wrap">
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
import { untrack } from 'svelte';
|
||||
import * as DropdownMenu from '@cio/ui/base/dropdown-menu';
|
||||
import EllipsisVerticalIcon from '@lucide/svelte/icons/ellipsis-vertical';
|
||||
import UserIcon from '@lucide/svelte/icons/user';
|
||||
|
||||
import * as Avatar from '@cio/ui/base/avatar';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import { TextareaField } from '@cio/ui/custom/textarea-field';
|
||||
import { DeleteModal } from '$features/ui';
|
||||
import { Button } from '@cio/ui/base/button';
|
||||
@@ -98,14 +96,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex h-full items-start gap-3">
|
||||
<Avatar.Root class="mt-2 size-6!">
|
||||
{#if $profile.avatarUrl}
|
||||
<Avatar.Image src={$profile.avatarUrl} alt={$profile.fullname ? $profile.fullname : 'User'} />
|
||||
{/if}
|
||||
<Avatar.Fallback>
|
||||
<UserIcon class="ui:size-3 ui:text-muted-foreground" />
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar src={$profile.avatarUrl} alt={$profile.fullname ?? 'User'} class="mt-2 size-6!" />
|
||||
<div class="h-full w-full">
|
||||
<TextareaField
|
||||
label={$t('course.navItem.lessons.comments.text_area_title')}
|
||||
@@ -125,14 +116,7 @@
|
||||
<div class="my-5">
|
||||
{#each comments as commentItem (commentItem.id)}
|
||||
<div class="mt-2 flex items-start gap-3 pb-2">
|
||||
<Avatar.Root class="mt-2 size-6!">
|
||||
{#if commentItem.avatar}
|
||||
<Avatar.Image src={commentItem.avatar} alt={commentItem.name ? commentItem.name : 'User'} />
|
||||
{/if}
|
||||
<Avatar.Fallback>
|
||||
<UserIcon class="ui:size-3 ui:text-muted-foreground" />
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar src={commentItem.avatar} alt={commentItem.name ?? 'User'} class="mt-2 size-6!" />
|
||||
|
||||
<div class="w-full rounded-md border px-3 py-2 dark:border-neutral-700">
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
import { newsfeedApi } from '$features/course/api';
|
||||
|
||||
import { Button } from '@cio/ui/base/button';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import type { Feed } from '$features/course/utils/types';
|
||||
import type { NewsfeedCommentsByFeedId } from '$features/course/api';
|
||||
|
||||
@@ -193,13 +194,7 @@
|
||||
|
||||
<!-- Input for new comment -->
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="h-7 w-7">
|
||||
<img
|
||||
src={author.avatarUrl}
|
||||
alt={$t('course.navItem.news_feed.user_avatar_alt')}
|
||||
class="h-full w-full rounded-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<UserAvatar src={author.avatarUrl} alt={$t('course.navItem.news_feed.user_avatar_alt')} class="size-7" />
|
||||
<div class="flex-1">
|
||||
<input
|
||||
type="text"
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { Empty } from '@cio/ui/custom/empty';
|
||||
import UserXIcon from '@lucide/svelte/icons/user-x';
|
||||
import * as Avatar from '@cio/ui/base/avatar';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import * as Table from '@cio/ui/base/table';
|
||||
import * as Tooltip from '@cio/ui/base/tooltip';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
import { shortenName } from '$lib/utils/functions/string';
|
||||
import { calculateStudentAverage, type MarksPageData, type ExerciseInfo } from '$features/course/utils/marks-utils';
|
||||
import TruncatedWithTooltip from '$features/course/components/truncated-with-tooltip.svelte';
|
||||
|
||||
@@ -70,15 +69,11 @@
|
||||
class="sticky left-0 min-w-[200px] border-r border-gray-200 bg-gray-50 px-3 py-2 dark:border-neutral-700 dark:bg-neutral-800/80"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<Avatar.Root class="size-6! shrink-0 rounded-full">
|
||||
<Avatar.Image
|
||||
src={student.profile?.avatarUrl ?? undefined}
|
||||
alt={student.profile?.fullname ?? 'Student'}
|
||||
/>
|
||||
<Avatar.Fallback class="ui:bg-muted ui:text-muted-foreground rounded-full">
|
||||
{shortenName(student.profile?.fullname) ?? 'S'}
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar
|
||||
src={student.profile?.avatarUrl}
|
||||
alt={student.profile?.fullname ?? 'Student'}
|
||||
class="size-6! shrink-0"
|
||||
/>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="ui:text-foreground truncate text-sm font-medium">
|
||||
{student.profile?.fullname ?? '-'}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
|
||||
import { Chip } from '@cio/ui/custom/chip';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import MarkExerciseModal from '$features/course/components/exercise/mark-exercise-modal.svelte';
|
||||
import { STATUS } from '$features/course/components/exercise/constants';
|
||||
import { onMount } from 'svelte';
|
||||
@@ -242,7 +243,7 @@
|
||||
class="mb-2 flex w-full cursor-pointer items-center text-black"
|
||||
href={`${page.url.pathname}?submissionId=${item.id}`}
|
||||
>
|
||||
<img alt="Student avatar" class="block h-6 w-6 rounded-full" src={item.student.avatarUrl} />
|
||||
<UserAvatar src={item.student.avatarUrl} alt="Student avatar" class="h-6 w-6" />
|
||||
<p class="ml-2 text-sm dark:text-white">
|
||||
{item.student.username}
|
||||
</p>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<script lang="ts">
|
||||
import * as Avatar from '@cio/ui/base/avatar';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import { calDateDiff } from '$lib/utils/functions/date';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
import type { UserAnalytics } from '$lib/utils/types/analytics';
|
||||
import AlarmClockIcon from '@lucide/svelte/icons/alarm-clock';
|
||||
import MailIcon from '@lucide/svelte/icons/mail';
|
||||
import UserIcon from '@lucide/svelte/icons/user';
|
||||
|
||||
interface Props {
|
||||
user: UserAnalytics['user'];
|
||||
@@ -16,14 +15,7 @@
|
||||
|
||||
<div class="rounded-md border p-5">
|
||||
<div class="flex w-full flex-col items-center justify-start gap-4 text-start md:flex-row">
|
||||
<Avatar.Root class="h-16 w-16">
|
||||
{#if user.avatarUrl}
|
||||
<Avatar.Image src={user.avatarUrl} alt={user.fullName ? user.fullName : 'User'} />
|
||||
{/if}
|
||||
<Avatar.Fallback>
|
||||
<UserIcon class="ui:size-8 ui:text-muted-foreground" />
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar src={user.avatarUrl} alt={user.fullName ?? 'User'} class="h-16 w-16" />
|
||||
<div class="flex flex-col space-y-2">
|
||||
<p class="text-center text-2xl md:text-left dark:text-white">
|
||||
{user.fullName}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
if (item.id === 'profile') {
|
||||
return {
|
||||
...item,
|
||||
is_completed: !$profile.avatarUrl?.includes('avatars/avatar.png')
|
||||
is_completed: !$profile.avatarUrl?.includes('avatars/avatar.png') || !!$profile.avatarUrl
|
||||
};
|
||||
}
|
||||
return item;
|
||||
@@ -46,7 +46,7 @@
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{#each setupList as item}
|
||||
{#each setupList as item (item.id)}
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
{#if item.is_completed}
|
||||
<BadgeCheckIcon class="custom size-4 shrink-0 text-green-600! opacity-50" />
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
import BellPlusIcon from '@lucide/svelte/icons/bell-plus';
|
||||
import BadgeHelpIcon from '@lucide/svelte/icons/badge-help';
|
||||
import LogOutIcon from '@lucide/svelte/icons/log-out';
|
||||
import * as Avatar from '@cio/ui/base/avatar';
|
||||
import * as Sidebar from '@cio/ui/base/sidebar';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import { useSidebar } from '@cio/ui/base/sidebar';
|
||||
import ChevronsUpDownIcon from '@lucide/svelte/icons/chevrons-up-down';
|
||||
import ThemeToggle from './theme-toggle.svelte';
|
||||
@@ -25,10 +25,7 @@
|
||||
|
||||
-->
|
||||
{#snippet avatarblock()}
|
||||
<Avatar.Root>
|
||||
<Avatar.Image src={$profile.avatarUrl} alt={$profile.fullname} />
|
||||
<Avatar.Fallback class="rounded-lg">{$profile.fullname.slice(0, 2)}</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar src={$profile.avatarUrl} alt={$profile.fullname} />
|
||||
<div class="grid flex-1 text-left text-sm leading-tight font-normal">
|
||||
<span class="truncate">{$profile.fullname}</span>
|
||||
<span class="truncate text-xs">{$profile.email}</span>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
import { currentOrgPath } from '$lib/utils/store/org';
|
||||
|
||||
import { CreateCourseButton } from '$features/course/components';
|
||||
import * as Avatar from '@cio/ui/base/avatar';
|
||||
import { UserAvatar } from '@cio/ui/custom/user-avatar';
|
||||
import { Progress } from '@cio/ui/base/progress';
|
||||
import { Button } from '@cio/ui/base/button';
|
||||
import { WelcomeModal } from '$features/onboarding/components';
|
||||
@@ -146,14 +146,7 @@
|
||||
{#each enrollments as enrollment, i (i)}
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<Avatar.Root class="h-6 w-6">
|
||||
{#if enrollment.avatarUrl}
|
||||
<Avatar.Image src={enrollment.avatarUrl} alt={enrollment.name ? enrollment.name : 'User'} />
|
||||
{/if}
|
||||
<Avatar.Fallback>
|
||||
<UserIcon class="ui:size-3 ui:text-muted-foreground" />
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
<UserAvatar src={enrollment.avatarUrl} alt={enrollment.name ?? 'User'} class="h-6 w-6" />
|
||||
|
||||
<div class="min-h-[45px] space-y-1">
|
||||
<p class="text-sm leading-none capitalize">{enrollment.name}</p>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
if (item.id === 'profile') {
|
||||
return {
|
||||
...item,
|
||||
is_completed: !$profile.avatarUrl?.includes('avatars/avatar.png')
|
||||
is_completed: !$profile.avatarUrl?.includes('avatars/avatar.png') || !!$profile.avatarUrl
|
||||
};
|
||||
}
|
||||
return item;
|
||||
|
||||
Reference in New Issue
Block a user