add manual sorting to unit cards
This commit is contained in:
+75
-12
@@ -60,7 +60,11 @@ export const Roster = ({
|
|||||||
const Force = ({ force, onePerPage, colorUserChoice }) => {
|
const Force = ({ force, onePerPage, colorUserChoice }) => {
|
||||||
const { units, factionRules, rules, catalog } = force;
|
const { units, factionRules, rules, catalog } = force;
|
||||||
const mergedRules = new Map([...factionRules, ...rules]);
|
const mergedRules = new Map([...factionRules, ...rules]);
|
||||||
// units with role "Character" are sorted to the top, then "Battleline", then "Other"
|
|
||||||
|
// State to manage the order of units
|
||||||
|
const [unitOrder, setUnitOrder] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
const sortedUnits = units.sort((a, b) => {
|
const sortedUnits = units.sort((a, b) => {
|
||||||
if (a.role === "Character" && b.role !== "Character") return -1;
|
if (a.role === "Character" && b.role !== "Character") return -1;
|
||||||
if (a.role !== "Character" && b.role === "Character") return 1;
|
if (a.role !== "Character" && b.role === "Character") return 1;
|
||||||
@@ -68,6 +72,8 @@ const Force = ({ force, onePerPage, colorUserChoice }) => {
|
|||||||
if (a.role !== "Battleline" && b.role === "Battleline") return 1;
|
if (a.role !== "Battleline" && b.role === "Battleline") return 1;
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
});
|
});
|
||||||
|
setUnitOrder(sortedUnits);
|
||||||
|
}, [units]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -75,30 +81,87 @@ const Force = ({ force, onePerPage, colorUserChoice }) => {
|
|||||||
display: "contents",
|
display: "contents",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{sortedUnits.map((unit, index) => (
|
{unitOrder.map((unit, index) => (
|
||||||
|
<div key={unit.name + index} className="relative">
|
||||||
|
<div className="flex items-center justify-start gap-1 absolute text-[13px] -top-2.5 z-10 print-display-none">
|
||||||
|
<button
|
||||||
|
disabled={index === 0}
|
||||||
|
type="button"
|
||||||
|
className="py-0.5 px-1.5 pl-1"
|
||||||
|
onClick={() =>
|
||||||
|
// move unit up in the order
|
||||||
|
setUnitOrder((prevOrder) => {
|
||||||
|
const newOrder = [...prevOrder];
|
||||||
|
const unitToMove = newOrder.splice(index, 1)[0];
|
||||||
|
newOrder.splice(index - 1, 0, unitToMove);
|
||||||
|
return newOrder;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
fill="#111113"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M12 4V20M12 4L8 8M12 4L16 8"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
Up
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
disabled={index === unitOrder.length - 1}
|
||||||
|
type="button"
|
||||||
|
className="py-0.5 px-1.5 pl-1"
|
||||||
|
onClick={() =>
|
||||||
|
// move unit down in the order
|
||||||
|
setUnitOrder((prevOrder) => {
|
||||||
|
const newOrder = [...prevOrder];
|
||||||
|
const unitToMove = newOrder.splice(index, 1)[0];
|
||||||
|
newOrder.splice(index + 1, 0, unitToMove);
|
||||||
|
return newOrder;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
fill="#111113"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M12 4V20M12 20L8 16M12 20L16 16"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
Down
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<Unit
|
<Unit
|
||||||
key={unit.name + index}
|
|
||||||
index={index}
|
|
||||||
unit={unit}
|
unit={unit}
|
||||||
catalog={catalog}
|
catalog={catalog}
|
||||||
onePerPage={onePerPage}
|
onePerPage={onePerPage}
|
||||||
forceRules={rules}
|
forceRules={rules}
|
||||||
colorUserChoice={colorUserChoice}
|
colorUserChoice={colorUserChoice}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
<ForceRules rules={mergedRules} onePerPage={onePerPage} />
|
<ForceRules rules={mergedRules} onePerPage={onePerPage} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Unit = ({
|
const Unit = ({ unit, catalog, onePerPage, forceRules, colorUserChoice }) => {
|
||||||
unit,
|
|
||||||
index,
|
|
||||||
catalog,
|
|
||||||
onePerPage,
|
|
||||||
forceRules,
|
|
||||||
colorUserChoice,
|
|
||||||
}) => {
|
|
||||||
const [hide, setHide] = useState(false);
|
const [hide, setHide] = useState(false);
|
||||||
const [hideModelCount, setHideModelCount] = useState(false);
|
const [hideModelCount, setHideModelCount] = useState(false);
|
||||||
const uploadRef = useRef();
|
const uploadRef = useRef();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const ShortSummaryTable = ({ force, primaryColor, name, points }) => {
|
|||||||
const [hide, setHide] = useState(false);
|
const [hide, setHide] = useState(false);
|
||||||
const { units, factionRules, rules, catalog } = force;
|
const { units, factionRules, rules, catalog } = force;
|
||||||
|
|
||||||
const sortedUnits = units.sort((a, b) => {
|
const sortedUnits = units.slice().sort((a, b) => {
|
||||||
// sort by points cost desc first, then by name
|
// sort by points cost desc first, then by name
|
||||||
if (a.cost.points < b.cost.points) return 1;
|
if (a.cost.points < b.cost.points) return 1;
|
||||||
if (a.cost.points > b.cost.points) return -1;
|
if (a.cost.points > b.cost.points) return -1;
|
||||||
|
|||||||
+12
-9
@@ -4,9 +4,8 @@
|
|||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
font-family:
|
font-family: "Noto Sans", sans-serif, Inter, system-ui, Avenir, Helvetica,
|
||||||
"Noto Sans", sans-serif, Inter, system-ui, Avenir, Helvetica, Arial,
|
Arial, sans-serif;
|
||||||
sans-serif;
|
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@@ -80,7 +79,7 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: border-color 0.25s;
|
transition: border-color 0.15s;
|
||||||
}
|
}
|
||||||
button:hover,
|
button:hover,
|
||||||
.button:hover {
|
.button:hover {
|
||||||
@@ -94,6 +93,13 @@
|
|||||||
outline: 4px auto -webkit-focus-ring-color;
|
outline: 4px auto -webkit-focus-ring-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button:disabled,
|
||||||
|
.button[disabled] {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
color: #999;
|
||||||
|
border-color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -139,11 +145,8 @@
|
|||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition:
|
transition: color 0.15s, border 0.15s, font-size 0.15s, background-color
|
||||||
color 0.25s,
|
0.15s;
|
||||||
border 0.25s,
|
|
||||||
font-size 0.25s,
|
|
||||||
background-color 0.25s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rosterUpload:hover {
|
.rosterUpload:hover {
|
||||||
|
|||||||
Reference in New Issue
Block a user