UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: канонизация окна и helper обложек проекта
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 379 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 219 KiB |
|
|
@ -215,23 +215,23 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
|
|||
|
||||
{isOpen && (
|
||||
<Popover.Panel
|
||||
className="absolute right-0 z-20 mt-2 rounded-md border border-subtle bg-surface-1 shadow-raised-200"
|
||||
className="nodedc-glass-modal nodedc-glass-popup-surface absolute right-0 z-20 mt-3 overflow-hidden rounded-[1.75rem]"
|
||||
static
|
||||
>
|
||||
<div
|
||||
ref={imagePickerRef}
|
||||
className="flex h-96 w-80 flex-col overflow-auto rounded border border-subtle bg-surface-1 shadow-raised-200 md:h-[36rem] md:w-[36rem]"
|
||||
className="flex h-[32rem] w-[21rem] flex-col overflow-hidden rounded-[1.75rem] md:h-[38rem] md:w-[38rem]"
|
||||
>
|
||||
<Tabs defaultValue={enabledTabs[0]?.key || "images"} className="flex h-full flex-col p-3">
|
||||
<Tabs.List className="flex rounded bg-layer-3 p-1">
|
||||
<Tabs defaultValue={enabledTabs[0]?.key || "images"} className="flex h-full flex-col px-4 pt-4 pb-3">
|
||||
<Tabs.List className="rounded-[1rem] bg-layer-3/80 p-1">
|
||||
{enabledTabs.map((tab) => (
|
||||
<Tabs.Trigger key={tab.key} value={tab.key} size="md">
|
||||
<Tabs.Trigger key={tab.key} value={tab.key} size="md" className="rounded-[0.875rem]">
|
||||
{tab.title}
|
||||
</Tabs.Trigger>
|
||||
))}
|
||||
<Tabs.Indicator />
|
||||
</Tabs.List>
|
||||
<div className="vertical-scrollbar mt-3 scrollbar-sm flex-1 overflow-x-hidden overflow-y-auto p-3">
|
||||
<div className="vertical-scrollbar mt-4 scrollbar-sm flex-1 overflow-x-hidden overflow-y-auto px-1 pb-1">
|
||||
<Tabs.Content value="unsplash" className="h-full w-full space-y-4">
|
||||
{(unsplashImages || !unsplashError) && (
|
||||
<>
|
||||
|
|
@ -254,21 +254,26 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
|
|||
onChange={(e) => setFormData({ ...formData, search: e.target.value })}
|
||||
ref={ref}
|
||||
placeholder={t("image_picker.search_placeholder")}
|
||||
className="w-full text-13"
|
||||
className="nodedc-modal-input w-full !px-4 !py-3 text-13"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Button variant="primary" size="xl" onClick={() => setSearchParams(formData.search)}>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="lg"
|
||||
className="nodedc-modal-primary-button min-w-[8rem]"
|
||||
onClick={() => setSearchParams(formData.search)}
|
||||
>
|
||||
{t("image_picker.search_button")}
|
||||
</Button>
|
||||
</div>
|
||||
{unsplashImages ? (
|
||||
unsplashImages.length > 0 ? (
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="grid grid-cols-4 gap-3">
|
||||
{unsplashImages.map((image) => (
|
||||
<div
|
||||
key={image.id}
|
||||
className="relative col-span-2 aspect-video md:col-span-1"
|
||||
className="nodedc-modal-field relative col-span-2 aspect-video overflow-hidden rounded-[1rem] p-0 md:col-span-1"
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
onChange(image.urls.regular);
|
||||
|
|
@ -277,7 +282,7 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
|
|||
<img
|
||||
src={image.urls.small}
|
||||
alt={image.alt_description}
|
||||
className="absolute top-0 left-0 h-full w-full cursor-pointer rounded-sm object-cover"
|
||||
className="absolute inset-0 h-full w-full cursor-pointer rounded-[1rem] object-cover transition-transform duration-200 hover:scale-[1.02]"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
|
@ -301,36 +306,36 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
|
|||
)}
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="images" className="h-full w-full space-y-4">
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="grid grid-cols-4 gap-3">
|
||||
{Object.values(STATIC_COVER_IMAGES).map((imageUrl, index) => (
|
||||
<div
|
||||
key={imageUrl}
|
||||
className="relative col-span-2 aspect-video md:col-span-1"
|
||||
className="nodedc-modal-field relative col-span-2 aspect-video overflow-hidden rounded-[1rem] p-0 md:col-span-1"
|
||||
onClick={() => handleStaticImageSelect(imageUrl)}
|
||||
>
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt={t("image_picker.cover_image_alt", { index: index + 1 })}
|
||||
className="absolute top-0 left-0 h-full w-full cursor-pointer rounded-sm object-cover transition-opacity hover:opacity-80"
|
||||
className="absolute inset-0 h-full w-full cursor-pointer rounded-[1rem] object-cover transition-transform duration-200 hover:scale-[1.02]"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Tabs.Content>
|
||||
<Tabs.Content value="upload" className="h-full w-full">
|
||||
<div className="flex h-full w-full flex-col gap-y-2">
|
||||
<div className="flex h-full w-full flex-col gap-y-3">
|
||||
<div className="flex w-full flex-1 items-center gap-3">
|
||||
<div
|
||||
{...getRootProps()}
|
||||
className={`relative grid h-full w-full cursor-pointer place-items-center rounded-lg p-12 text-center focus:ring-2 focus:ring-accent-strong focus:ring-offset-2 focus:outline-none ${
|
||||
className={`nodedc-modal-field relative grid h-full w-full cursor-pointer place-items-center overflow-hidden rounded-[1.35rem] p-6 text-center ${
|
||||
(image === null && isDragActive) || !value
|
||||
? "border-2 border-dashed border-subtle hover:bg-surface-2"
|
||||
? "border-2 border-dashed border-subtle/80 hover:bg-white/6"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className="absolute top-0 right-0 z-40 -translate-y-1/2 rounded-sm bg-surface-2 px-2 py-0.5 text-11 font-medium text-secondary"
|
||||
className="nodedc-modal-chip absolute top-3 right-3 z-40 !min-h-0 !px-3 !py-1 text-11 font-medium"
|
||||
>
|
||||
{t("image_picker.edit")}
|
||||
</button>
|
||||
|
|
@ -339,7 +344,7 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
|
|||
<img
|
||||
src={image ? URL.createObjectURL(image) : getCoverImageDisplayURL(value, "")}
|
||||
alt="image"
|
||||
className="h-full w-full rounded-lg object-cover"
|
||||
className="h-full w-full rounded-[1rem] object-cover"
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
|
|
@ -363,19 +368,20 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
|
|||
|
||||
<p className="text-13 text-secondary">{t("image_picker.supported_formats")}</p>
|
||||
|
||||
<div className="flex h-12 items-start justify-end gap-2">
|
||||
<div className="mt-auto flex items-start justify-end gap-3 border-t border-subtle/70 pt-4">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
setImage(null);
|
||||
}}
|
||||
className="nodedc-modal-secondary-button min-w-[8rem]"
|
||||
>
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
className="w-full"
|
||||
className="nodedc-modal-primary-button min-w-[12rem]"
|
||||
onClick={handleSubmit}
|
||||
disabled={!image}
|
||||
loading={isImageUploading}
|
||||
|
|
|
|||
|
|
@ -7,33 +7,16 @@
|
|||
import type { EFileAssetType } from "@plane/types";
|
||||
import { getFileURL } from "@plane/utils";
|
||||
|
||||
import CoverImage1 from "@/app/assets/cover-images/image_1.jpg?url";
|
||||
import CoverImage1 from "@/app/assets/cover-images/image_1.png?url";
|
||||
import CoverImage10 from "@/app/assets/cover-images/image_10.jpg?url";
|
||||
import CoverImage11 from "@/app/assets/cover-images/image_11.jpg?url";
|
||||
import CoverImage11 from "@/app/assets/cover-images/image_11.png?url";
|
||||
import CoverImage12 from "@/app/assets/cover-images/image_12.jpg?url";
|
||||
import CoverImage13 from "@/app/assets/cover-images/image_13.jpg?url";
|
||||
import CoverImage14 from "@/app/assets/cover-images/image_14.jpg?url";
|
||||
import CoverImage15 from "@/app/assets/cover-images/image_15.jpg?url";
|
||||
import CoverImage16 from "@/app/assets/cover-images/image_16.jpg?url";
|
||||
import CoverImage17 from "@/app/assets/cover-images/image_17.jpg?url";
|
||||
import CoverImage18 from "@/app/assets/cover-images/image_18.jpg?url";
|
||||
import CoverImage19 from "@/app/assets/cover-images/image_19.jpg?url";
|
||||
import CoverImage2 from "@/app/assets/cover-images/image_2.jpg?url";
|
||||
import CoverImage20 from "@/app/assets/cover-images/image_20.jpg?url";
|
||||
import CoverImage21 from "@/app/assets/cover-images/image_21.jpg?url";
|
||||
import CoverImage22 from "@/app/assets/cover-images/image_22.jpg?url";
|
||||
import CoverImage23 from "@/app/assets/cover-images/image_23.jpg?url";
|
||||
import CoverImage24 from "@/app/assets/cover-images/image_24.jpg?url";
|
||||
import CoverImage25 from "@/app/assets/cover-images/image_25.jpg?url";
|
||||
import CoverImage26 from "@/app/assets/cover-images/image_26.jpg?url";
|
||||
import CoverImage27 from "@/app/assets/cover-images/image_27.jpg?url";
|
||||
import CoverImage28 from "@/app/assets/cover-images/image_28.jpg?url";
|
||||
import CoverImage29 from "@/app/assets/cover-images/image_29.jpg?url";
|
||||
import CoverImage3 from "@/app/assets/cover-images/image_3.jpg?url";
|
||||
import CoverImage4 from "@/app/assets/cover-images/image_4.jpg?url";
|
||||
import CoverImage5 from "@/app/assets/cover-images/image_5.jpg?url";
|
||||
import CoverImage6 from "@/app/assets/cover-images/image_6.jpg?url";
|
||||
import CoverImage7 from "@/app/assets/cover-images/image_7.jpg?url";
|
||||
import CoverImage6 from "@/app/assets/cover-images/image_6.webp?url";
|
||||
import CoverImage7 from "@/app/assets/cover-images/image_7.webp?url";
|
||||
import CoverImage8 from "@/app/assets/cover-images/image_8.jpg?url";
|
||||
import CoverImage9 from "@/app/assets/cover-images/image_9.jpg?url";
|
||||
|
||||
|
|
@ -58,23 +41,6 @@ export const STATIC_COVER_IMAGES = {
|
|||
IMAGE_10: CoverImage10,
|
||||
IMAGE_11: CoverImage11,
|
||||
IMAGE_12: CoverImage12,
|
||||
IMAGE_13: CoverImage13,
|
||||
IMAGE_14: CoverImage14,
|
||||
IMAGE_15: CoverImage15,
|
||||
IMAGE_16: CoverImage16,
|
||||
IMAGE_17: CoverImage17,
|
||||
IMAGE_18: CoverImage18,
|
||||
IMAGE_19: CoverImage19,
|
||||
IMAGE_20: CoverImage20,
|
||||
IMAGE_21: CoverImage21,
|
||||
IMAGE_22: CoverImage22,
|
||||
IMAGE_23: CoverImage23,
|
||||
IMAGE_24: CoverImage24,
|
||||
IMAGE_25: CoverImage25,
|
||||
IMAGE_26: CoverImage26,
|
||||
IMAGE_27: CoverImage27,
|
||||
IMAGE_28: CoverImage28,
|
||||
IMAGE_29: CoverImage29,
|
||||
} as const;
|
||||
|
||||
export const DEFAULT_COVER_IMAGE_URL = STATIC_COVER_IMAGES.IMAGE_1;
|
||||
|
|
|
|||