[WEB-5779] fix: handle loading state while fetching project cover image (#8419)

* refactor: replace cover image handling with CoverImage component across profile and project forms

* fix: extend CoverImage component to accept additional img props

* Update apps/web/core/components/common/cover-image.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: handle undefined cover image URL in ProfileSidebar component

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Jayash Tripathy 2025-12-24 19:30:01 +05:30 committed by GitHub
parent 59f26a80bb
commit 39728d4cc4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 68 additions and 31 deletions

View file

@ -22,10 +22,10 @@ import { useUserPermissions } from "@/hooks/store/user";
import { useAppRouter } from "@/hooks/use-app-router";
import { usePlatformOS } from "@/hooks/use-platform-os";
// local imports
import { CoverImage } from "@/components/common/cover-image";
import { DeleteProjectModal } from "./delete-project-modal";
import { JoinProjectModal } from "./join-project-modal";
import { ArchiveRestoreProjectModal } from "./settings/archive-project/archive-restore-modal";
import { DEFAULT_COVER_IMAGE_URL, getCoverImageDisplayURL } from "@/helpers/cover-image.helper";
type Props = {
project: IProject;
@ -206,10 +206,10 @@ export const ProjectCard = observer(function ProjectCard(props: Props) {
<div className="relative h-[118px] w-full rounded-t ">
<div className="absolute inset-0 z-[1] bg-gradient-to-t from-black/60 to-transparent" />
<img
src={getCoverImageDisplayURL(project.cover_image_url, DEFAULT_COVER_IMAGE_URL)}
<CoverImage
src={project.cover_image_url}
alt={project.name}
className="absolute left-0 top-0 h-full w-full rounded-t object-cover"
className="absolute left-0 top-0 h-full w-full rounded-t"
/>
<div className="absolute bottom-4 z-[1] flex h-10 w-full items-center justify-between gap-3 px-4">

View file

@ -10,9 +10,8 @@ import type { IProject } from "@plane/types";
// plane ui
import { getTabIndex } from "@plane/utils";
// components
import { CoverImage } from "@/components/common/cover-image";
import { ImagePickerPopover } from "@/components/core/image-picker-popover";
// helpers
import { DEFAULT_COVER_IMAGE_URL, getCoverImageDisplayURL } from "@/helpers/cover-image.helper";
// plane web imports
import { ProjectTemplateSelect } from "@/plane-web/components/projects/create/template-select";
@ -33,13 +32,11 @@ function ProjectCreateHeader(props: Props) {
return (
<div className="group relative h-44 w-full rounded-lg">
{coverImage && (
<img
src={getCoverImageDisplayURL(coverImage, DEFAULT_COVER_IMAGE_URL)}
className="absolute left-0 top-0 h-full w-full rounded-lg object-cover"
alt={t("project_cover_image_alt")}
/>
)}
<CoverImage
src={coverImage}
alt={t("project_cover_image_alt")}
className="absolute left-0 top-0 h-full w-full rounded-lg"
/>
<div className="absolute left-2.5 top-2.5">
<ProjectTemplateSelect handleModalClose={handleClose} />
</div>

View file

@ -12,10 +12,11 @@ import { EFileAssetType } from "@plane/types";
import type { IProject, IWorkspace } from "@plane/types";
import { CustomSelect, Input, TextArea } from "@plane/ui";
import { renderFormattedDate } from "@plane/utils";
import { CoverImage } from "@/components/common/cover-image";
import { ImagePickerPopover } from "@/components/core/image-picker-popover";
import { TimezoneSelect } from "@/components/global";
// helpers
import { DEFAULT_COVER_IMAGE_URL, getCoverImageDisplayURL, handleCoverImageChange } from "@/helpers/cover-image.helper";
import { handleCoverImageChange } from "@/helpers/cover-image.helper";
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
// hooks
import { useProject } from "@/hooks/store/use-project";
@ -200,11 +201,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {
<form onSubmit={handleSubmit(onSubmit)}>
<div className="relative h-44 w-full">
<div className="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" />
<img
src={getCoverImageDisplayURL(coverImage, DEFAULT_COVER_IMAGE_URL)}
alt="Project cover image"
className="h-44 w-full rounded-md object-cover"
/>
<CoverImage src={coverImage} alt="Project cover image" className="h-44 w-full rounded-md" />
<div className="z-5 absolute bottom-4 flex w-full items-end justify-between gap-3 px-4">
<div className="flex flex-grow gap-3 truncate">
<Controller