mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: provisions
This commit is contained in:
1 parent
5d0fe8726b
commit
85d699dbfc
3 files changed
+132
-73
No files matched your search
@@ -23,7 +23,9 @@ import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
|||||||
import { use, useCallback, useEffect, useMemo, useState } from 'react';
|
import { use, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { EquipmentManager } from '../../../components/EquipmentManager';
|
import { EquipmentManager } from '../../../components/EquipmentManager';
|
||||||
import PageWrapper from '../../../components/PageWrapper';
|
import PageWrapper from '../../../components/PageWrapper';
|
||||||
|
import { ProvisionsManager } from '../../../components/ProvisionsManager';
|
||||||
import { asset } from '../../../core/blitzkrieg/asset';
|
import { asset } from '../../../core/blitzkrieg/asset';
|
||||||
|
import { availableProvisions } from '../../../core/blitzkrieg/availableProvisions';
|
||||||
import { equipmentDefinitions } from '../../../core/blitzkrieg/equipmentDefinitions';
|
import { equipmentDefinitions } from '../../../core/blitzkrieg/equipmentDefinitions';
|
||||||
import { modelDefinitions } from '../../../core/blitzkrieg/modelDefinitions';
|
import { modelDefinitions } from '../../../core/blitzkrieg/modelDefinitions';
|
||||||
import { provisionDefinitions } from '../../../core/blitzkrieg/provisionDefinitions';
|
import { provisionDefinitions } from '../../../core/blitzkrieg/provisionDefinitions';
|
||||||
@@ -439,9 +441,14 @@ export default function Page() {
|
|||||||
<Table.Cell />
|
<Table.Cell />
|
||||||
|
|
||||||
{members.map(
|
{members.map(
|
||||||
({ equipmentMatrix, tank, key, provisions }, index) => {
|
({ equipmentMatrix, tank, key, provisions, gun }, index) => {
|
||||||
const equipmentPreset =
|
const equipmentPreset =
|
||||||
awaitedEquipmentDefinitions.presets[tank.equipment];
|
awaitedEquipmentDefinitions.presets[tank.equipment];
|
||||||
|
const provisionsList = availableProvisions(
|
||||||
|
tank,
|
||||||
|
gun,
|
||||||
|
awaitedProvisionDefinitions,
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table.Cell key={key}>
|
<Table.Cell key={key}>
|
||||||
@@ -559,48 +566,70 @@ export default function Page() {
|
|||||||
</Popover.Content>
|
</Popover.Content>
|
||||||
</Popover.Root>
|
</Popover.Root>
|
||||||
|
|
||||||
<Button
|
<Popover.Root>
|
||||||
variant="ghost"
|
<Popover.Trigger>
|
||||||
radius="large"
|
<Button
|
||||||
style={{
|
variant="ghost"
|
||||||
height: '100%',
|
radius="large"
|
||||||
width: 16,
|
style={{
|
||||||
position: 'relative',
|
height: '100%',
|
||||||
}}
|
width: 16,
|
||||||
>
|
position: 'relative',
|
||||||
<Flex direction="column">
|
}}
|
||||||
{provisions.map((provision, index) => (
|
>
|
||||||
<img
|
<Flex direction="column">
|
||||||
key={provision}
|
{provisions.map((provision, index) => (
|
||||||
src={asset(
|
<img
|
||||||
`/icons/provisions/${provision}.webp`,
|
key={provision}
|
||||||
)}
|
src={asset(
|
||||||
style={{
|
`/icons/provisions/${provision}.webp`,
|
||||||
left: '50%',
|
)}
|
||||||
/**
|
style={{
|
||||||
* max = 100% - 16px - 4px
|
left: '50%',
|
||||||
* min = 4px
|
/**
|
||||||
* diff = max - min
|
* max = 100% - 16px - 4px
|
||||||
* = 100% - 16px - 4px - 4px
|
* min = 4px
|
||||||
* = 100% - 24px
|
* diff = max - min
|
||||||
* coefficient = index / length - 1
|
* = 100% - 16px - 4px - 4px
|
||||||
* position = min + coefficient * diff
|
* = 100% - 24px
|
||||||
*/
|
* coefficient = index / length - 1
|
||||||
top: `calc(4px + ${
|
* position = min + coefficient * diff
|
||||||
provisions.length === 1
|
*/
|
||||||
? 0.5
|
top: `calc(4px + ${
|
||||||
: index / (provisions.length - 1)
|
provisions.length === 1
|
||||||
} * (100% - 24px))`,
|
? 0.5
|
||||||
transform: 'translateX(-50%)',
|
: index / (provisions.length - 1)
|
||||||
position: 'absolute',
|
} * (100% - 24px))`,
|
||||||
width: 16,
|
transform: 'translateX(-50%)',
|
||||||
height: 16,
|
position: 'absolute',
|
||||||
objectFit: 'contain',
|
width: 16,
|
||||||
}}
|
height: 16,
|
||||||
/>
|
objectFit: 'contain',
|
||||||
))}
|
}}
|
||||||
</Flex>
|
/>
|
||||||
</Button>
|
))}
|
||||||
|
</Flex>
|
||||||
|
</Button>
|
||||||
|
</Popover.Trigger>
|
||||||
|
|
||||||
|
<Popover.Content>
|
||||||
|
<ProvisionsManager
|
||||||
|
provisions={provisionsList.map(
|
||||||
|
(provision) => provision.id,
|
||||||
|
)}
|
||||||
|
selected={provisions}
|
||||||
|
disabled={
|
||||||
|
tank.provisions === provisionsList.length
|
||||||
|
}
|
||||||
|
onChange={(provisions) => {
|
||||||
|
mutateCompareTemporary((draft) => {
|
||||||
|
draft.members[index].provisions =
|
||||||
|
provisions;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Popover.Content>
|
||||||
|
</Popover.Root>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
);
|
);
|
||||||
|
|||||||
+11
-30
@@ -1,6 +1,6 @@
|
|||||||
import { Button, Flex, Heading } from '@radix-ui/themes';
|
import { Button, Flex, Heading } from '@radix-ui/themes';
|
||||||
import { use } from 'react';
|
import { use } from 'react';
|
||||||
import { ProvisionButton } from '../../../../../../../components/ModuleButtons/ProvisionButton';
|
import { ProvisionsManager } from '../../../../../../../components/ProvisionsManager';
|
||||||
import { availableProvisions } from '../../../../../../../core/blitzkrieg/availableProvisions';
|
import { availableProvisions } from '../../../../../../../core/blitzkrieg/availableProvisions';
|
||||||
import { provisionDefinitions } from '../../../../../../../core/blitzkrieg/provisionDefinitions';
|
import { provisionDefinitions } from '../../../../../../../core/blitzkrieg/provisionDefinitions';
|
||||||
import { mutateDuel, useDuel } from '../../../../../../../stores/duel';
|
import { mutateDuel, useDuel } from '../../../../../../../stores/duel';
|
||||||
@@ -33,35 +33,16 @@ export function Provisions() {
|
|||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex wrap="wrap">
|
<ProvisionsManager
|
||||||
{provisionsList.map((provision, index) => {
|
provisions={provisionsList.map((provision) => provision.id)}
|
||||||
const selected = provisions.includes(provision.id);
|
selected={provisions}
|
||||||
|
disabled={tank.provisions === provisionsList.length}
|
||||||
return (
|
onChange={(provisions) => {
|
||||||
<ProvisionButton
|
mutateDuel((draft) => {
|
||||||
key={provision.id}
|
draft.protagonist!.provisions = provisions;
|
||||||
first={index === 0}
|
});
|
||||||
last={index === provisionsList.length - 1}
|
}}
|
||||||
rowChild
|
/>
|
||||||
disabled={tank.provisions === provisions.length && !selected}
|
|
||||||
provision={provision.id}
|
|
||||||
selected={selected}
|
|
||||||
onClick={() => {
|
|
||||||
mutateDuel((draft) => {
|
|
||||||
if (selected) {
|
|
||||||
draft.protagonist!.provisions =
|
|
||||||
draft.protagonist!.provisions.filter(
|
|
||||||
(id) => id !== provision.id,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
draft.protagonist!.provisions.push(provision.id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Flex>
|
|
||||||
</ConfigurationChildWrapper>
|
</ConfigurationChildWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { Flex } from '@radix-ui/themes';
|
||||||
|
import { ProvisionButton } from './ModuleButtons/ProvisionButton';
|
||||||
|
|
||||||
|
interface ProvisionsManagerProps {
|
||||||
|
provisions: number[];
|
||||||
|
selected: number[];
|
||||||
|
disabled?: boolean;
|
||||||
|
onChange?: (provisions: number[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProvisionsManager({
|
||||||
|
provisions,
|
||||||
|
selected,
|
||||||
|
onChange,
|
||||||
|
disabled,
|
||||||
|
}: ProvisionsManagerProps) {
|
||||||
|
return (
|
||||||
|
<Flex wrap="wrap">
|
||||||
|
{provisions.map((provision, index) => {
|
||||||
|
const isSelected = selected.includes(provision);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ProvisionButton
|
||||||
|
key={provision}
|
||||||
|
first={index === 0}
|
||||||
|
last={index === provisions.length - 1}
|
||||||
|
rowChild
|
||||||
|
disabled={disabled && !selected}
|
||||||
|
provision={provision}
|
||||||
|
selected={isSelected}
|
||||||
|
onClick={() => {
|
||||||
|
if (!onChange) return;
|
||||||
|
|
||||||
|
const draft = [...selected];
|
||||||
|
|
||||||
|
if (isSelected) {
|
||||||
|
draft.splice(draft.indexOf(provision), 1);
|
||||||
|
} else {
|
||||||
|
draft.push(provision);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(draft);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user