forked from M-Labs/web2019
Spare cards is always last
Also add warning if no cards were added
This commit is contained in:
parent
a589c309cc
commit
963f342c89
|
@ -11,6 +11,18 @@
|
||||||
.feedback-add-success {
|
.feedback-add-success {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.feedback-add-failure {
|
||||||
|
background-color: #c75e5e;
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
padding: 1em;
|
||||||
|
z-index: 100000;
|
||||||
|
color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 5px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
#accordion_categories,
|
#accordion_categories,
|
||||||
#accordion_categories .accordion-header,
|
#accordion_categories .accordion-header,
|
||||||
|
@ -251,7 +263,7 @@
|
||||||
##Screen = B/w 481px to 767px
|
##Screen = B/w 481px to 767px
|
||||||
*/
|
*/
|
||||||
@media (min-width: 481px) and (max-width: 767px) {
|
@media (min-width: 481px) and (max-width: 767px) {
|
||||||
.feedback-add-success {
|
.feedback-add-success, .feedback-add-failure {
|
||||||
background-color: green;
|
background-color: green;
|
||||||
display: block;
|
display: block;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -263,6 +275,9 @@
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 0 5px 3px;
|
box-shadow: 0 0 5px 3px;
|
||||||
}
|
}
|
||||||
|
.feedback-add-failure {
|
||||||
|
background-color: #c75e5e;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
font-size: .75em;
|
font-size: .75em;
|
||||||
|
@ -459,7 +474,7 @@
|
||||||
##Screen = B/w 320px to 479px
|
##Screen = B/w 320px to 479px
|
||||||
*/
|
*/
|
||||||
@media (min-width: 320px) and (max-width: 480px) {
|
@media (min-width: 320px) and (max-width: 480px) {
|
||||||
.feedback-add-success {
|
.feedback-add-success, .feedback-add-failure {
|
||||||
background-color: green;
|
background-color: green;
|
||||||
display: block;
|
display: block;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -471,6 +486,9 @@
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 0 5px 3px;
|
box-shadow: 0 0 5px 3px;
|
||||||
}
|
}
|
||||||
|
.feedback-add-failure {
|
||||||
|
background-color: #c75e5e;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
font-size: .75em;
|
font-size: .75em;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,6 +4,5 @@ import React from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
|
|
||||||
import { Shop } from "./shop/Shop.jsx"
|
import { Shop } from "./shop/Shop.jsx"
|
||||||
import { data } from "./shop/utils"
|
|
||||||
|
|
||||||
createRoot(document.querySelector('#root-shop')).render(<Shop data={data} />);
|
createRoot(document.querySelector('#root-shop')).render(<Shop />);
|
||||||
|
|
|
@ -16,19 +16,21 @@ export function CrateList() {
|
||||||
const onAddCrate = useShopStore((state) => state.newCrate);
|
const onAddCrate = useShopStore((state) => state.newCrate);
|
||||||
const setActiveCrate = useShopStore((state) => state.setActiveCrate);
|
const setActiveCrate = useShopStore((state) => state.setActiveCrate);
|
||||||
|
|
||||||
// #!render_count
|
const onSelectHandler = (e) => {
|
||||||
console.log("CrateList renders: ", renderCount)
|
|
||||||
return (
|
|
||||||
<Accordion id="accordion_crates" flush activeKey={active_crate} onSelect={(e) => {
|
|
||||||
// if e === null, that means that an accordion item was collapsed rather than expanded. e will be non-null when an item is expanded
|
// if e === null, that means that an accordion item was collapsed rather than expanded. e will be non-null when an item is expanded
|
||||||
if (e !== null)
|
if (e !== null)
|
||||||
setActiveCrate(e);
|
setActiveCrate(e);
|
||||||
else
|
else
|
||||||
setActiveCrate("")
|
setActiveCrate("")
|
||||||
}}>
|
};
|
||||||
|
|
||||||
|
// #!render_count
|
||||||
|
console.log("CrateList renders: ", renderCount)
|
||||||
|
return (
|
||||||
|
<Accordion id="accordion_crates" flush activeKey={active_crate} onSelect={onSelectHandler}>
|
||||||
{crates.map((crate, index) =>
|
{crates.map((crate, index) =>
|
||||||
<Accordion.Item eventKey={crate.id} key={"accordion"+crate.id} className="accordion_crates_item">
|
<Accordion.Item eventKey={crate.id} key={"accordion"+crate.id} className="accordion_crates_item">
|
||||||
<Accordion.Header>Crate #{`${index}`}</Accordion.Header>
|
<Accordion.Header>{crate.name ? crate.name : <>Crate #{`${index}`}</>} </Accordion.Header>
|
||||||
<Accordion.Body>
|
<Accordion.Body>
|
||||||
<Crate crate_index={index}/>
|
<Crate crate_index={index}/>
|
||||||
</Accordion.Body>
|
</Accordion.Body>
|
||||||
|
|
|
@ -19,16 +19,20 @@ export function CrateMode({crate_index}) {
|
||||||
|
|
||||||
// #!render_count
|
// #!render_count
|
||||||
console.log("CrateMode renders: ", renderCount)
|
console.log("CrateMode renders: ", renderCount)
|
||||||
|
if (modes_order.includes(crate.crate_mode)) {
|
||||||
return (
|
return (
|
||||||
<div className="crate-mode">
|
<div className="crate-mode">
|
||||||
{modes_order.map((mode_name, _) => (
|
{modes_order.map((mode_name, _) => (
|
||||||
<a
|
<a
|
||||||
key={mode_name}
|
key={mode_name}
|
||||||
className={(crate.crate_mode === mode_name ? 'active' : '') }
|
className={(crate.crate_mode === mode_name ? 'active' : '')}
|
||||||
onClick={() => setMode(crate.id, mode_name)}
|
onClick={() => setMode(crate.id, mode_name)}
|
||||||
href="#"
|
href="#"
|
||||||
role="button">{crate_modes[mode_name].name}</a>
|
role="button">{crate_modes[mode_name].name}</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return <div className="crate-mode"></div>
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -16,6 +16,7 @@ export function Layout({aside, main}) {
|
||||||
const mobileSideMenuShouldOpen = useShopStore(state => state.sideMenuIsOpen);
|
const mobileSideMenuShouldOpen = useShopStore(state => state.sideMenuIsOpen);
|
||||||
const onClickToggleMobileSideMenu = useShopStore(state => state.switchSideMenu);
|
const onClickToggleMobileSideMenu = useShopStore(state => state.switchSideMenu);
|
||||||
const showCardAddedFeedback = useShopStore(state => state.showCardAddedFeedback);
|
const showCardAddedFeedback = useShopStore(state => state.showCardAddedFeedback);
|
||||||
|
const showNoDestination = useShopStore(state => state.showNoDestination);
|
||||||
|
|
||||||
// #!render_count
|
// #!render_count
|
||||||
console.log("Layout renders: ", renderCount)
|
console.log("Layout renders: ", renderCount)
|
||||||
|
@ -32,9 +33,13 @@ export function Layout({aside, main}) {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{showCardAddedFeedback ? (
|
{showCardAddedFeedback ? (
|
||||||
<div className="feedback-add-success">
|
!showNoDestination ?
|
||||||
|
(<div className="feedback-add-success">
|
||||||
✓ added
|
✓ added
|
||||||
</div>
|
</div>)
|
||||||
|
: (<div className="feedback-add-failure">
|
||||||
|
No cards added: all crates are closed
|
||||||
|
</div>)
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -39,6 +39,7 @@ const useLayout = ((set, get) => ({
|
||||||
isMobile: window.deviceIsMobile(),
|
isMobile: window.deviceIsMobile(),
|
||||||
sideMenuIsOpen: false,
|
sideMenuIsOpen: false,
|
||||||
showCardAddedFeedback: false,
|
showCardAddedFeedback: false,
|
||||||
|
showNoDestination: false,
|
||||||
timerAdded: null,
|
timerAdded: null,
|
||||||
|
|
||||||
switchSideMenu: () => set(state => ({
|
switchSideMenu: () => set(state => ({
|
||||||
|
@ -46,10 +47,18 @@ const useLayout = ((set, get) => ({
|
||||||
})),
|
})),
|
||||||
cardAdded: () => set(state => ({
|
cardAdded: () => set(state => ({
|
||||||
showCardAddedFeedback: true,
|
showCardAddedFeedback: true,
|
||||||
|
showNoDestination: false,
|
||||||
timerAdded: (!!state.timerAdded ? clearTimeout(state.timerAdded) : null) || (state.isMobile && setTimeout(() => {
|
timerAdded: (!!state.timerAdded ? clearTimeout(state.timerAdded) : null) || (state.isMobile && setTimeout(() => {
|
||||||
get()._endCardAdded()
|
get()._endCardAdded()
|
||||||
}, 2000))
|
}, 2000))
|
||||||
})),
|
})),
|
||||||
|
noDestinationWarning: () => set(state => ({
|
||||||
|
showCardAddedFeedback: true,
|
||||||
|
showNoDestination: true,
|
||||||
|
timerAdded: (!!state.timerAdded ? clearTimeout(state.timerAdded) : null) || (setTimeout(() => {
|
||||||
|
get()._endCardAdded()
|
||||||
|
}, 2000))
|
||||||
|
})),
|
||||||
_endCardAdded: () => set(state => ({
|
_endCardAdded: () => set(state => ({
|
||||||
showCardAddedFeedback: false,
|
showCardAddedFeedback: false,
|
||||||
timerAdded: !!state.timerAdded ? clearTimeout(state.timerAdded) : null
|
timerAdded: !!state.timerAdded ? clearTimeout(state.timerAdded) : null
|
||||||
|
@ -221,7 +230,7 @@ const useCart = ((set, get) => ({
|
||||||
active_crate: "crate0",
|
active_crate: "crate0",
|
||||||
|
|
||||||
_newCrate: (crate_id) => set((state) => ({
|
_newCrate: (crate_id) => set((state) => ({
|
||||||
crates: state.crates.concat({
|
crates: state.crates.toSpliced(-1, 0, {
|
||||||
id: crate_id || "crate" + state.crates.length,
|
id: crate_id || "crate" + state.crates.length,
|
||||||
crate_mode: "rack",
|
crate_mode: "rack",
|
||||||
items: [],
|
items: [],
|
||||||
|
@ -403,7 +412,11 @@ const useCart = ((set, get) => ({
|
||||||
|
|
||||||
addCardFromBacklog: (crate_to, index_from, index_to, just_mounted) => {
|
addCardFromBacklog: (crate_to, index_from, index_to, just_mounted) => {
|
||||||
const dest = crate_to || get().active_crate;
|
const dest = crate_to || get().active_crate;
|
||||||
if (!dest) return {};
|
if (!dest) {
|
||||||
|
console.warn("No destination");
|
||||||
|
get().noDestinationWarning();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
get()._addCardFromBacklog(dest, index_from, index_to)
|
get()._addCardFromBacklog(dest, index_from, index_to)
|
||||||
get().fillExtData(dest);
|
get().fillExtData(dest);
|
||||||
get().fillWarnings(dest);
|
get().fillWarnings(dest);
|
||||||
|
|
|
@ -25,7 +25,7 @@ const shop_data = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
crateModeOrder: [
|
crateModeOrder: [
|
||||||
"rack", "desktop", "no_crate"
|
"rack", "desktop"
|
||||||
],
|
],
|
||||||
|
|
||||||
items: {
|
items: {
|
||||||
|
@ -1156,7 +1156,16 @@ const shop_data = {
|
||||||
items: [],
|
items: [],
|
||||||
warnings: [],
|
warnings: [],
|
||||||
occupiedHP: 0,
|
occupiedHP: 0,
|
||||||
}]
|
},
|
||||||
|
{
|
||||||
|
id: "spare",
|
||||||
|
name: "Spare cards",
|
||||||
|
crate_mode: "no_crate",
|
||||||
|
items: [],
|
||||||
|
warnings: [],
|
||||||
|
occupiedHP: 0,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,8 +37,8 @@ module.exports = {
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.tsx', '.ts', '.js', '.jsx'],
|
extensions: ['.tsx', '.ts', '.js', '.jsx'],
|
||||||
},
|
},
|
||||||
devtool: "inline-source-map",
|
//devtool: "inline-source-map",
|
||||||
mode: "development"
|
//mode: "development"
|
||||||
//devtool: false,
|
devtool: false,
|
||||||
//mode: "production"
|
mode: "production"
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue