Skip to content

Commit

Permalink
Add equipment types management
Browse files Browse the repository at this point in the history
Fixes #155
  • Loading branch information
Perdolique committed Sep 25, 2024
1 parent 894060d commit eaf9641
Show file tree
Hide file tree
Showing 21 changed files with 1,408 additions and 216 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
<template>
<div :class="$style.component">
<Icon
name="tabler:backpack"
:name="icon"
size="1.5em"
/>

<span>
Inventory is empty
</span>
<slot />
</div>
</template>

<script lang="ts" setup>
interface Props {
readonly icon: string;
}
defineProps<Props>();
</script>

<style module>
.component {
display: flex;
Expand All @@ -20,5 +26,7 @@
padding: var(--spacing-32);
color: var(--input-color-main);
background-color: var(--element-color-background);
border: 1px solid var(--input-color-main);
border-radius: var(--border-radius-16);
}
</style>
100 changes: 100 additions & 0 deletions app/components/dialogs/AddEquipmentTypeDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<ModalDialog v-model="isOpened">
<form
method="dialog"
:class="$style.content"
@submit="handleSubmit"
>
<div :class="$style.header">
Add new equipment type
</div>

<input
required
autofocus
placeholder="Sleeping bag"
v-model="typeName"
:class="$style.input"
:maxlength="limits.maxEquipmentTypeNameLength"
type="text"
/>

<div :class="$style.buttons">
<PerdButton
secondary
type="button"
@click="handleCancelClick"
>
Cancel
</PerdButton>

<PerdButton>
Add type
</PerdButton>
</div>
</form>
</ModalDialog>
</template>

<script lang="ts" setup>
import { limits } from '~~/constants';
import PerdButton from '~/components/PerdButton.vue'
import ModalDialog from './ModalDialog.vue'
type Emits = (event: 'submit', typeName: string) => void
const emit = defineEmits<Emits>()
const typeName = ref('')
const isOpened = defineModel<boolean>({
required: true
})
function handleCancelClick() {
isOpened.value = false
}
function handleSubmit(event: Event) {
if (typeName.value !== '') {
emit('submit', typeName.value)
}
}
// Reset form when dialog is opened
watch(isOpened, (value) => {
if (value) {
typeName.value = ''
}
})
</script>

<style module>
.content {
display: grid;
row-gap: var(--spacing-24);
background-color: var(--dialog-color-background);
padding: var(--dialog-padding);
border-radius: var(--dialog-border-radius);
border: 1px solid var(--dialog-color-border);
}
.header {
font-size: var(--font-size-20);
font-weight: var(--font-weight-medium);
text-align: center;
}
.input {
text-align: center;
}
.input::placeholder {
user-select: none;
}
.buttons {
display: grid;
grid-auto-flow: column;
column-gap: var(--spacing-16);
}
</style>
69 changes: 27 additions & 42 deletions app/components/equipment/EquipmentTable.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
<template>
<div :class="$style.component">
<table :class="$style.table">
<thead
v-if="hasItems"
:class="$style.header"
>
<thead :class="$style.header">
<tr :class="$style.row">
<th :class="[$style.cell, 'name']">
Name
Expand All @@ -19,50 +16,39 @@
</thead>

<tbody :class="$style.body">
<template v-if="hasItems">
<tr
v-for="item in equipment"
:key="item.id"
:class="$style.row"
>
<td :class="[$style.cell, 'name']">
{{ item.name }}
</td>

<td :class="[$style.cell, 'weight']">
{{ item.weight }}
</td>

<td :class="[$style.cell, 'actions']">
<div :class="$style.action">
<PerdButton
small
secondary
icon="tabler:trash"
@click="removeItem(item)"
>
Retire
</PerdButton>
</div>
</td>
</tr>
</template>

<template v-else>
<tr>
<td colspan="3">
<EmptyContent />
</td>
</tr>
</template>
<tr
v-for="item in equipment"
:key="item.id"
:class="$style.row"
>
<td :class="[$style.cell, 'name']">
{{ item.name }}
</td>

<td :class="[$style.cell, 'weight']">
{{ item.weight }}
</td>

<td :class="[$style.cell, 'actions']">
<div :class="$style.action">
<PerdButton
small
secondary
icon="tabler:trash"
@click="removeItem(item)"
>
Retire
</PerdButton>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</template>

<script lang="ts" setup generic="Item extends EquipmentItem">
import PerdButton from '~/components/PerdButton.vue';
import EmptyContent from './EmptyContent.vue';
export interface EquipmentItem {
readonly id: number;
Expand All @@ -78,7 +64,6 @@
const { equipment } = defineProps<Props>()
const emit = defineEmits<Emits>()
const hasItems = computed(() => equipment.length > 0)
async function removeItem(item: Item) {
emit('remove', item)
Expand Down
59 changes: 0 additions & 59 deletions app/composables/use-equipment-search.ts

This file was deleted.

27 changes: 27 additions & 0 deletions app/composables/use-equipment-types-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
interface EquipmentType {
readonly id: number
readonly name: string
}

export default async function useEquipmentTypesData() {
const types = ref<EquipmentType[]>([])

const sortedTypes = computed(
() => types.value.sort((typeA, typeB) => typeA.name.localeCompare(typeB.name))
)

const { data } = await useFetch('/api/equipment/type')

if (data.value !== undefined) {
types.value = data.value
}

function addType(type: EquipmentType) {
types.value.push(type)
}

return {
addType,
types: sortedTypes
}
}
10 changes: 10 additions & 0 deletions app/pages/inventory.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,25 @@
</PerdSearch>

<EquipmentTable
v-if="hasItems"
:equipment="equipment"
@remove="removeItem"
/>

<EmptyState
v-else
icon="tabler:backpack"
>
Inventory is empty
</EmptyState>
</div>
</template>

<script lang="ts" setup>
import EquipmentTable from '~/components/equipment/EquipmentTable.vue';
import SearchOptionAdd from '~/components/PerdSearch/SearchOptionAdd.vue';
import PerdSearch from '~/components/PerdSearch/PerdSearch.vue';
import EmptyState from '~/components/EmptyState.vue';
interface EquipmentItem {
readonly id: number;
Expand All @@ -42,6 +51,7 @@
const isSearching = ref(false);
const options = ref<EquipmentItem[]>([]);
const { equipment, updateEquipment } = await useUserEquipment()
const hasItems = computed(() => equipment.value.length > 0)
async function search(searchString: string) {
try {
Expand Down
Loading

0 comments on commit eaf9641

Please sign in to comment.