-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
251abbc
commit 6b8a5d4
Showing
3 changed files
with
242 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
import { | ||
DragDropProvider, | ||
DragDropSensors, | ||
createDraggable, | ||
createDroppable, | ||
closestCenter | ||
} from "@thisbeyond/solid-dnd"; | ||
import { For, batch, createSignal, createEffect, Show } from "solid-js"; | ||
import { createStore } from "solid-js/store"; | ||
|
||
const allTeamsName = "All"; | ||
|
||
/** | ||
* | ||
* @param {object} props | ||
* @param {object} props.team | ||
* @param {int} props.team.seed | ||
* @param {str} props.team.name | ||
* @returns | ||
*/ | ||
const TeamInfo = props => ( | ||
<div class="p-2 text-start flex gap-4 cursor-grab text-sm"> | ||
<div class="basis-1/6 text-center text-white dark:text-white-400 rounded-xl border-b bg-green-400 border-green-200 dark:bg-green-800 dark:border-green-700"> | ||
{props.team.seed} | ||
</div> | ||
<div class="basis-5/6">{props.team.name}</div> | ||
</div> | ||
); | ||
|
||
/** | ||
* | ||
* @param {object} props | ||
* @param {{seed: int, name: str}} props.team | ||
*/ | ||
const Draggable = props => { | ||
const draggable = createDraggable(props.team.seed); | ||
return ( | ||
<div | ||
use:draggable | ||
class="text-gray-500 dark:text-gray-400 my-2 rounded-lg bg-gray-200 border-gray-300 border-b dark:bg-gray-800 dark:border-gray-700" | ||
> | ||
<TeamInfo team={props.team} /> | ||
</div> | ||
); | ||
}; | ||
|
||
/** | ||
* | ||
* @param {object} props | ||
* @param {str} props.id | ||
* @param {str} props.name | ||
* @param {{seed: int, name: str}[]} props.teams | ||
*/ | ||
const Droppable = props => { | ||
const droppable = createDroppable(props.id); | ||
return ( | ||
<> | ||
<div | ||
use:droppable | ||
class="flex flex-col justify-items-center justify-start gap-y-2 content-center h-full p-4 rounded-xl dark:text-gray-400 bg-white text-center select-none border dark:border-gray-700" | ||
classList={{ | ||
"ring-4 ring-blue-500": droppable.isActiveDroppable, | ||
"justify-between dark:bg-gray-700": props.id !== allTeamsName, | ||
"dark:bg-gray-900": props.id === allTeamsName | ||
}} | ||
> | ||
{/* bg-gray-200 dark:bg-gray-700 border-b dark:border-gray-600 rounded-b-xl */} | ||
<h4 class="text-center text-white p-2 justify-self-start"> | ||
<Show when={props.id !== allTeamsName} fallback={"All teams"}> | ||
Pool - {props.name} | ||
</Show> | ||
</h4> | ||
<div class=""> | ||
<For each={props.teams}>{team => <Draggable team={team} />}</For> | ||
</div> | ||
<Show when={props.id !== allTeamsName}> | ||
<button | ||
class="justify-self-end p-2 text-sm font-normal text-white rounded-lg bg-red-700 hover:bg-red-800 dark:bg-red-500/75 dark:hover:bg-red-700/75" | ||
onClick={() => props.removePool(props.id)} | ||
> | ||
Remove pool | ||
</button> | ||
</Show> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
const CreatePools = props => { | ||
const [enteredPoolName, setEnteredPoolName] = createSignal(""); | ||
const [draggedTeam, setDraggedTeam] = createSignal({}); | ||
const [draggableStartPool, setDraggableStartPool] = createSignal(""); | ||
|
||
const [pools, setPools] = createStore({}); | ||
|
||
createEffect(() => { | ||
let allTeams = []; | ||
props.allTeams.forEach((teamId, idx) => | ||
allTeams.push({ | ||
seed: idx + 1, | ||
name: props.teamsMap[teamId] | ||
}) | ||
); | ||
|
||
setPools(allTeamsName, allTeams); | ||
}); | ||
|
||
const onDragStart = ({ draggable }) => { | ||
if (draggable) { | ||
console.log(draggable.id); | ||
|
||
for (const [poolName, teams] of Object.entries(pools)) { | ||
const teamIdx = teams.findIndex(team => team.seed == draggable.id); | ||
if (teamIdx !== -1) { | ||
setDraggedTeam(teams[teamIdx]); | ||
setDraggableStartPool(poolName); | ||
break; | ||
} | ||
} | ||
} | ||
}; | ||
|
||
const onDragEnd = ({ draggable, droppable }) => { | ||
if (draggable && droppable) { | ||
console.log(draggable.id, droppable.id); | ||
|
||
if (draggableStartPool() == droppable.id) { | ||
return; | ||
} | ||
|
||
console.log("drag start:", draggableStartPool()); | ||
console.log("drag end:", droppable.id); | ||
|
||
batch(() => { | ||
setPools(draggableStartPool(), teams => | ||
teams.filter(team => team.seed !== draggable.id) | ||
); | ||
setPools(droppable.id, teams => [...teams, draggedTeam()]); | ||
}); | ||
} | ||
}; | ||
|
||
const removePool = droppableId => { | ||
batch(() => { | ||
setPools(allTeamsName, teams => [...teams, ...pools[droppableId]]); | ||
// setting value undefined to delete it from the store | ||
setPools(droppableId, undefined); | ||
}); | ||
}; | ||
|
||
const addPool = poolName => { | ||
console.log("creating pool", poolName); | ||
if (Object.keys(pools).includes(poolName)) { | ||
return; | ||
} | ||
setPools(poolName, []); | ||
}; | ||
|
||
return ( | ||
<> | ||
<div class="w-1/2 mb-4 flex gap-4 justify-start items-center rounded-md"> | ||
<input | ||
type="text" | ||
id="pool-name" | ||
placeholder="Enter Pool Name" | ||
value={enteredPoolName()} | ||
onChange={e => setEnteredPoolName(e.target.value.trim())} | ||
class="basis-2/3 p-2 placeholder:text-md placeholder:italic text-gray-900 rounded-lg bg-gray-50 border border-gray-300 dark:border-gray-600 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" | ||
/> | ||
<button | ||
type="button" | ||
onClick={() => { | ||
addPool(enteredPoolName()); | ||
setEnteredPoolName(""); | ||
}} | ||
class="basis-1/3 p-2 font-normal text-sm rounded-lg text-white bg-blue-700 hover:bg-blue-800 dark:bg-blue-600 dark:hover:bg-blue-700 disabled:dark:bg-gray-400" | ||
> | ||
Add Pool | ||
</button> | ||
</div> | ||
<DragDropProvider | ||
onDragStart={onDragStart} | ||
onDragEnd={onDragEnd} | ||
collisionDetector={closestCenter} | ||
> | ||
<DragDropSensors> | ||
<div class="w-full grid grid-rows-2 grid-cols-3 grid-flow-row gap-4"> | ||
<div class="row-span-2 col-span-1"> | ||
<Droppable | ||
id={allTeamsName} | ||
name={allTeamsName} | ||
teams={pools[allTeamsName]} | ||
/> | ||
</div> | ||
|
||
<For each={Object.entries(pools)}> | ||
{([poolName, teams], idx) => ( | ||
<Show when={poolName !== allTeamsName}> | ||
<div class="row-span-1 col-span-1"> | ||
<Droppable | ||
id={poolName} | ||
name={poolName} | ||
teams={teams} | ||
removePool={removePool} | ||
/> | ||
</div> | ||
</Show> | ||
)} | ||
</For> | ||
</div> | ||
</DragDropSensors> | ||
</DragDropProvider> | ||
<button | ||
type="button" | ||
class="basis-1/3 px-4 py-2 my-4 text-sm font-normal rounded-lg text-white bg-blue-700 hover:bg-blue-800 dark:bg-blue-600 dark:hover:bg-blue-700 disabled:dark:bg-gray-400" | ||
> | ||
Submit Pools | ||
</button> | ||
</> | ||
); | ||
}; | ||
|
||
export default CreatePools; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters