forked from mirrors/homebox
style updates
This commit is contained in:
parent
f4f7123073
commit
6bbe62823d
19 changed files with 337 additions and 107 deletions
|
@ -64,48 +64,52 @@
|
|||
<LabelCreateModal v-model="modals.label" />
|
||||
<LocationCreateModal v-model="modals.location" />
|
||||
|
||||
<BaseContainer is="header" class="py-6">
|
||||
<h2 class="mt-1 text-4xl font-bold tracking-tight text-base-content sm:text-5xl lg:text-6xl flex">
|
||||
HomeB
|
||||
<AppLogo class="w-12 -mb-4" style="padding-left: 3px; padding-right: 2px" />
|
||||
x
|
||||
</h2>
|
||||
<div class="ml-1 mt-2 text-lg text-base-content/50 space-x-2">
|
||||
<template v-for="link in links">
|
||||
<NuxtLink
|
||||
v-if="!link.action"
|
||||
class="hover:text-base-content transition-color duration-200 italic"
|
||||
:to="link.href"
|
||||
>
|
||||
{{ link.name }}
|
||||
</NuxtLink>
|
||||
<button
|
||||
for="location-form-modal"
|
||||
v-else
|
||||
@click="link.action"
|
||||
class="hover:text-base-content transition-color duration-200 italic"
|
||||
>
|
||||
{{ link.name }}
|
||||
</button>
|
||||
<span v-if="!link.last"> / </span>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex mt-6">
|
||||
<div class="dropdown">
|
||||
<label tabindex="0" class="btn btn-sm">
|
||||
<span>
|
||||
<Icon name="mdi-plus" class="mr-1 -ml-1" />
|
||||
</span>
|
||||
Create
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<li v-for="btn in dropdown">
|
||||
<button @click="btn.action">
|
||||
{{ btn.name }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="bg-neutral absolute shadow-xl top-0 h-[50vh] max-h-96 sm:h-[28vh] -z-10 w-full"></div>
|
||||
|
||||
<BaseContainer is="header" class="py-6 max-w-none">
|
||||
<BaseContainer>
|
||||
<h2 class="mt-1 text-4xl font-bold tracking-tight text-neutral-content sm:text-5xl lg:text-6xl flex">
|
||||
HomeB
|
||||
<AppLogo class="w-12 -mb-4" style="padding-left: 3px; padding-right: 2px" />
|
||||
x
|
||||
</h2>
|
||||
<div class="ml-1 mt-2 text-lg text-neutral-content/75 space-x-2">
|
||||
<template v-for="link in links">
|
||||
<NuxtLink
|
||||
v-if="!link.action"
|
||||
class="hover:text-base-content transition-color duration-200 italic"
|
||||
:to="link.href"
|
||||
>
|
||||
{{ link.name }}
|
||||
</NuxtLink>
|
||||
<button
|
||||
for="location-form-modal"
|
||||
v-else
|
||||
@click="link.action"
|
||||
class="hover:text-base-content transition-color duration-200 italic"
|
||||
>
|
||||
{{ link.name }}
|
||||
</button>
|
||||
<span v-if="!link.last"> / </span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex mt-6">
|
||||
<div class="dropdown">
|
||||
<label tabindex="0" class="btn btn-primary btn-sm">
|
||||
<span>
|
||||
<Icon name="mdi-plus" class="mr-1 -ml-1" />
|
||||
</span>
|
||||
Create
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<li v-for="btn in dropdown">
|
||||
<button @click="btn.action">
|
||||
{{ btn.name }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</BaseContainer>
|
||||
</BaseContainer>
|
||||
</template>
|
||||
|
|
|
@ -1,21 +1,18 @@
|
|||
<template>
|
||||
<div class="relative">
|
||||
<div class="absolute inset-0 flex items-center" aria-hidden="true">
|
||||
<div class="w-full border-t border-primary" />
|
||||
</div>
|
||||
<div class="relative flex justify-center">
|
||||
<span class="isolate inline-flex -space-x-px rounded-md shadow-sm">
|
||||
<div class="btn-group">
|
||||
<button @click="$emit('edit')" name="options" class="btn btn-sm btn-primary">
|
||||
<Icon name="heroicons-pencil" class="h-5 w-5 mr-1" aria-hidden="true" />
|
||||
<span> Edit </span>
|
||||
</button>
|
||||
<button @click="$emit('delete')" name="options" class="btn btn-sm btn-primary">
|
||||
<Icon name="heroicons-trash" class="h-5 w-5 mr-1" aria-hidden="true" />
|
||||
<span> Delete </span>
|
||||
</button>
|
||||
</div>
|
||||
</span>
|
||||
<div class="divider">
|
||||
<div class="btn-group min-w-[180px] flex-nowrap">
|
||||
<button @click="$emit('edit')" name="options" class="btn btn-sm btn-primary">
|
||||
<Icon name="heroicons-pencil" class="h-5 w-5 mr-1" aria-hidden="true" />
|
||||
<span> Edit </span>
|
||||
</button>
|
||||
<button @click="$emit('delete')" name="options" class="btn btn-sm btn-primary">
|
||||
<Icon name="heroicons-trash" class="h-5 w-5 mr-1" aria-hidden="true" />
|
||||
<span> Delete </span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineEmits(['edit', 'delete']);
|
||||
</script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="overflow-hidden card bg-base-100 shadow-xl sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6 bg-neutral">
|
||||
<h3 class="text-lg font-medium leading-6 text-neutral-content">
|
||||
<div class="overflow-hidden card bg-base-100 shadow-xl sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg font-medium leading-6">
|
||||
<slot name="title"></slot>
|
||||
</h3>
|
||||
<p v-if="$slots.subtitle" class="mt-1 max-w-2xl text-sm text-gray-500">
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
<template>
|
||||
<div class="border-b border-base-200 pb-3">
|
||||
<h3 class="text-xl font-medium leading-4 text-base-content">
|
||||
<div class="pb-3">
|
||||
<h3
|
||||
class="text-3xl font-bold tracking-tight"
|
||||
:class="{
|
||||
'text-neutral-content': dark,
|
||||
'text-content': !dark,
|
||||
}"
|
||||
>
|
||||
<slot />
|
||||
</h3>
|
||||
<p v-if="$slots.description" class="mt-2 max-w-4xl text-sm text-gray-500">
|
||||
|
@ -8,3 +14,12 @@
|
|||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineProps({
|
||||
dark: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</div>
|
||||
<ul
|
||||
tabindex="0"
|
||||
class="dropdown-content mb-1 menu shadow border border-gray-400 rounded bg-base-100 w-full z-[9999] max-h-96 overflow-y-scroll scroll-bar"
|
||||
class="dropdown-content mb-1 menu shadow border border-gray-400 rounded bg-base-100 w-full z-[9999] max-h-60 overflow-y-scroll scroll-bar"
|
||||
>
|
||||
<li
|
||||
v-for="(obj, idx) in items"
|
||||
|
|
30
frontend/components/Item/Card.vue
Normal file
30
frontend/components/Item/Card.vue
Normal file
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<NuxtLink
|
||||
class="group card bg-neutral text-neutral-content hover:bg-primary transition-colors duration-300"
|
||||
:to="`/item/${item.id}`"
|
||||
>
|
||||
<div class="card-body py-4 px-6">
|
||||
<h2 class="card-title">
|
||||
<Icon name="mdi-package-variant" />
|
||||
{{ item.name }}
|
||||
</h2>
|
||||
<p>{{ item.description }}</p>
|
||||
<div class="flex gap-2 flex-wrap justify-end">
|
||||
<LabelChip v-for="label in item.labels" :label="label" class="badge-primary group-hover:badge-secondary" />
|
||||
</div>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Item } from '~~/lib/api/classes/items';
|
||||
|
||||
defineProps({
|
||||
item: {
|
||||
type: Object as () => Item,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -26,6 +26,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type Location } from '~~/lib/api/classes/locations';
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
|
@ -39,7 +40,7 @@
|
|||
const loading = ref(false);
|
||||
const focused = ref(false);
|
||||
const form = reactive({
|
||||
location: {},
|
||||
location: {} as Location,
|
||||
name: '',
|
||||
description: '',
|
||||
color: '', // Future!
|
||||
|
@ -75,7 +76,18 @@
|
|||
});
|
||||
|
||||
async function create() {
|
||||
const { data, error } = await api.labels.create(form);
|
||||
if (!form.location) {
|
||||
return;
|
||||
}
|
||||
|
||||
const out = {
|
||||
name: form.name,
|
||||
description: form.description,
|
||||
locationId: form.location.id as string,
|
||||
labelIds: form.labels.map(l => l.id) as string[],
|
||||
};
|
||||
|
||||
const { data, error } = await api.items.create(out);
|
||||
if (error) {
|
||||
toast.error("Couldn't create label");
|
||||
return;
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
<script setup lang="ts">
|
||||
export type sizes = 'sm' | 'md' | 'lg';
|
||||
|
||||
import { Label } from '~~/lib/api/classes/labels';
|
||||
defineProps({
|
||||
label: {
|
||||
type: Object as () => Label,
|
||||
required: true,
|
||||
},
|
||||
size: {
|
||||
type: String as () => sizes,
|
||||
default: 'md',
|
||||
},
|
||||
});
|
||||
|
||||
const badge = ref(null);
|
||||
|
@ -15,13 +21,19 @@
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<NuxtLink ref="badge" :to="`/label/${label.id}`">
|
||||
<span class="badge badge-lg p-4">
|
||||
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
|
||||
<Icon name="heroicons-arrow-right" class="mr-2 swap-on"></Icon>
|
||||
<Icon name="heroicons-tag" class="mr-2 swap-off"></Icon>
|
||||
</label>
|
||||
{{ label.name }}
|
||||
</span>
|
||||
<NuxtLink
|
||||
class="badge"
|
||||
:class="{
|
||||
'p-3': size !== 'sm',
|
||||
'p-2 badge-sm': size === 'sm',
|
||||
}"
|
||||
ref="badge"
|
||||
:to="`/label/${label.id}`"
|
||||
>
|
||||
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
|
||||
<Icon name="heroicons-arrow-right" class="mr-2 swap-on"></Icon>
|
||||
<Icon name="heroicons-tag" class="mr-2 swap-off"></Icon>
|
||||
</label>
|
||||
{{ label.name }}
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
|
37
frontend/components/Location/Card.vue
Normal file
37
frontend/components/Location/Card.vue
Normal file
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<NuxtLink
|
||||
ref="card"
|
||||
:to="`/location/${location.id}`"
|
||||
class="card bg-primary text-primary-content transition duration-300"
|
||||
>
|
||||
<div class="card-body p-4">
|
||||
<h2 class="flex items-center gap-2">
|
||||
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
|
||||
<Icon name="heroicons-arrow-right" class="swap-on" />
|
||||
<Icon name="heroicons-map-pin" class="swap-off" />
|
||||
</label>
|
||||
{{ location.name }}
|
||||
<span class="badge badge-secondary badge-lg ml-auto text-secondary-content">
|
||||
{{ location.itemCount }}</span
|
||||
>
|
||||
</h2>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Location } from '~~/lib/api/classes/locations';
|
||||
|
||||
defineProps({
|
||||
location: {
|
||||
type: Object as () => Location,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const card = ref(null);
|
||||
const isHover = useElementHover(card);
|
||||
const { focused } = useFocus(card);
|
||||
|
||||
const isActive = computed(() => isHover.value || focused.value);
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue