summaryrefslogtreecommitdiff
path: root/frontend/src/components/ElementList.tsx
blob: 04650c43060e6249b9da4b3564e81ab38f5e7a9d (plain)
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
import { FC, useEffect, useState } from 'react';
import { Element } from '../types';
import ElementView from './ElementView';
import Dialog from './Dialog';
import ElementCreator from './ElementCreator';
import { userStore } from '../stores';
import toast from 'react-hot-toast';

const ElementList: FC = () => {
  const [elements, setElements] = useState<Element[]>([]);
  const [elementCreatorVisible, setElementCreatorVisible] =
    useState<boolean>(false);
  const [creatorFirstElementId, setCreatorFirstElementId] = useState<
    number | undefined
  >(undefined);
  const [creatorSecondElementId, setCreatorSecondElementId] = useState<
    number | undefined
  >(undefined);
  const user = userStore((store) => store.user);

  useEffect(() => {
    const initialElements: number[] = [1, 2, 3, 4];

    const elementStateString = localStorage.getItem('elementState');
    if (elementStateString != null) {
      setElements(JSON.parse(elementStateString));
      return;
    }

    const fetchElements = async () => {
      const elems: Element[] = [];

      for (const elemId of initialElements) {
        const response = await fetch(`/api/element/${elemId}`);
        const elem: Element = await response.json();
        elems.push(elem);
      }

      localStorage.setItem('elementState', JSON.stringify(elems));
      setElements(elems);
    };

    fetchElements().catch(console.error);
  }, []);

  useEffect(() => {
    if (elements.length != 0) {
      localStorage.setItem('elementState', JSON.stringify(elements));
    }
  }, [elements]);

  const createOnElementCombine = (firstElementId: number) => {
    return async (secondElementId: number) => {
      const combineResponse = await fetch(
        `/api/element/combine?firstElementId=${firstElementId}&secondElementId=${secondElementId}`,
      );
      if (combineResponse.status == 404) {
        console.log("Element doesn't exist");
        if (!user) {
          toast("You have discovered a new element but need to log in to name it");
          return;
        }
        setCreatorFirstElementId(firstElementId);
        setCreatorSecondElementId(secondElementId);
        setElementCreatorVisible(true);
        return;
      }

      const newElem: Element = await combineResponse.json();
      if (elements.find((e) => e.id == newElem.id)) {
        toast(`You have already discovered ${newElem.name}`);
        return;
      }
      setElements((elems) => elems.concat(newElem));
    };
  };

  return (
    <div className="p-3 flex gap-3">
      {elements.map((elem) => (
        <ElementView
          key={elem.id}
          interactive={true}
          isPreview={false}
          element={elem}
          onElementCombine={createOnElementCombine(elem.id)}
        />
      ))}
      <Dialog
        visible={elementCreatorVisible}
        closeDialog={() => {
          setElementCreatorVisible(false);
        }}>
        <ElementCreator
          firstElementId={creatorFirstElementId}
          secondElementId={creatorSecondElementId}
          closeDialog={() => setElementCreatorVisible(false)}
        />
      </Dialog>
    </div>
  );
};

export default ElementList;