File size: 3,149 Bytes
ab75c71
b1ecc22
 
 
 
 
fd2aa6b
b1ecc22
ab75c71
fd2aa6b
b1ecc22
fd2aa6b
ab75c71
 
fd2aa6b
ab75c71
b1ecc22
 
 
 
 
ab75c71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b1ecc22
 
 
 
 
 
 
 
 
 
ab75c71
 
 
 
 
 
b1ecc22
 
 
 
 
 
 
 
ab75c71
b1ecc22
 
ab75c71
b1ecc22
 
 
 
 
 
 
 
 
 
 
fd2aa6b
b1ecc22
 
fd2aa6b
 
 
b1ecc22
fd2aa6b
b1ecc22
 
 
 
fd2aa6b
 
b1ecc22
fd2aa6b
 
 
 
 
 
b1ecc22
 
 
fd2aa6b
b1ecc22
 
 
 
 
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
import { useEffect, useRef } from "react"
import Image from "next/image"
import { useDrag, useDrop } from "react-dnd"

import { Game } from "@/app/games/types"
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip"
import { DropZoneTarget, InventoryEvent, InventoryItem, OnInventoryEvent } from "@/types"

import { store } from "@/app/store"
import { cn } from "@/lib/utils"

export function DraggableItem({ game, item, isLoading, onEvent }: {
  game: Game
  item: InventoryItem
  isLoading: boolean
  onEvent: OnInventoryEvent
}) {
  const [{ isDragging }, drag] = useDrag(() => ({
    type: "item",
    item,
    end: (item, monitor) => {
      const target = monitor.getDropResult<DropZoneTarget>()
      if (item && target) {
        if ( target.type === "InventoryItem" && item.name === target.name) {
          // user is trying to drop the item on itself.. that's not possible
          return
        }
        onEvent(
          target.type === "Actionnable"
            ? "DroppedOnActionnable"
            : "DroppedOnAnotherItem",
          item,
          {
            name: target.name,
            title: target.title,
            description: target.description
          }
        )
      }
    },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
      handlerId: monitor.getHandlerId(),
    }),
  }))

  const [{ isOver, canDrop }, drop] = useDrop({
    accept: "item",
    drop: (): DropZoneTarget => ({
      type: "InventoryItem",
      name: item.name,
      title: item.title,
      description: item.description
    }),
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  })

  useEffect(() => {
    if (isDragging) {
      store.currentlyDraggedItem = item
      onEvent("Grabbing", item)
    } else {
      store.currentlyDraggedItem = undefined
      onEvent("DroppedBackToInventory", item)
    }
  }, [isDragging])

  return (
    <Tooltip key={item.name}>
      <TooltipTrigger asChild>
        <div
          ref={drag}
          key={item.name}
          onClick={() => onEvent("ClickOnItem", item)}
          className={cn(
          "bg-gray-100 rounded-2xl overflow-hidden",
          "transition-all duration-200",
          isLoading
            ? `scale-0`
            : `scale-100`,
          isDragging
            ? "brightness-100 scale-110 border border-stone-300 shadow-2xl cursor-grabbing"
            : "brightness-90 border-2 shadow-md cursor-grab",
          isOver && canDrop
            ? "border-stone-100"
            : "border-stone-600",
          "hover:brightness-100 hover:scale-110 hover:border hover:border-stone-300 hover:shadow-2xl",
          )}>
        <div ref={drop}>
            <Image
              src={`/inventories/${game.type}/${item.name}.jpeg`}
              width={1024}
              height={1024}
              alt={item.title}
            />
        </div>
      </div>
      </TooltipTrigger>
      <TooltipContent side="right" className="translate-x-[5px] translate-y-[-8px]">
        <p className="text-xl">{item.title}</p>
      </TooltipContent>
    </Tooltip>
  )
}