Skip to content

Commit

Permalink
Add spacer calc
Browse files Browse the repository at this point in the history
  • Loading branch information
tervay committed Nov 12, 2023
1 parent d323ba2 commit 4672202
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/web/info/util/components/HoleSizes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ export function HoleSizes(): JSX.Element {

return (
<>
<div className="is-size-3">Hole Sizes</div>
<Columns formColumns>
<Column>
<SingleInputLine label="Hole Size">
Expand Down
156 changes: 156 additions & 0 deletions src/web/info/util/components/Spacers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import SingleInputLine from "common/components/io/inputs/SingleInputLine";
import { MeasurementInput } from "common/components/io/new/inputs";
import MeasurementOutput from "common/components/io/outputs/MeasurementOutput";
import { Column, Columns } from "common/components/styling/Building";
import Measurement from "common/models/Measurement";
import { countBy } from "lodash";
import sortBy from "lodash/sortBy";
import { useMemo, useState } from "react";

interface SpacerSize {
label: string;
size: Measurement;
}

const imperialSizes: SpacerSize[] = [
{
label: '1/32"',
size: new Measurement(1 / 32, "in"),
},
{
label: '1/16"',
size: new Measurement(1 / 16, "in"),
},
{
label: '1/8"',
size: new Measurement(1 / 8, "in"),
},
{
label: '1/4"',
size: new Measurement(1 / 4, "in"),
},
{
label: '1/2"',
size: new Measurement(1 / 2, "in"),
},
{
label: '1"',
size: new Measurement(1, "in"),
},
{
label: '2"',
size: new Measurement(2, "in"),
},
];

export function countSpacers(
targetSize: Measurement,
spacerSizes: SpacerSize[],
): {
spacers: SpacerSize[];
remaining: Measurement;
} {
const spacers = [];
let remainingSize = targetSize;
let sizesThatFit = sortBy(spacerSizes, (s) => s.size.baseScalar).filter((s) =>
s.size.lte(remainingSize),
);
while (
remainingSize.gte(new Measurement(0, "in")) &&
sizesThatFit.length > 0
) {
const spacer = sizesThatFit.pop()!;
spacers.push(spacer);

remainingSize = remainingSize.sub(spacer.size);
sizesThatFit = sortBy(spacerSizes, (s) => s.size.baseScalar).filter((s) =>
s.size.lte(remainingSize),
);
}

return {
spacers,
remaining: remainingSize,
};
}

export default function SpacerCalc(): JSX.Element {
const [desiredLength, setDesiredLength] = useState(
new Measurement(0.875, "in"),
);

const [enabledSizes, setEnabledSizes] = useState(() => {
const initialEnabledSizes = imperialSizes.map(() => true); // Initially, all sizes are enabled
return initialEnabledSizes;
});

const handleToggle = (index: number) => {
setEnabledSizes((prev) => {
const updatedSizes = [...prev];
updatedSizes[index] = !updatedSizes[index];
return updatedSizes;
});
};

const out = useMemo(
() =>
countSpacers(
desiredLength,
enabledSizes
.map((isEnabled, index) => imperialSizes[index])
.filter((size, index) => enabledSizes[index]),
),
[desiredLength, enabledSizes],
);

return (
<>
<div className="is-size-3">Spacers</div>
<Columns>
<Column>
<SingleInputLine label="Desired Length">
<MeasurementInput stateHook={[desiredLength, setDesiredLength]} />
</SingleInputLine>

<Columns multiline mobile>
{imperialSizes.map((spacer, index) => (
<Column>
<SingleInputLine label={spacer.label}>
<div className="field">
<div className="control">
<label className="checkbox">
<input
type="checkbox"
className="recalc-switch"
onChange={() => handleToggle(index)}
defaultChecked={true}
/>
</label>
</div>
</div>
</SingleInputLine>
</Column>
))}
</Columns>
</Column>

<Column>
<SingleInputLine label="Remaining Length">
<MeasurementOutput
stateHook={[out.remaining, () => {}]}
defaultUnit="in"
numberRoundTo={4}
/>
</SingleInputLine>
{Object.entries(countBy(out.spacers, (s) => s.label)).map(
([k, v]) => (
<li>
<b>{v}x</b> {k}
</li>
),
)}
</Column>
</Columns>
</>
);
}
2 changes: 2 additions & 0 deletions src/web/info/util/components/Util.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Bearings from "web/info/util/components/Bearings";
import { HoleSizes } from "web/info/util/components/HoleSizes";
import MountingCheatSheet from "web/info/util/components/MountingCheatSheet";
import SpacerCalc from "web/info/util/components/Spacers";

export default function Util(): JSX.Element {
return (
<>
<HoleSizes />
<SpacerCalc />
<MountingCheatSheet />
<Bearings />
{/* <ExtrusionPrices /> */}
Expand Down

0 comments on commit 4672202

Please sign in to comment.