#134 - fill users data for resume (#144)

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* lint fixes

* missing empty lines

* translations

* fix vue version

* #134 - fixes

* fix

* fix

* #134 - fix

* fix

* fix

* #134 - added tests

* #134 - fix to translations

* #134 - tests

* #134 - fix

* Update database/factories/ResumeFactory.php

Co-authored-by: Krzysztof Rewak <krzysztof.rewak@gmail.com>

* #134 - fix

* #134 - fix

Co-authored-by: EwelinaLasowy <ewelina.lasowy@blumilk.pl>
Co-authored-by: Krzysztof Rewak <krzysztof.rewak@gmail.com>
This commit is contained in:
Adrian Hopek
2022-05-18 08:50:41 +02:00
committed by GitHub
parent 7154caa340
commit 431262dfb7
42 changed files with 4697 additions and 1017 deletions

View File

@@ -0,0 +1,68 @@
<template>
<Combobox
as="div"
nullable
>
<div class="relative">
<ComboboxInput
:id="id"
class="w-full h-12 rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 shadow-sm focus:border-blumilk-500 focus:outline-none focus:ring-1 focus:ring-blumilk-500 sm:text-sm"
@change="query = $event.target.value"
/>
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none">
<SelectorIcon class="h-5 w-5 text-gray-400" />
</ComboboxButton>
<ComboboxOptions
v-if="filteredItems.length"
class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
>
<ComboboxOption
v-for="item in filteredItems"
:key="item.id"
v-slot="{ active, selected }"
:value="item"
as="template"
>
<li :class="['relative cursor-default select-none py-2 pl-3 pr-9', active ? 'bg-blumilk-600 text-white' : 'text-gray-900']">
<span :class="['block truncate', selected && 'font-semibold']">
{{ item }}
</span>
<span
v-if="selected"
:class="['absolute inset-y-0 right-0 flex items-center pr-4', active ? 'text-white' : 'text-blumilk-600']"
>
<CheckIcon class="h-5 w-5" />
</span>
</li>
</ComboboxOption>
</ComboboxOptions>
</div>
</Combobox>
</template>
<script setup>
import { computed, ref } from 'vue'
import { CheckIcon, SelectorIcon } from '@heroicons/vue/solid'
import {
Combobox,
ComboboxButton,
ComboboxInput,
ComboboxOption,
ComboboxOptions,
} from '@headlessui/vue'
const props = defineProps({
items: Array,
id: String,
})
const query = ref('')
const filteredItems = computed(() =>
query.value === ''
? props.items
: props.items.filter((item) => item.toLowerCase().includes(query.value.toLowerCase())),
)
</script>

View File

@@ -0,0 +1,113 @@
<template>
<div>
<h3 class="text-lg font-medium leading-6 text-gray-900">
{{ header }}
</h3>
<Draggable
v-model="items"
class="pt-4 space-y-4"
tag="transition-group"
ghost-class="opacity-50"
handle=".handle"
:animation="200"
:component-data="{tag: 'div', type: 'transition-group'}"
:item-key="((item) => items.indexOf(item))"
>
<template #item="{ element, index }">
<div class="group flex items-start space-x-3">
<button
class="py-4 text-red-500 hover:text-gray-600 opacity-100 group-hover:opacity-100 transition-opacity hover:scale-110 lg:opacity-0 handle"
type="button"
>
<ViewGridIcon class="w-5 h-5 text-gray-500" />
</button>
<Disclosure
v-slot="{ open }"
as="div"
class="flex-1 border border-gray-200"
>
<div class="flex">
<DisclosureButton class="transition transition-colors rounded-md group w-full max-w-full overflow-hidden flex items-center justify-between p-4 font-semibold text-gray-500 hover:text-blumilk-500 transition transition-colors rounded-md focus:outline-none">
<div class="break-all line-clamp-1 text-md">
<slot
name="itemHeader"
:element="element"
:index="index"
/>
</div>
<div class="ml-2">
<svg
:class="[open ? '-rotate-90' : 'rotate-90', 'h-6 w-6 transform transition-transform ease-in-out duration-150']"
viewBox="0 0 20 20"
>
<path
d="M6 6L14 10L6 14V6Z"
fill="currentColor"
/>
</svg>
</div>
</DisclosureButton>
</div>
<DisclosurePanel
as="div"
class="py-2 px-4 border-t border-gray-200"
>
<slot
name="form"
:element="element"
:index="index"
/>
</DisclosurePanel>
</Disclosure>
<button
class="py-4 text-red-500 hover:text-red-600 opacity-100 group-hover:opacity-100 transition-opacity hover:scale-110 lg:opacity-0"
type="button"
@click="removeItem(index)"
>
<TrashIcon class="w-5 h-5 text-red-500" />
</button>
</div>
</template>
</Draggable>
<div class="px-8">
<button
type="button"
class="p-4 mx-auto mt-4 w-full font-semibold text-center text-blumilk-600 hover:bg-blumilk-25 focus:outline-none transition-colors"
@click="addItem()"
>
{{ addLabel }}
</button>
</div>
</div>
</template>
<script setup>
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue'
import { TrashIcon, ViewGridIcon } from '@heroicons/vue/outline'
import Draggable from 'vuedraggable'
import { computed } from 'vue'
const props = defineProps({
header: String,
addLabel: String,
modelValue: Object,
itemHeader: [Function, String],
})
const emit = defineEmits(['update:modelValue', 'addItem', 'removeItem'])
const items = computed({
get: () => props.modelValue,
set: (value) => {
emit('update:modelValue', value)
},
})
function addItem() {
emit('addItem')
}
function removeItem(index) {
emit('removeItem', index)
}
</script>

View File

@@ -0,0 +1,46 @@
<template>
<RadioGroup v-model="selectedValue">
<div
:class="`relative overflow-hidden flex h-12 rounded-l-md rounded-r-md space-x-px ${selectedValue.activeColor} transition-colors duration-200 easy-in-out`"
>
<RadioGroupOption
v-for="(level, index) in levels"
:key="index"
as="template"
:value="level"
>
<div
:class="`${selectedValue.backgroundColor} hover:opacity-80 cursor-pointer transition-colors duration-200 easy-in-out focus:outline-none flex-1`"
/>
</RadioGroupOption>
<div
:class="`absolute transform transition-transform duration-200 easy-in-out`"
:style="`width: ${100/levels.length}%; transform: translateX(calc(${100 * currentIndex}% - 1px))`"
>
<div :class="`h-12 ${selectedValue.activeColor} transition-colors duration-300 easy-in-out`" />
</div>
</div>
</RadioGroup>
</template>
<script setup>
import { RadioGroup, RadioGroupOption } from '@headlessui/vue'
import { computed } from 'vue'
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
levels: Array,
modelValue: Object,
})
const selectedValue = computed({
get: () => props.modelValue,
set: (value) => {
emit('update:modelValue', value)
},
})
const currentIndex = computed(() => props.levels.findIndex((level) => level.level === selectedValue.value.level))
</script>

View File

@@ -0,0 +1,18 @@
<template>
<FlatPickr :config="config" />
</template>
<script setup>
import FlatPickr from 'vue-flatpickr-component'
import monthSelectPlugin from 'flatpickr/dist/plugins/monthSelect'
const config = {
plugins: [
new monthSelectPlugin({
shorthand: true,
dateFormat: 'm/Y',
}),
],
}
</script>

View File

@@ -0,0 +1,108 @@
<template>
<Combobox
v-model="selectedItems"
as="div"
nullable
multiple
>
<div class="flex flex-wrap gap-3">
<span
v-for="(item, index) in selectedItems"
:key="index"
class="inline-flex items-center py-1.5 pl-3 pr-1.5 rounded-lg text-sm font-medium bg-blumilk-500 text-white"
>
{{ item }}
<button
type="button"
class="flex-shrink-0 ml-0.5 h-5 w-5 rounded-full inline-flex items-center justify-center text-white hover:bg-blumilk-600 focus:outline-none"
@click="selectedItems.splice(index, 1)"
>
<svg
class="h-2 w-2"
stroke="currentColor"
fill="none"
viewBox="0 0 8 8"
>
<path
stroke-linecap="round"
stroke-width="1.5"
d="M1 1l6 6m0-6L1 7"
/>
</svg>
</button>
</span>
</div>
<div class="relative mt-2">
<ComboboxInput
:id="id"
class="w-full rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 shadow-sm focus:border-blumilk-500 focus:outline-none focus:ring-1 focus:ring-blumilk-500 sm:text-sm"
@change="query = $event.target.value"
/>
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none">
<SelectorIcon class="h-5 w-5 text-gray-400" />
</ComboboxButton>
<ComboboxOptions
v-if="filteredItems.length"
class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
>
<ComboboxOption
v-for="item in filteredItems"
:key="item.id"
v-slot="{ active, selected }"
:value="item"
as="template"
>
<li :class="['relative cursor-default select-none py-2 pl-3 pr-9', active ? 'bg-blumilk-600 text-white' : 'text-gray-900']">
<span :class="['block truncate', selected && 'font-semibold']">
{{ item }}
</span>
<span
v-if="selected"
:class="['absolute inset-y-0 right-0 flex items-center pr-4', active ? 'text-white' : 'text-blumilk-600']"
>
<CheckIcon class="h-5 w-5" />
</span>
</li>
</ComboboxOption>
</ComboboxOptions>
</div>
</Combobox>
</template>
<script setup>
import { computed, ref } from 'vue'
import { CheckIcon, SelectorIcon } from '@heroicons/vue/solid'
import {
Combobox,
ComboboxButton,
ComboboxInput,
ComboboxOption,
ComboboxOptions,
} from '@headlessui/vue'
const props = defineProps({
items: Array,
modelValue: Array,
id: String,
})
const emit = defineEmits(['update:modelValue'])
const query = ref('')
const selectedItems = computed({
get: () => props.modelValue,
set: (value) => {
query.value = ''
emit('update:modelValue', value)
},
})
const filteredItems = computed(() =>
query.value === ''
? props.items
: props.items.filter((item) => item.toLowerCase().includes(query.value.toLowerCase())),
)
</script>