All files / src/screens/components MetaSection.tsx

80% Statements 4/5
73.33% Branches 11/15
100% Functions 3/3
100% Lines 4/4

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113                                                    10x     1x                                                                                                                           27x   27x                                      
import { ChevronDown, ChevronUp, Clock } from 'lucide-react'
import { type RecipeDetail, type ScaleResponse } from '../../api/client'
import { formatTime } from '../../lib/formatting'
import ServingsDisplay from './ServingsDisplay'
 
interface MetaSectionProps {
  recipe: RecipeDetail
  metaExpanded: boolean
  setMetaExpanded: (expanded: boolean) => void
  canShowServingAdjustment: boolean
  servings: number | null
  scaledData: ScaleResponse | null
  scalingLoading: boolean
  onServingChange: (delta: number) => void
}
 
export default function MetaSection({
  recipe,
  metaExpanded,
  setMetaExpanded,
  canShowServingAdjustment,
  servings,
  scaledData,
  scalingLoading,
  onServingChange,
}: MetaSectionProps) {
  return (
    <div className="border-b border-border">
      <button
        onClick={() => setMetaExpanded(!metaExpanded)}
        className="flex w-full items-center justify-between px-4 py-3 text-left"
      >
        <span className="text-sm font-medium text-foreground">
          Recipe Details
        </span>
        {metaExpanded ? (
          <ChevronUp className="h-5 w-5 text-muted-foreground" />
        ) : (
          <ChevronDown className="h-5 w-5 text-muted-foreground" />
        )}
      </button>
 
      {metaExpanded && (
        <div className="flex flex-wrap gap-4 px-4 pb-4">
          <TimeDisplay
            label="Prep"
            time={recipe.prep_time}
            adjustedTime={scaledData?.prep_time_adjusted}
          />
          <TimeDisplay
            label="Cook"
            time={recipe.cook_time}
            adjustedTime={scaledData?.cook_time_adjusted}
          />
          <TimeDisplay
            label="Total"
            time={recipe.total_time}
            adjustedTime={scaledData?.total_time_adjusted}
          />
 
          <ServingsDisplay
            recipe={recipe}
            canShowServingAdjustment={canShowServingAdjustment}
            servings={servings}
            scaledData={scaledData}
            scalingLoading={scalingLoading}
            onServingChange={onServingChange}
          />
 
          {/* Yields (if different from servings) */}
          {recipe.yields && !recipe.servings && (
            <div className="flex items-center gap-2 text-sm">
              <span className="text-muted-foreground">Yields:</span>
              <span className="text-foreground">{recipe.yields}</span>
            </div>
          )}
        </div>
      )}
    </div>
  )
}
 
function TimeDisplay({
  label,
  time,
  adjustedTime,
}: {
  label: string
  time: number | null
  adjustedTime: number | null | undefined
}) {
  Iif (!time) return null
 
  return (
    <div className="flex items-center gap-2 text-sm">
      <Clock className="h-4 w-4 text-muted-foreground" />
      <span className="text-muted-foreground">{label}:</span>
      <span className="text-foreground">
        {adjustedTime && adjustedTime !== time ? (
          <>
            {formatTime(adjustedTime)}
            <span className="ml-1 text-muted-foreground">
              (was {formatTime(time)})
            </span>
          </>
        ) : (
          formatTime(adjustedTime ?? time)
        )}
      </span>
    </div>
  )
}
 
← Back to Dashboard