Added DayJS

Restructured Products
Some Changes in Documents
Some Changes with Logo
This commit is contained in:
2023-12-14 20:58:52 +01:00
parent 2dd31690e5
commit cd36514e1c
10 changed files with 426 additions and 248 deletions

View File

@@ -3,7 +3,7 @@
const user = useSupabaseUser()
console.log(user)
//console.log(user.value)
const router = useRouter()
const route = useRoute()
const colorMode = useColorMode()
@@ -11,9 +11,14 @@ const supabase = useSupabaseClient()
const tenants = (await supabase.from("tenants").select()).data
const {loaded, profiles} = storeToRefs(useDataStore())
const {fetchData, getProfileById} = useDataStore()
const userProfile = user.value ? getProfileById(user.value.id) : {}
const userProfile = (user.value ? getProfileById(user.value.id) : {})
//console.log(userProfile)
const viewport = useViewport()
watch(viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
})
fetchData()
@@ -110,26 +115,7 @@ generateLinks()
const userTenant = ref({})
if(user) userTenant.value = tenants.find(tenant => tenant.id === user.value.app_metadata.tenant)
const userDropdownItems = [
[
{
label: user.value ? user.value.email : "Profil",
},/*{
label: user ? userTenant.value.name : "",
}*/
],
[
{
label: "Logout",
click: () => {
router.push("/login")
}
}
]
]
useHead({
@@ -182,8 +168,16 @@ const items = [
<UHeader :links="navLinks">
<template #logo>
<div id="logo">
<img v-if="colorMode.value === 'dark'" src="/spaces.svg"/>
<img v-else src="/spaces_hell.svg"/>
<img
v-if="colorMode.value === 'light'"
alt="Logo Hell"
src="/spaces_hell.svg"
/>
<img
v-else
src="/spaces_hell.svg"
alt="Logo Dunkel"
/>
</div>
</template>

View File

@@ -36,6 +36,7 @@
"@zip.js/zip.js": "^2.7.32",
"axios": "^1.6.2",
"buffer": "^6.0.3",
"dayjs": "^1.11.10",
"jsprintmanager": "^6.0.3",
"nuxt-editorjs": "^1.0.4",
"nuxt-viewport": "^2.0.6",

View File

@@ -74,14 +74,14 @@
fullscreen
>
<UCard class="h-full">
{{selectedDocument}}
<!-- <embed
<embed
class="bigPreview mb-3"
:src="selectedDocument.url"
/>-->
/>
<UBadge
v-for="tag in selectedDocument.tags"
class="ml-2"
>
{{tag}}
</UBadge>
@@ -98,6 +98,17 @@
/>
</UFormGroup>
<UFormGroup
label="Tags ändern:"
>
<USelectMenu
:options="tags"
v-model="selectedDocument.tags"
@change="updateDocument"
multiple
/>
</UFormGroup>
@@ -169,8 +180,12 @@ definePageMeta({
})
const supabase = useSupabaseClient()
const user = useSupabaseUser()
const toast = useToast()
const {documents} = storeToRefs(useDataStore())
const {fetchDocuments} = useDataStore()
fetchDocuments()
const tabOpen = ref(0)
const uploadModalOpen = ref(false)
@@ -183,7 +198,7 @@ const fileUploadFormData = ref({
const selectedDocuments = ref([])
let tags = ["Eingangsrechnung","Ausgangrechnung","Mahnung", "Dokument"]
let tags = ["Eingangsrechnung","Ausgangrechnung","Mahnung", "Dokument", "E-Mail Anhang"]
const folders = [
{
label: "Eingang",
@@ -237,7 +252,29 @@ const uploadFile = async () => {
uploadModalOpen.value = false;
}
const updateDocument = async () => {
console.log(selectedDocument.value)
let objData = selectedDocument.value
delete objData.url
const {data,error} = await supabase
.from("documents")
.update(objData)
.eq('id',objData.id)
.select()
console.log(data)
if(error) {
console.log(error)
} else {
toast.add({title: "Dokument aktualisiert"})
selectedDocument.value = data[0]
showDocumentModal.value = false
fetchDocuments()
}
}
const changeFolder = async () => {
console.log("Change Folder")

View File

@@ -1,6 +1,5 @@
<script setup>
import FullCalendar from "@fullcalendar/vue3"
import dayGridPlugin from '@fullcalendar/daygrid'
import resourceTimelinePlugin from '@fullcalendar/resource-timeline'
import deLocale from '@fullcalendar/core/locales/de'
import interactionPlugin from '@fullcalendar/interaction'
@@ -50,7 +49,8 @@ const calendarOptionsList = reactive({
plugins: [listPlugin],
initialView: "listWeek",
initialEvents: events,
nowIndicator: true
nowIndicator: true,
height: "80vh"
})
const calendarOptionsTimeline = reactive({
@@ -171,4 +171,5 @@ const calendarOptionsTimeline = reactive({
</template>
<style scoped>
</style>

View File

@@ -1,209 +0,0 @@
<template>
<div id="main">
<div id="left">
<UButton @click="showCreateProduct = true" >+ Artikel</UButton>
<UModal v-model="showCreateProduct">
<UCard :ui="{ ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }">
<template #header>
Artikel erstellen
</template>
<UFormGroup
label="Name:"
>
<UInput
v-model="createProductData.name"
/>
</UFormGroup>
<UFormGroup
label="Hersteller:"
>
<UInput
v-model="createProductData.manufacturer"
/>
</UFormGroup>
<UFormGroup
label="Einheit:"
>
<USelectMenu
v-model="createProductData.unit"
:options="units"
value-attribute="id"
option-attribute="name"
/>
</UFormGroup>
<template #footer>
<UButton @click="createProduct">Erstellen</UButton>
</template>
</UCard>
</UModal>
<div class="listContainer">
<a v-for="item in products" @click="selectItem(item)">
<UCard class="listItem">
<UBadge>{{item.id}}</UBadge> {{item.name}} - {{item.manufacturer}}
</UCard>
</a>
</div>
</div>
<div id="right">
<div v-if="false">
<img
v-if="selectedItem.image"
:src="'http://localhost:1337' + selectedItem.image.data.url"/>
{{selectedItem.image.data.url}}
</div>
<UCard v-if="selectedItem.id">
<template #header>
<UBadge>{{selectedItem.id}}</UBadge> {{selectedItem.name}}
</template>
<UBadge
v-for="tag in selectedItem.tags"
class="mr-2"
>
{{tag}}
</UBadge>
<UDivider class="my-3"/>
<div v-if="selectedItem">
Hersteller: {{selectedItem.manufacturer}}<br>
Einkaufspreis: {{selectedItem.purchasePriceNet}} <br>
Aufschlag: {{selectedItem.profitPercentage}} %<br>
Verkaufspreis: {{selectedItem.retailPriceNet}} <br>
</div>
<!--<UDivider class="my-3"/>
<p>Verlauf:</p>
<table>
<tr
v-for="item in history"
class="historyItem"
>
<td>
{{item.position}}
</td>
<td>
{{item.date}}
</td>
<td>
<UBadge>{{item.user}}</UBadge>
</td>
<td>
{{item.message}}
</td>
</tr>
</table>-->
<!-- <div
v-for="item in history"
class="historyItem"
>
<p>{{item.message}}</p>
<UBadge>{{item.user}}</UBadge>
</div>-->
</UCard> {{selectedItem}}
</div>
</div>
</template>
<script setup>
definePageMeta({
middleware: "auth"
})
const supabase = useSupabaseClient()
const {products,units} = storeToRefs(useDataStore())
const showCreateProduct = ref(false)
const createProductData = ref({})
let selectedItem = ref({})
const history = ref([
{
position: 0,
message: "Produkt erstellt",
date: "2023-11-20",
user: "flfeders"
}
])
const selectItem = (item) => {
selectedItem.value = item
console.log(item)
}
const createProduct = async () => {
//await create('products', createProductData.value)
const {data,error} = await supabase
.from("products")
.insert([createProductData.value])
.select()
console.log(error)
showCreateProduct.value = false
createProductData.value = {}
}
</script>
<style scoped>
#main {
display: flex;
flex-direction: row;
}
#left {
width: 25vw;
overflow: hidden;
}
#right {
width: 60vw;
padding-left: 3vw;
}
.listContainer {
height: 75vh;
overflow: auto;
margin-top: 3vh;
}
.historyItem >td {
border: 0.5px solid grey;
border-radius: 15px;
padding: 1em
}
/* Hide scrollbar for Chrome, Safari and Opera */
.listContainer::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
.listContainer {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
</style>

View File

@@ -0,0 +1,229 @@
<script setup>
definePageMeta({
middleware: "auth"
})
//
const supabase = useSupabaseClient()
const route = useRoute()
const router = useRouter()
const toast = useToast()
const id = ref(route.params.id ? route.params.id : null )
//Store
const {products, units, ownTenant } = storeToRefs(useDataStore())
const {fetchProducts, getProductById, getStockByProductId} = useDataStore()
let currentProduct = null
//Working
const mode = ref(route.params.mode || "show")
const itemInfo = ref({
unit: 1,
tags: []
})
//Functions
const setupPage = () => {
if(mode.value === "show" || mode.value === "edit"){
currentProduct = getProductById(Number(useRoute().params.id))
}
if(mode.value === "edit") itemInfo.value = currentProduct
}
const createItem = async () => {
const {data,error} = await supabase
.from("products")
.insert([itemInfo.value])
.select()
if(error) {
console.log(error)
} else {
mode.value = "show"
itemInfo.value = {
id: 0,
name: ""
}
toast.add({title: "Artikel erfolgreich erstellt"})
await fetchProducts()
router.push(`/products/show/${data[0].id}`)
setupPage()
}
}
const editItem = async () => {
router.push(`/products/edit/${currentProduct.id}`)
setupPage()
}
const cancelEditorCreate = () => {
mode.value = "show"
itemInfo.value = {
id: 0,
}
}
const updateItem = async () => {
const {error} = await supabase
.from("products")
.update(itemInfo.value)
.eq('id',itemInfo.value.id)
if(error) {
console.log(error)
} else {
mode.value = "show"
itemInfo.value = {
id: 0,
name: "",
}
toast.add({title: "Artikel erfolgreich gespeichert"})
fetchProducts()
}
}
setupPage()
</script>
<template>
<div>
<UCard v-if="currentProduct && mode == 'show'" >
<template #header>
{{currentProduct.name}}
</template>
<UBadge
v-for="tag in currentProduct.tags"
class="mr-2"
>
{{tag}}
</UBadge>
<UDivider
class="my-2"
/>
Bestand: {{getStockByProductId(currentProduct.id)}} {{units.find(unit => unit.id === currentProduct.unit) ? units.find(unit => unit.id === currentProduct.unit).name : ""}}
<UDivider
class="my-2"
/>
{{currentProduct}}
<template #footer>
<UButton
v-if="mode == 'show' && currentProduct.id"
@click="editItem"
>
Bearbeiten
</UButton>
<UButton
color="red"
class="ml-2"
disabled
>
Archivieren
</UButton>
<!-- TODO: Produkt archivieren -->
</template>
</UCard>
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
<template #header>
{{itemInfo.name}}
</template>
<UFormGroup
label="Name:"
>
<UInput
v-model="itemInfo.name"
/>
</UFormGroup>
<UFormGroup
label="Hersteller:"
>
<UInput
v-model="itemInfo.manufacturer"
/>
</UFormGroup>
<UFormGroup
label="Einheit:"
>
<USelectMenu
v-model="itemInfo.unit"
:options="units"
option-attribute="name"
value-attribute="id"
>
<template #label>
{{units.find(unit => unit.id === itemInfo.unit) ? units.find(unit => unit.id === itemInfo.unit).name : itemInfo.unit }}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Tags:"
>
<USelectMenu
v-model="itemInfo.tags"
:options="ownTenant.tags.products"
multiple
/>
</UFormGroup>
<UFormGroup
label="EAN:"
>
<UInput
v-model="itemInfo.ean"
/>
</UFormGroup>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="updateItem"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="createItem"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</div>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,92 @@
<template>
<div>
<UButton @click="router.push(`/products/create/`)">+ Artikel</UButton>
<UInput
v-model="searchString"
placeholder="Suche..."
/>
<UTable
:rows="filteredRows"
:columns="itemColumns"
@select="selectItem"
>
<template #tags-data="{row}">
<UBadge
v-if="row.tags.length > 0"
v-for="tag in row.tags"
class="mr-2"
>
{{tag}}
</UBadge>
<span v-else>-</span>
</template>
<template #unit-data="{row}">
{{units.find(unit => unit.id === row.unit) ? units.find(unit => unit.id === row.unit).name : row.unit}}
</template>
</UTable>
</div>
</template>
<script setup>
definePageMeta({
middleware: "auth"
})
const supabase = useSupabaseClient()
const router = useRouter()
const {products,units} = storeToRefs(useDataStore())
const itemColumns = [
{
key: "id",
label: "Id"
},
{
key: "name",
label: "Name"
},
{
key: "manufacturer",
label: "Hersteller",
},
{
key: "unit",
label: "Einheit"
},
{
key: "tags",
label: "Tags"
}
]
const selectItem = (item) => {
console.log(item)
router.push(`/products/show/${item.id} `)
}
const searchString = ref('')
const filteredRows = computed(() => {
if(!searchString.value) {
return products.value
}
return products.value.filter(product => {
return Object.values(product).some((value) => {
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
})
})
})
</script>
<style scoped>
</style>

View File

@@ -3,11 +3,13 @@ definePageMeta({
middleware: "auth"
})
import * as dayjs from 'dayjs'
const supabase = useSupabaseClient()
const route = useRoute()
const {getProjectById, getFormSubmitsWithLabelProp, getTimesByProjectId} = useDataStore()
const {forms, formSubmits, times} = storeToRefs(useDataStore())
const {forms, formSubmits, times, profiles} = storeToRefs(useDataStore())
const currentProject = getProjectById(Number(route.params.id))
@@ -252,7 +254,19 @@ const phaseInfo = ref({
<UTable
:rows="getTimesByProjectId(currentProject.id)"
:columns="timeTableRows"
/>
>
<template #user-data="{row}">
{{profiles.find(profile => profile.id === row.user) ? profiles.find(profile => profile.id === row.user).firstName + " " + profiles.find(profile => profile.id === row.user).lastName : row.user }}
</template>
<template #start-data="{row}">
{{dayjs(row.start).format("DD.MM.YY HH:mm")}}
</template>
<template #end-data="{row}">
{{dayjs(row.end).format("DD.MM.YY HH:mm")}}
</template>
</UTable>
</div>
<div v-else-if="item.key === 'material'" class="space-y-3">
<p>Hier wird aktuell noch gearbeitet</p>

View File

@@ -49,7 +49,13 @@
:columns="projectColumns"
@select="selectProject"
/>
>
<template #customer-data="{row}">
{{customers.find(customer => customer.id == row.customer ) ? customers.find(customer => customer.id == row.customer ).name : row.id}}
</template>
</UTable>

View File

@@ -38,20 +38,23 @@ export const useDataStore = defineStore('data', {
await this.fetchOwnTenant()
await this.fetchProfiles()
await this.fetchEvents()
await this.fetchCustomers()
await this.fetchTasks()
await this.fetchProjects()
await this.fetchTimes()
await this.fetchJobs()
this.loaded = true
await this.fetchCustomers()
await this.fetchForms()
await this.fetchFormSubmits()
await this.fetchProducts()
await this.fetchUnits()
await this.fetchProjects()
await this.fetchDocuments()
//await this.fetchDocuments()
await this.fetchMovements()
await this.fetchTimes()
await this.fetchJobs()
await this.fetchSpaces()
await this.fetchVehicles()
this.loaded = true
},
async fetchOwnTenant() {
//TODO: Tenant ID Dynamisch machen
@@ -84,7 +87,7 @@ export const useDataStore = defineStore('data', {
},
async fetchProducts() {
// @ts-ignore
this.products = (await supabase.from("products").select()).data
this.products = (await supabase.from("products").select().order('id',{ascending: true})).data
},
async fetchUnits() {
// @ts-ignore
@@ -128,6 +131,16 @@ export const useDataStore = defineStore('data', {
getProfileById: (state) => (userUid:string) => state.profiles.find(profile => profile.id === userUid),
getOpenTasksCount: (state) => state.tasks.filter(task => task.categorie != "Erledigt").length,
movementsBySpace: (state) => (spaceId:number) => state.movements.filter(move => move.spaceId === spaceId),
getStockByProductId: (state) => (productId:number) => {
let movements = state.movements.filter((movement:any) => movement.productId === productId)
let count = 0
movements.forEach(movement => count += movement.quantity)
return count
},
getProductById: (state) => (productId:number) => state.products.find(product => product.id === productId),
getProjectById: (state) => (projectId:number) => {
let project = state.projects.find(project => project.id === projectId)