All files / web/src/components/create/abacus DesignShareToggle.tsx

100% Statements 70/70
100% Branches 10/10
100% Functions 4/4
100% Lines 70/70

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 711x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 22x 22x 22x 22x 22x 22x 4x 4x 8x 8x 8x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 1x 1x 1x 1x 1x 22x 22x 22x 22x  
'use client'
 
// DesignShareToggle (Gitea #24) — who may open the saved design link.
//
// Deliberately NOT a third verb. The rail already has "make this {player}'s
// abacus" (about a PERSON) and "🔗 Copy design link" (about an ADDRESS); a
// "Share" button would compete with both. Sharing is a PROPERTY of the link,
// so it renders as a two-segment readout under the chip — grammatically it
// can't be mistaken for another save.
//
// One click each way, and the control is its own undo: because sharing is a
// flag on the design row rather than a minted code, turning it back on revives
// the very same URL. That is why there's no confirm modal and no separate Undo
// affordance. Hidden entirely unless the viewer owns a currently-saved design.
 
import { button, STUDIO } from '@/components/studio/theme'
import { useAbacusStudio } from './AbacusStudioContext'
 
export function DesignShareToggle() {
  const { designShared, canShareDesign, setDesignShared, designSharePending, designShareFailed } =
    useAbacusStudio()
 
  // Also covers `undefined` from a partial context — the control simply isn't
  // there for anyone who has nothing saved, or whose saved link isn't theirs.
  if (!canShareDesign) return null
 
  const segmentStyle = (active: boolean) => ({
    ...button('pill', { on: active, disabled: designSharePending }),
    cursor: designSharePending ? 'default' : 'pointer',
  })
 
  return (
    <div
      data-element="abacus-design-share"
      style={{ display: 'flex', flexDirection: 'column', gap: 4 }}
    >
      <span style={STUDIO.type.eyebrow}>Who can open it</span>
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
        <button
          type="button"
          data-action="set-design-private"
          onClick={() => setDesignShared(false)}
          disabled={designSharePending}
          title="Only your account can open this link."
          style={segmentStyle(!designShared)}
        >
          🔒 Only me
        </button>
        <button
          type="button"
          data-action="set-design-shared"
          onClick={() => setDesignShared(true)}
          disabled={designSharePending}
          title="Anyone with this link can open and copy this design — including any name engraved on it. You can turn this off again, but you can't un-copy a link someone already took."
          style={segmentStyle(designShared)}
        >
          🔗 Anyone with the link
        </button>
      </div>
      {designShareFailed && (
        <span
          data-element="abacus-design-share-error"
          style={{ ...STUDIO.type.note, color: STUDIO.color.dangerInline }}
        >
          Couldn&apos;t change who can open this — try again.
        </span>
      )}
    </div>
  )
}