Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
34 changes: 21 additions & 13 deletions app/[user]/waves/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import { notFound, redirect } from "next/navigation";

export default async function WavesPage({
params,
}: {
readonly params?: Promise<{ user: string }> | undefined;
}) {
const resolvedParams = params ? await params : undefined;
const user = resolvedParams?.user;
if (!user) {
notFound();
}
redirect(`/${user}`);
import { createUserTabPage } from "@/app/[user]/_lib/userTabPageFactory";
import UserPageProfileWave from "@/components/user/waves/UserPageProfileWave";
import type { ApiIdentity } from "@/generated/models/ApiIdentity";
import {
USER_PAGE_TAB_IDS,
USER_PAGE_TAB_MAP,
} from "@/components/user/layout/userTabs.config";

function WaveTab({ profile }: { readonly profile: ApiIdentity }) {
return <UserPageProfileWave profile={profile} />;
}

const TAB_CONFIG = USER_PAGE_TAB_MAP[USER_PAGE_TAB_IDS.WAVES];

const { Page, generateMetadata } = createUserTabPage({
subroute: TAB_CONFIG.route,
metaLabel: TAB_CONFIG.metaLabel,
Tab: WaveTab,
});

export default Page;
export { generateMetadata };
30 changes: 30 additions & 0 deletions components/brain/my-stream/curations/CurationEmptyState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client";

interface CurationEmptyStateProps {
readonly curationTitle: string;
readonly containerClassName?: string | undefined;
readonly description?: string | undefined;
}

const DEFAULT_CONTAINER_CLASS_NAME =
"tw-flex tw-min-h-[20rem] tw-items-center tw-justify-center tw-px-6";

const DEFAULT_DESCRIPTION =
"This tab will show the drops added to this curation.";

export default function CurationEmptyState({
curationTitle,
containerClassName = DEFAULT_CONTAINER_CLASS_NAME,
description = DEFAULT_DESCRIPTION,
}: CurationEmptyStateProps) {
return (
<div className={containerClassName}>
<div className="tw-max-w-md tw-rounded-2xl tw-border tw-border-dashed tw-border-iron-700 tw-bg-iron-950/70 tw-px-6 tw-py-8 tw-text-center">
<p className="tw-mb-2 tw-text-base tw-font-semibold tw-text-iron-100">
{curationTitle} is empty
</p>
<p className="tw-mb-0 tw-text-sm tw-text-iron-400">{description}</p>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import CircleLoader, {
CircleLoaderSize,
} from "@/components/distribution-plan-tool/common/CircleLoader";
import CurationEmptyState from "@/components/brain/my-stream/curations/CurationEmptyState";
import { Spinner } from "@/components/dotLoader/DotLoader";
import CommonIntersectionElement from "@/components/utils/CommonIntersectionElement";
import Drop, { DropLocation } from "@/components/waves/drops/Drop";
import type { ExtendedDrop } from "@/helpers/waves/drop.helpers";
import { useCurationManagementPermission } from "@/hooks/useCurationManagementPermission";
import { useDropCurationMembershipMutation } from "@/hooks/drops/useDropCurationMembershipMutation";
import { useDropCurations } from "@/hooks/drops/useDropCurations";
import useDeviceInfo from "@/hooks/useDeviceInfo";
import useIsTouchDevice from "@/hooks/useIsTouchDevice";
import { useWaveDrops } from "@/hooks/useWaveDrops";
Expand All @@ -21,7 +22,8 @@ interface MyStreamWaveCurationContentProps {
readonly wave: ApiWave;
readonly curationId: string;
readonly curationName?: string | null | undefined;
readonly onDropClick: (drop: ExtendedDrop) => void;
readonly onDropClick?: ((drop: ExtendedDrop) => void) | undefined;
readonly constrainToViewport?: boolean | undefined;
}

function MyStreamWaveCurationDropItem({
Expand All @@ -37,7 +39,7 @@ function MyStreamWaveCurationDropItem({
readonly nextDrop: ExtendedDrop | null;
readonly curationId: string;
readonly canManageActiveCuration: boolean;
readonly onDropClick: (drop: ExtendedDrop) => void;
readonly onDropClick?: ((drop: ExtendedDrop) => void) | undefined;
}) {
const { hasTouchScreen, isApp } = useDeviceInfo();
const isTouchDevice = useIsTouchDevice();
Expand Down Expand Up @@ -129,6 +131,7 @@ export default function MyStreamWaveCurationContent({
curationId,
curationName,
onDropClick,
constrainToViewport = true,
}: MyStreamWaveCurationContentProps) {
const { leaderboardViewStyle } = useLayout();
const { drops, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
Expand All @@ -137,9 +140,9 @@ export default function MyStreamWaveCurationContent({
curationId,
});
const permissionProbeDropId = drops[0]?.id ?? "";
const { data: permissionProbeCurations = [] } = useDropCurations({
dropId: permissionProbeDropId,
enabled: Boolean(permissionProbeDropId),
const canManageActiveCuration = useCurationManagementPermission({
curationId,
probeDropId: permissionProbeDropId,
});

const isInitialLoading = isFetching && drops.length === 0;
Expand All @@ -156,9 +159,6 @@ export default function MyStreamWaveCurationContent({
);

const curationTitle = curationName?.trim() ?? "Curation";
const canManageActiveCuration =
permissionProbeCurations.find((curation) => curation.id === curationId)
?.authenticated_user_can_curate ?? false;

const renderedDrops = useMemo(
() =>
Expand Down Expand Up @@ -186,16 +186,14 @@ export default function MyStreamWaveCurationContent({
);
} else if (drops.length === 0) {
content = (
<div className="tw-flex tw-flex-1 tw-items-center tw-justify-center tw-px-6">
<div className="tw-max-w-md tw-rounded-2xl tw-border tw-border-dashed tw-border-iron-700 tw-bg-iron-950/70 tw-px-6 tw-py-8 tw-text-center">
<p className="tw-mb-2 tw-text-base tw-font-semibold tw-text-iron-100">
{curationTitle} is empty
</p>
<p className="tw-mb-0 tw-text-sm tw-text-iron-400">
This tab will show the drops added to this curation.
</p>
</div>
</div>
<CurationEmptyState
curationTitle={curationTitle}
containerClassName={
constrainToViewport
? "tw-flex tw-flex-1 tw-items-center tw-justify-center tw-px-6"
: undefined
}
/>
);
} else {
content = (
Expand All @@ -220,8 +218,12 @@ export default function MyStreamWaveCurationContent({

return (
<div
className="tw-flex tw-h-full tw-min-h-0 tw-w-full tw-min-w-0 tw-flex-grow tw-flex-col tw-overflow-y-auto tw-overflow-x-hidden tw-scrollbar-thin tw-scrollbar-track-iron-800 tw-scrollbar-thumb-iron-500 desktop-hover:hover:tw-scrollbar-thumb-iron-300"
style={leaderboardViewStyle}
className={
constrainToViewport
? "tw-flex tw-h-full tw-min-h-0 tw-w-full tw-min-w-0 tw-flex-grow tw-flex-col tw-overflow-y-auto tw-overflow-x-hidden tw-scrollbar-thin tw-scrollbar-track-iron-800 tw-scrollbar-thumb-iron-500 desktop-hover:hover:tw-scrollbar-thumb-iron-300"
: "tw-flex tw-min-h-0 tw-w-full tw-min-w-0 tw-flex-col"
}
style={constrainToViewport ? leaderboardViewStyle : undefined}
>
{content}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function MyStreamWaveCreateCurationAction({

return (
<>
<div className="tw-flex tw-flex-shrink-0 tw-items-center tw-gap-2 tw-pr-2 sm:tw-pr-4">
<div className="tw-flex tw-flex-shrink-0 tw-items-center tw-gap-2">
{showCreateFirstCurationCallout ? (
<button
type="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default function DropListItemContentMedia({
disableAutoPlay = false,
imageObjectPosition,
imageScale = ImageScale.AUTOx800,
naturalHeight = false,
htmlIframeContainerClassName,
htmlPreviewImageUrl,
loadStrategy = "in-view",
Expand All @@ -47,6 +48,7 @@ export default function DropListItemContentMedia({
readonly disableAutoPlay?: boolean | undefined;
readonly imageObjectPosition?: string | undefined;
readonly imageScale?: ImageScale | undefined;
readonly naturalHeight?: boolean | undefined;
readonly htmlIframeContainerClassName?: string | undefined;
readonly htmlPreviewImageUrl?: string | undefined;
readonly loadStrategy?: MediaLoadStrategy | undefined;
Expand Down Expand Up @@ -87,6 +89,7 @@ export default function DropListItemContentMedia({
disableModal={disableModal}
imageObjectPosition={imageObjectPosition}
imageScale={imageScale}
naturalHeight={naturalHeight}
loadStrategy={loadStrategy}
/>
);
Expand Down
Loading
Loading