Skip to content

Commit

Permalink
🎁 Someone's PC (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
jynnie authored Feb 28, 2023
1 parent 9ebf8ae commit 37b6801
Show file tree
Hide file tree
Showing 33 changed files with 1,174 additions and 126 deletions.
16 changes: 13 additions & 3 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@

🌶🌶🌶 Super cool

- [ ] New region!
- [ ] Timeline: Inline editing
- [ ] Box view? TL location in the bottom
- [ ] Box: Drag and drop between categories to move
- [ ] Locations
- [ ] Origin names
- [ ] Nicknames
- [x] Box View
- [x] Drag and drop between categories to move
- [x] Edit pokemon from view
- [x] Adding to team needs to make sure not full
- [x] Add new Pokemon
- [x] Styling
- [x] Show current location?
- [ ] Shared type rule (either present suggested parties or a toggle to enforce rule)

🌶🌶 Would improve most experiences or could be cool

- [ ] Skeletons while loading
- [ ] Mobile friendly
- [ ] Cooler summary view styles
- [ ] New region! (Waiting on pokeapi to update tbh)

🌶 Should have, but low value add rn

Expand Down
2 changes: 1 addition & 1 deletion components/AddPokemon/AddPokemon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function AddPokemon({
interactiveBorder={10}
onClickOutside={() => setShowForm(false)}
>
<div>
<div className="flex center">
<Tippy content={<TooltipContent content="Add Pokemon" />}>
<div>
<Button
Expand Down
2 changes: 1 addition & 1 deletion components/AddPokemon/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function AddPokemonForm({
setCaught(true);
};

const handlePokemonChange = (value: string) => setPokemon(value);
const handlePokemonChange = (value?: string) => setPokemon(value);
const handleNicknameChange: React.ChangeEventHandler<HTMLInputElement> = (
evt,
) => setNickname(evt.target.value);
Expand Down
9 changes: 5 additions & 4 deletions components/AddToTimeline/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SearchableSelect } from "components/ui-library/SearchableSelect";
import type { MapLocation } from "models";
import React from "react";
import { Plus } from "react-feather";
import { cleanName } from "utils/utils";
import { capitalize, cleanName } from "utils/utils";

function AddToTimelineForm({
allLocations,
Expand All @@ -22,7 +22,7 @@ function AddToTimelineForm({
setLocation(undefined);
};

const handleChange = (value: string) => {
const handleChange = (value?: string) => {
setLocation(value);
};

Expand All @@ -33,16 +33,17 @@ function AddToTimelineForm({
options={[
...allLocations?.map((l) => ({
value: l.name,
label: cleanName(l.name),
label: capitalize(cleanName(l.name)),
})),
...allBadges?.map((b) => ({
value: b,
label: cleanName(b),
label: capitalize(cleanName(b)),
})),
]}
value={location}
onChange={handleChange}
placeholder="Add Location or Badge"
allowCustom
/>

<Button
Expand Down
181 changes: 181 additions & 0 deletions components/BoxView/BoxFilters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import { Button } from "components/ui-library/Button";
import { Modal } from "components/ui-library/Modal";
import { SearchableSelect } from "components/ui-library/SearchableSelect";
import { useAddPokemonAndLocation } from "hooks/useAddPokemons";
import { usePlayersArray } from "hooks/usePlayersArray";
import { useRegion, useRegionData } from "hooks/useRegionData";
import { useRouter } from "next/router";
import { RunContext } from "pages/run/[id]";
import React, { useState } from "react";
import { Plus, Search } from "react-feather";
import styles from "styles/Box.module.scss";
import fstyles from "styles/Filters.module.scss";
import Box from "ui-box";
import { capitalize, cleanName } from "utils/utils";

export function BoxFilters({
onChange,
latestLocation,
}: {
onChange: (val: any) => void;
latestLocation?: { name: string; key: string };
}) {
const [showModal, setShowModal] = React.useState<boolean>(false);
const handleOpenModal = () => setShowModal(true);
const handleCloseModal = () => setShowModal(false);

const [inputVal, setInputVal] = React.useState<string>("");
const handleSearch: React.ChangeEventHandler<HTMLInputElement> = (e) => {
setInputVal(e.target.value);
handleChange({ searchTerm: e.target.value });
};

const handleChange = (override?: any) => {
if (onChange)
onChange({
searchTerm: inputVal,
...(override || {}),
});
};

return (
<>
<Box className={styles.filters} width="100%">
<div className={fstyles.search}>
<Search size="1rem" />
<input
type="text"
placeholder="Search"
value={inputVal}
onChange={handleSearch}
/>
</div>

<div className={styles.location}>
{capitalize(cleanName(latestLocation?.name || ""))}
</div>

<div className="flex items-center justify-end">
<Button
className="outline icon"
icon={<Plus />}
onClick={handleOpenModal}
/>
</div>
</Box>

<AddPokemonModal
{...{
visible: !!showModal,
onCancel: handleCloseModal,
}}
/>
</>
);
}

function AddPokemonModal({
visible,
onCancel,
}: {
visible: boolean;
onCancel: () => void;
}) {
const router = useRouter();
const { id: rawId } = router.query;
const id = Array.isArray(rawId) ? rawId[0] : rawId;

const region = useRegion(id);
const regionData = useRegionData(region);
const allLocations = regionData?.locations || [];

const { allPokemon } = React.useContext(RunContext);
const players = usePlayersArray();

const [newLocation, setLocation] = useState<string>("");
const [pokemonNames, setPokemonNames] = useState<string[]>(
Array(players.length).fill(""),
);
const [nicknames, setNicknames] = useState<string[]>(
Array(players.length).fill(""),
);

const addPokemon = useAddPokemonAndLocation();

async function addNew() {
await addPokemon(
newLocation,
players.map((p) => p.id),
pokemonNames,
nicknames,
);
onCancel();
}

function updatePokemonName(index: number, name: string) {
const newPokemonNames = [...pokemonNames];
newPokemonNames[index] = name;
setPokemonNames(newPokemonNames);
}

function updateNickname(index: number, name: string) {
const newNicknames = [...nicknames];
newNicknames[index] = name;
setNicknames(newNicknames);
}

return (
<Modal visible={visible} onCancel={onCancel}>
<>
<h3 className="mt-1 mb-4">Add Pokémon</h3>

<div className="flex flex-col gap-2">
<label>
<span className="color-purple">*</span> Caught at:
</label>
<SearchableSelect
options={[
...allLocations?.map((l) => ({
value: l.name,
label: capitalize(cleanName(l.name)),
})),
]}
value={newLocation}
onChange={(value?: string) => setLocation(value || "")}
placeholder="Add New Location"
allowCustom
/>
</div>

<div className="my-4 flex flex-wrap gap-2">
{players?.map((player, index) => (
<div key={player.id} className="flex grow-1 flex-col gap-2">
<h4 className="m-0 capitalize">{player.name}</h4>

<SearchableSelect
onChange={(value?: string) =>
updatePokemonName(index, value || "")
}
value={pokemonNames[index]}
placeholder="Select a Pokémon"
options={allPokemon.map((p) => ({
value: p.name,
label: p.name,
}))}
/>
<input
type="text"
placeholder="Nickname"
value={nicknames[index]}
onChange={(e) => updateNickname(index, e.target.value)}
/>
</div>
))}
</div>
<div className="flex justify-end">
<button onClick={addNew}>Add</button>
</div>
</>
</Modal>
);
}
50 changes: 50 additions & 0 deletions components/BoxView/BoxPokemon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { PokemonBoxModal } from "components/Pokemon/PokemonBoxModal";
import PokemonImage from "components/PokemonImage";
import { Data } from "components/Timeline/Timeline";
import { TooltipContent } from "components/ui-library/TooltipContent";
import React from "react";
import styles from "styles/Box.module.scss";

import Tippy from "@tippyjs/react";

export function BoxPokemon({ data }: { data: Data }) {
const [showModal, setShowModal] = React.useState<boolean>(false);

const handleOpenModal = () => setShowModal(true);
const handleCloseModal = () => setShowModal(false);

return (
<>
<PokemonBoxModal
{...{
data,
showModal,
onCancel: handleCloseModal,
}}
/>

<div className={styles.pokemon} onClick={handleOpenModal}>
<Tippy
content={
<TooltipContent className="capitalize">
{data.pokemon.map((p) => p.nickname || "?").join(" & ")}
</TooltipContent>
}
delay={[500, 0]}
>
<div className={styles.images}>
{data.pokemon.map((p, i) => (
<PokemonImage
key={i}
pokemon={p}
width={48}
marginLeft={i * -16}
marginTop={i * 16 - 12}
/>
))}
</div>
</Tippy>
</div>
</>
);
}
Loading

1 comment on commit 37b6801

@vercel
Copy link

@vercel vercel bot commented on 37b6801 Feb 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.