ZacharyFolk / sandbox

My digital business card, blog, and sandbox for various JS experiments
https://folk.codes
0 stars 0 forks source link

Magnetic poetry #32

Open ZacharyFolk opened 1 year ago

ZacharyFolk commented 1 year ago

https://react-dnd.github.io/react-dnd/docs/tutorial

https://codepen.io/Daniel_Silber-Baker/pen/egMGyb

https://github.com/ZacharyFolk/birthday-game/blob/master/util/words.txt

ZacharyFolk commented 1 year ago

{ word: 'saunter', type: 'verb' }, { word: 'languidly', type: 'adverb' }, { word: 'cogitate', type: 'verb' }, { word: 'luminescent', type: 'adjective' }, { word: 'dulcet', type: 'adjective' }, { word: 'flummox', type: 'verb' }, { word: 'higgledy-piggledy', type: 'adverb' }, { word: 'eccentric', type: 'adjective' }, { word: 'palaver', type: 'verb' }, { word: 'supercilious', type: 'adjective' }, { word: 'welter', type: 'verb' }, { word: 'whippersnapper', type: 'noun' }, { word: 'ebullience', type: 'noun' }, { word: 'fandango', type: 'noun' }, { word: 'jubilant', type: 'adjective' }, { word: 'knell', type: 'noun' }, { word: 'lachrymose', type: 'adjective' }, { word: 'milquetoast', type: 'noun' }, { word: 'nihilist', type: 'noun' }, { word: 'obsequious', type: 'adjective' }, { word: 'perspicacious', type: 'adjective' }, { word: 'quixotic', type: 'adjective' }, { word: 'repartee', type: 'noun' }, { word: 'sagacious', type: 'adjective' }, { word: 'toady', type: 'noun' }, { word: 'unctuous', type: 'adjective' }, { word: 'visceral', type: 'adjective' }, { word: 'winsome', type: 'adjective' }, { word: 'xenophobe', type: 'noun' }, { word: 'yawner', type: 'noun' }, { word: 'zephyr', type: 'noun' }, { word: 'capricious', type: 'adjective' }, { word: 'curmudgeon', type: 'noun' }, { word: 'droll', type: 'adjective' }, { word: 'eccentric', type: 'adjective' }, { word: 'felicity', type: 'noun' }, { word: 'guffaw', type: 'verb' }, { word: 'hapless', type: 'adjective' }, { word: 'inchoate', type: 'adjective' }, { word: 'jubilant', type: 'adjective' }, { word: 'ken', type: 'verb' },

import React, { useState, useRef } from 'react';
import { useDrag, useDrop } from 'react-dnd';

const words = [
  { word: 'saunter', type: 'verb' },
  { word: 'languidly', type: 'adverb' },
  // ...
];

function MagneticPoetry() {
  const [stanza, setStanza] = useState([]);
  const [magnets, setMagnets] = useState(words);

  function moveMagnet(id, atIndex) {
    const { word, type } = magnets.find((magnet) => magnet.id === id);
    const newMagnets = Array.from(magnets);
    newMagnets.splice(atIndex, 0, { word, type, id });
    newMagnets.splice(
      magnets.findIndex((magnet) => magnet.id === id) + 1,
      1
    );
    setMagnets(newMagnets);
  }

  function addMagnetToStanza(id) {
    const { word, type } = magnets.find((magnet) => magnet.id === id);
    setStanza([...stanza, { word, type }]);
  }

  function removeMagnetFromStanza(id) {
    setStanza(stanza.filter((magnet) => magnet.id !== id));
  }

  const [, drop] = useDrop({
    accept: 'MAGNET',
    drop(item, monitor) {
      const didDrop = monitor.didDrop();
      if (!didDrop) {
        moveMagnet(item.id, magnets.length);
      }
    },
  });

  return (
    <div className="magnetic-poetry-board" ref={drop}>
      <div className="magnets-container">
        {magnets.map((magnet, index) => (
          <Magnet
            key={magnet.id}
            index={index}
            id={magnet.id}
            word={magnet.word}
            type={magnet.type}
            moveMagnet={moveMagnet}
            addMagnetToStanza={addMagnetToStanza}
            removeMagnetFromStanza={removeMagnetFromStanza}
          />
        ))}
      </div>
      <div className="stanza-container">
        {stanza.map((magnet) => (
          <Magnet
            key={magnet.id}
            word={magnet.word}
            type={magnet.type}
            removeMagnetFromStanza={removeMagnetFromStanza}
            isInStanza
          />
        ))}
      </div>
    </div>
  );
}

function Magnet({
  word,
  type,
  index,
  id,
  moveMagnet,
  addMagnetToStanza,
  removeMagnetFromStanza,
  isInStanza,
}) {
  const ref = useRef(null);
.magnetic-poetry-board {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.magnets-container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.magnet {
  padding: 8px;
  border: 1px solid gray;
  margin: 8px;
  cursor: move;
}

.verb {
  color: blue;
}

.adverb {
  color: green;
}

.noun {
  color: purple;
}

.adjective {
  color: orange;
}

.pronoun {
  color: pink;
}

.stanza-container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
}
function MagneticPoetry() {
  // ...

  async function handleSave() {
    try {
      // Save stanza to local storage
      localStorage.setItem('stanza', JSON.stringify(stanza));

      // Save stanza to MongoDB collection
      const response = await fetch('/api/stanzas', {
        method: 'POST',
        body: JSON.stringify({ stanza }),
        headers: { 'Content-Type': 'application/json' },
      });
      const data = await response.json();
      console.log(data);
    } catch (err) {
      console.error(err);
    }
  }

  return (
    <div className="magnetic-poetry-board" ref={drop}>
      {/* ... */}
      <button className="save-button" onClick={handleSave}>
        Save
      </button>
    </div>
  );
}