Skip to content

Commit

Permalink
fix: Made long notes, history, and description fields collapsible (#503)
Browse files Browse the repository at this point in the history
Signed-off-by: Johannes Groß <[email protected]>
  • Loading branch information
jo-gross authored Jan 20, 2025
1 parent 1591e80 commit 87ded4e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 4 deletions.
48 changes: 48 additions & 0 deletions components/ExpandableText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';

interface ExpandableTextProps {
text: string;
}

export interface ExpandableTextHandle {
recalculateClamp: () => void;
}

const ExpandableText = forwardRef<ExpandableTextHandle, ExpandableTextProps>(({ text }, ref) => {
const textRef = useRef<HTMLDivElement | null>(null); // Typisiert als HTMLDivElement
const [isClamped, setIsClamped] = useState(false);

const checkClamp = () => {
if (textRef.current) {
setIsClamped(textRef.current.scrollHeight > textRef.current.clientHeight);
}
};

useImperativeHandle(ref, () => ({
recalculateClamp: checkClamp,
}));

useEffect(() => {
checkClamp();
}, [text]);

return (
<details className="group">
<summary className={`${isClamped ? 'cursor-pointer' : ''} flex w-full list-none flex-col`}>
<div ref={textRef} className="long-text-format line-clamp-3 group-open:line-clamp-none">
{text}
</div>
{isClamped && (
<>
<div className="w-full p-1 text-center underline group-open:hidden">mehr anzeigen</div>
<div className="hidden p-1 text-center underline group-open:inline">weniger anzeigen</div>
</>
)}
</summary>
</details>
);
});

ExpandableText.displayName = 'ExpandableText';

export default ExpandableText;
48 changes: 44 additions & 4 deletions components/cocktails/CocktailRecipeCardItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CocktailRecipeFull } from '../../models/CocktailRecipeFull';
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react';
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { CompactCocktailRecipeInstruction } from './CompactCocktailRecipeInstruction';
import { ShowCocktailInfoButton } from './ShowCocktailInfoButton';
import { useRouter } from 'next/router';
Expand All @@ -9,9 +9,11 @@ import { fetchCocktail } from '../../lib/network/cocktails';
import { CocktailRating } from '@prisma/client';
import { fetchCocktailRatings } from '../../lib/network/cocktailRatings';
import StatisticActions from '../StatisticActions';
import ExpandableText, { ExpandableTextHandle } from '../ExpandableText';

export type CocktailRecipeOverviewItemRef = {
refresh: () => void;
recalculateClamp: () => void;
};

export type CocktailRecipeOverviewItemProps = {
Expand Down Expand Up @@ -55,8 +57,19 @@ const CocktailRecipeCardItem = forwardRef<CocktailRecipeOverviewItemRef, Cocktai
refresh();
}, [refresh]);

const expandableRefs = useRef<Record<string, Record<string, ExpandableTextHandle | null>>>({});

const recalculateClamp = useCallback(() => {
Object.values(expandableRefs.current).forEach((textRefs) => Object.values(textRefs).forEach((expandableText) => expandableText?.recalculateClamp()));
}, []);

useEffect(() => {
recalculateClamp();
}, [recalculateClamp]);

useImperativeHandle(ref, () => ({
refresh,
recalculateClamp,
}));

const cocktailRecipe = typeof props.cocktailRecipe === 'string' ? loadedCocktailRecipe : props.cocktailRecipe;
Expand Down Expand Up @@ -92,21 +105,48 @@ const CocktailRecipeCardItem = forwardRef<CocktailRecipeOverviewItemRef, Cocktai
<>
<div className={'border-b border-base-100'}></div>
<div className={'font-bold'}>Zubereitungsnotizen</div>
<div className={'long-text-format'}>{cocktailRecipe.notes}</div>
<div className={'pl-2'}>
<ExpandableText
text={cocktailRecipe.notes}
ref={(el) => {
if (!expandableRefs.current[cocktailRecipe.id]) expandableRefs.current[cocktailRecipe.id] = {};
expandableRefs.current[cocktailRecipe.id]['notes'] = el;
}}
/>
{/*<div className={'long-text-format'}>{cocktailRecipe.notes}</div>*/}
</div>
</>
)}
{props.showDescription && cocktailRecipe.description && (
<>
<div className={'border-b border-base-100'}></div>
<div className={'font-bold'}>Allgemeine Beschreibung</div>
<div className={'long-text-format'}>{cocktailRecipe.description}</div>
<div className={'pl-2'}>
<ExpandableText
text={cocktailRecipe.description}
ref={(el) => {
if (!expandableRefs.current[cocktailRecipe.id]) expandableRefs.current[cocktailRecipe.id] = {};
expandableRefs.current[cocktailRecipe.id]['description'] = el;
}}
/>
{/*<div className={'long-text-format'}>{cocktailRecipe.description}</div>*/}
</div>
</>
)}
{props.showHistory && cocktailRecipe.history && (
<>
<div className={'border-b border-base-100'}></div>
<div className={'font-bold'}>Geschichte und Entstehung</div>
<div className={'long-text-format'}>{cocktailRecipe.history}</div>
<div className={'pl-2'}>
<ExpandableText
text={cocktailRecipe.history}
ref={(el) => {
if (!expandableRefs.current[cocktailRecipe.id]) expandableRefs.current[cocktailRecipe.id] = {};
expandableRefs.current[cocktailRecipe.id]['history'] = el;
}}
/>
</div>
{/*<div className={'long-text-format'}>{cocktailRecipe.history}</div>*/}
</>
)}

Expand Down
11 changes: 11 additions & 0 deletions pages/workspaces/[workspaceId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,17 @@ export default function OverviewPage() {
}
}, []);

const triggerAllCocktailCardRefresh = useCallback(() => {
Object.keys(cocktailItemRefs.current).forEach((cocktailId) => {
if (cocktailItemRefs.current[cocktailId]) {
cocktailItemRefs.current[cocktailId]?.recalculateClamp();
}
});
}, []);
useEffect(() => {
triggerAllCocktailCardRefresh();
}, [lessItems]);

return (
<>
<Head>
Expand Down

0 comments on commit 87ded4e

Please sign in to comment.