#134 - fill users data for resume #144
| @@ -44,12 +44,12 @@ class ResumeFactory extends Factory | |||||||
|   
				
					
						
						krzysztofrewak
					
					
						commented  
						Review
						 ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   
				
					
						
						krzysztofrewak
					
					
						commented  
						Review
						 ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
|  |  | ||||||
|     protected function generateLanguages(): array |     protected function generateLanguages(): array | ||||||
|     { |     { | ||||||
|         $languages = new Collection(["english", "polish", "germany"]); |         $languages = new Collection(["English", "Polish", "German"]); | ||||||
|   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
|         $number = $this->faker->numberBetween(1, $languages->count()); |         $number = $this->faker->numberBetween(1, $languages->count()); | ||||||
|  |  | ||||||
|         return $languages->random($number) |         return $languages->random($number) | ||||||
|             ->map(fn(string $language): array => [ |             ->map(fn(string $language): array => [ | ||||||
|                 "language" => $language, |                 "name" => $language, | ||||||
|   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
|                 "level" => $this->faker->numberBetween(1, 6), |                 "level" => $this->faker->numberBetween(1, 6), | ||||||
|             ]) |             ]) | ||||||
|             ->all(); |             ->all(); | ||||||
| @@ -57,12 +57,12 @@ class ResumeFactory extends Factory | |||||||
|   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
|  |  | ||||||
|     protected function generateTechnologies(): array |     protected function generateTechnologies(): array | ||||||
|     { |     { | ||||||
|         $technologies = Technology::all(); |         $technologies = Technology::all()->pluck("name"); | ||||||
|   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
|         $number = $this->faker->numberBetween(2, $technologies->count()); |         $number = $this->faker->numberBetween(2, $technologies->count()); | ||||||
|  |  | ||||||
|         return $technologies->random($number) |         return $technologies->random($number) | ||||||
|             ->map(fn(string $technology): array => [ |             ->map(fn(string $technology): array => [ | ||||||
|                 "technology" => $technology, |                 "name" => $technology, | ||||||
|   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
|                 "level" => $this->faker->numberBetween(1, 5), |                 "level" => $this->faker->numberBetween(1, 5), | ||||||
|             ]) |             ]) | ||||||
|             ->all(); |             ->all(); | ||||||
| @@ -71,7 +71,7 @@ class ResumeFactory extends Factory | |||||||
|   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
|     protected function generateProjects(): array |     protected function generateProjects(): array | ||||||
|     { |     { | ||||||
|         $items = []; |         $items = []; | ||||||
|         $technologies = Technology::all(); |         $technologies = Technology::all()->pluck("name"); | ||||||
|   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
|  |  | ||||||
|         for ($i = 0; $i < $this->faker->numberBetween(1, 3); $i++) { |         for ($i = 0; $i < $this->faker->numberBetween(1, 3); $i++) { | ||||||
|             $number = $this->faker->numberBetween(2, $technologies->count()); |             $number = $this->faker->numberBetween(2, $technologies->count()); | ||||||
|   | |||||||
|   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
```   ```suggestion
            "name" => fn(array $attributes): bool => empty($attributes["user_id"]) ? $this->faker->name : null,
``` | |||||||
| @@ -1,34 +1,34 @@ | |||||||
| const technologyLevels = [ | const technologyLevels = [ | ||||||
|   { |   { | ||||||
|     level: 0, |     level: 1, | ||||||
|     name: 'Beginner', |     name: 'Beginner', | ||||||
|     activeColor: 'bg-rose-400', |     activeColor: 'bg-rose-400', | ||||||
|     backgroundColor: 'bg-rose-100', |     backgroundColor: 'bg-rose-100', | ||||||
|     textColor: 'text-rose-400', |     textColor: 'text-rose-400', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 1, |     level: 2, | ||||||
|     name: 'Junior', |     name: 'Junior', | ||||||
|     activeColor: 'bg-orange-400', |     activeColor: 'bg-orange-400', | ||||||
|     backgroundColor: 'bg-orange-100', |     backgroundColor: 'bg-orange-100', | ||||||
|     textColor: 'text-orange-400', |     textColor: 'text-orange-400', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 2, |     level: 3, | ||||||
|     name: 'Regular', |     name: 'Regular', | ||||||
|     activeColor: 'bg-amber-400', |     activeColor: 'bg-amber-400', | ||||||
|     backgroundColor: 'bg-amber-100', |     backgroundColor: 'bg-amber-100', | ||||||
|     textColor: 'text-yellow-500', |     textColor: 'text-yellow-500', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 3, |     level: 4, | ||||||
|     name: 'Advanced', |     name: 'Advanced', | ||||||
|     activeColor: 'bg-emerald-400', |     activeColor: 'bg-emerald-400', | ||||||
|     backgroundColor: 'bg-emerald-100', |     backgroundColor: 'bg-emerald-100', | ||||||
|     textColor: 'text-emerald-400', |     textColor: 'text-emerald-400', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 4, |     level: 5, | ||||||
|     name: 'Master', |     name: 'Master', | ||||||
|     activeColor: 'bg-blumilk-400', |     activeColor: 'bg-blumilk-400', | ||||||
|     backgroundColor: 'bg-blumilk-100', |     backgroundColor: 'bg-blumilk-100', | ||||||
| @@ -37,42 +37,42 @@ const technologyLevels = [ | |||||||
| ] | ] | ||||||
| const languageLevels = [ | const languageLevels = [ | ||||||
|   { |   { | ||||||
|     level: 0, |     level: 1, | ||||||
|     name: 'A1', |     name: 'A1', | ||||||
|     activeColor: 'bg-rose-400', |     activeColor: 'bg-rose-400', | ||||||
|     backgroundColor: 'bg-rose-100', |     backgroundColor: 'bg-rose-100', | ||||||
|     textColor: 'text-rose-400', |     textColor: 'text-rose-400', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 1, |     level: 2, | ||||||
|     name: 'A2', |     name: 'A2', | ||||||
|     activeColor: 'bg-orange-400', |     activeColor: 'bg-orange-400', | ||||||
|     backgroundColor: 'bg-orange-100', |     backgroundColor: 'bg-orange-100', | ||||||
|     textColor: 'text-orange-400', |     textColor: 'text-orange-400', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 2, |     level: 3, | ||||||
|     name: 'B1', |     name: 'B1', | ||||||
|     activeColor: 'bg-amber-400', |     activeColor: 'bg-amber-400', | ||||||
|     backgroundColor: 'bg-amber-100', |     backgroundColor: 'bg-amber-100', | ||||||
|     textColor: 'text-yellow-500', |     textColor: 'text-yellow-500', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 3, |     level: 4, | ||||||
|     name: 'B2', |     name: 'B2', | ||||||
|     activeColor: 'bg-emerald-400', |     activeColor: 'bg-emerald-400', | ||||||
|     backgroundColor: 'bg-emerald-100', |     backgroundColor: 'bg-emerald-100', | ||||||
|     textColor: 'text-emerald-400', |     textColor: 'text-emerald-400', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 4, |     level: 5, | ||||||
|     name: 'C1', |     name: 'C1', | ||||||
|     activeColor: 'bg-blumilk-400', |     activeColor: 'bg-blumilk-400', | ||||||
|     backgroundColor: 'bg-blumilk-100', |     backgroundColor: 'bg-blumilk-100', | ||||||
|     textColor: 'text-blumilk-400', |     textColor: 'text-blumilk-400', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     level: 5, |     level: 6, | ||||||
|     name: 'C2', |     name: 'C2', | ||||||
|     activeColor: 'bg-gray-600', |     activeColor: 'bg-gray-600', | ||||||
|     backgroundColor: 'bg-gray-200', |     backgroundColor: 'bg-gray-200', | ||||||
|   | |||||||
| @@ -138,10 +138,13 @@ | |||||||
|           @add-item="addEducation" |           @add-item="addEducation" | ||||||
|           @remove-item="(index) => form.educations.splice(index, 1)" |           @remove-item="(index) => form.educations.splice(index, 1)" | ||||||
|         > |         > | ||||||
|           <template #itemHeader="{ element }"> |           <template #itemHeader="{ element, index }"> | ||||||
|  |             <template v-if="hasAnyErrorInSection('education', index)"> | ||||||
|  |               <ExclamationCircleIcon class="h-6 w-6 mr-2 text-red-600 inline-block" /> | ||||||
|  |             </template> | ||||||
|             {{ element.school ? element.school : '(Nieokreślony)' }} |             {{ element.school ? element.school : '(Nieokreślony)' }} | ||||||
|           </template> |           </template> | ||||||
|           <template #form="{ element }"> |           <template #form="{ element, index }"> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
|               <label class="block text-sm font-medium text-gray-700 sm:mt-px"> |               <label class="block text-sm font-medium text-gray-700 sm:mt-px"> | ||||||
|                 Szkoła |                 Szkoła | ||||||
| @@ -151,8 +154,14 @@ | |||||||
|                   v-model="element.school" |                   v-model="element.school" | ||||||
|                   type="text" |                   type="text" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.school`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.school`] }" | ||||||
|                 > |                 > | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.school`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.school`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
| @@ -164,8 +173,14 @@ | |||||||
|                   v-model="element.degree" |                   v-model="element.degree" | ||||||
|                   type="text" |                   type="text" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.degree`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.degree`] }" | ||||||
|                 > |                 > | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.degree`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.degree`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
| @@ -177,8 +192,14 @@ | |||||||
|                   v-model="element.fieldOfStudy" |                   v-model="element.fieldOfStudy" | ||||||
|                   type="text" |                   type="text" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.fieldOfStudy`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.fieldOfStudy`] }" | ||||||
|                 > |                 > | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.fieldOfStudy`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.fieldOfStudy`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
| @@ -190,8 +211,14 @@ | |||||||
|                   v-model="element.startDate" |                   v-model="element.startDate" | ||||||
|                   placeholder="Wybierz datę" |                   placeholder="Wybierz datę" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.startDate`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.startDate`] }" | ||||||
|                 /> |                 /> | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.startDate`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.startDate`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
| @@ -203,8 +230,14 @@ | |||||||
|                   v-model="element.endDate" |                   v-model="element.endDate" | ||||||
|                   placeholder="Wybierz datę" |                   placeholder="Wybierz datę" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.endDate`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.endDate`] }" | ||||||
|                 /> |                 /> | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.endDate`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.endDate`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </template> |           </template> | ||||||
| @@ -216,7 +249,10 @@ | |||||||
|           @add-item="addLanguage" |           @add-item="addLanguage" | ||||||
|           @remove-item="(index) => form.languages.splice(index, 1)" |           @remove-item="(index) => form.languages.splice(index, 1)" | ||||||
|         > |         > | ||||||
|           <template #itemHeader="{ element }"> |           <template #itemHeader="{ element, index }"> | ||||||
|  |             <template v-if="hasAnyErrorInSection('languages', index)"> | ||||||
|  |               <ExclamationCircleIcon class="h-6 w-6 mr-2 text-red-600 inline-block" /> | ||||||
|  |             </template> | ||||||
|             <template v-if="element.name"> |             <template v-if="element.name"> | ||||||
|               {{ element.name }} - <span :class="element.level.textColor">{{ element.level.name }}</span> |               {{ element.name }} - <span :class="element.level.textColor">{{ element.level.name }}</span> | ||||||
|             </template> |             </template> | ||||||
| @@ -263,7 +299,10 @@ | |||||||
|           @add-item="addTechnology" |           @add-item="addTechnology" | ||||||
|           @remove-item="(index) => form.technologies.splice(index, 1)" |           @remove-item="(index) => form.technologies.splice(index, 1)" | ||||||
|         > |         > | ||||||
|           <template #itemHeader="{ element }"> |           <template #itemHeader="{ element, index }"> | ||||||
|  |             <template v-if="hasAnyErrorInSection('technologies', index)"> | ||||||
|  |               <ExclamationCircleIcon class="h-6 w-6 mr-2 text-red-600 inline-block" /> | ||||||
|  |             </template> | ||||||
|             <template v-if="element.name"> |             <template v-if="element.name"> | ||||||
|               {{ element.name }} - <span :class="element.level.textColor">{{ element.level.name }}</span> |               {{ element.name }} - <span :class="element.level.textColor">{{ element.level.name }}</span> | ||||||
|             </template> |             </template> | ||||||
| @@ -310,7 +349,10 @@ | |||||||
|           @add-item="addProject" |           @add-item="addProject" | ||||||
|           @remove-item="(index) => form.projects.splice(index, 1)" |           @remove-item="(index) => form.projects.splice(index, 1)" | ||||||
|         > |         > | ||||||
|           <template #itemHeader="{ element }"> |           <template #itemHeader="{ element, index }"> | ||||||
|  |             <template v-if="hasAnyErrorInSection('projects', index)"> | ||||||
|  |               <ExclamationCircleIcon class="h-6 w-6 mr-2 text-red-600 inline-block" /> | ||||||
|  |             </template> | ||||||
|             {{ element.description ? element.description : '(Nieokreślony)' }} |             {{ element.description ? element.description : '(Nieokreślony)' }} | ||||||
|           </template> |           </template> | ||||||
|           <template #form="{ element, index }"> |           <template #form="{ element, index }"> | ||||||
| @@ -413,13 +455,12 @@ | |||||||
|                 Zadania |                 Zadania | ||||||
|               </label> |               </label> | ||||||
|               <div class="mt-1 sm:mt-0"> |               <div class="mt-1 sm:mt-0"> | ||||||
|                 <input |                 <textarea | ||||||
|                   :id="`project-tasks-${index}`" |                   :id="`project-tasks-${index}`" | ||||||
|                   v-model="element.tasks" |                   v-model="element.tasks" | ||||||
|                   type="text" |  | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`projects.${index}.tasks`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`projects.${index}.tasks`] }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`projects.${index}.tasks`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`projects.${index}.tasks`] }" | ||||||
|                 > |                 /> | ||||||
|                 <p |                 <p | ||||||
|                   v-if="form.errors[`projects.${index}.tasks`]" |                   v-if="form.errors[`projects.${index}.tasks`]" | ||||||
|                   class="mt-2 text-sm text-red-600" |                   class="mt-2 text-sm text-red-600" | ||||||
| @@ -469,9 +510,9 @@ const props = defineProps({ | |||||||
| const { technologyLevels, languageLevels } = useLevels() | const { technologyLevels, languageLevels } = useLevels() | ||||||
|  |  | ||||||
| const languages = [ | const languages = [ | ||||||
|   'Język polski', |   'Polish', | ||||||
|   'Język angielski', |   'English', | ||||||
|   'Język niemiecki', |   'German', | ||||||
| ] | ] | ||||||
|  |  | ||||||
| const form = useForm({ | const form = useForm({ | ||||||
| @@ -517,6 +558,12 @@ function addLanguage() { | |||||||
|   }) |   }) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function hasAnyErrorInSection(section, index) { | ||||||
|  |   return Object | ||||||
|  |     .keys(form.errors) | ||||||
|  |     .some((error) => error.startsWith(`${section}.${index}.`)) | ||||||
|  | } | ||||||
|  |  | ||||||
| function submitResume() { | function submitResume() { | ||||||
|   form |   form | ||||||
|     .transform((data) => ({ |     .transform((data) => ({ | ||||||
|   | |||||||
| @@ -138,10 +138,13 @@ | |||||||
|           @add-item="addEducation" |           @add-item="addEducation" | ||||||
|           @remove-item="(index) => form.educations.splice(index, 1)" |           @remove-item="(index) => form.educations.splice(index, 1)" | ||||||
|         > |         > | ||||||
|           <template #itemHeader="{ element }"> |           <template #itemHeader="{ element, index }"> | ||||||
|  |             <template v-if="hasAnyErrorInSection('education', index)"> | ||||||
|  |               <ExclamationCircleIcon class="h-6 w-6 mr-2 text-red-600 inline-block" /> | ||||||
|  |             </template> | ||||||
|             {{ element.school ? element.school : '(Nieokreślony)' }} |             {{ element.school ? element.school : '(Nieokreślony)' }} | ||||||
|           </template> |           </template> | ||||||
|           <template #form="{ element }"> |           <template #form="{ element, index }"> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
|               <label class="block text-sm font-medium text-gray-700 sm:mt-px"> |               <label class="block text-sm font-medium text-gray-700 sm:mt-px"> | ||||||
|                 Szkoła |                 Szkoła | ||||||
| @@ -151,8 +154,14 @@ | |||||||
|                   v-model="element.school" |                   v-model="element.school" | ||||||
|                   type="text" |                   type="text" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.school`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.school`] }" | ||||||
|                 > |                 > | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.school`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.school`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
| @@ -164,8 +173,14 @@ | |||||||
|                   v-model="element.degree" |                   v-model="element.degree" | ||||||
|                   type="text" |                   type="text" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.degree`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.degree`] }" | ||||||
|                 > |                 > | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.degree`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.degree`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
| @@ -177,8 +192,14 @@ | |||||||
|                   v-model="element.fieldOfStudy" |                   v-model="element.fieldOfStudy" | ||||||
|                   type="text" |                   type="text" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.fieldOfStudy`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.fieldOfStudy`] }" | ||||||
|                 > |                 > | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.fieldOfStudy`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.fieldOfStudy`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
| @@ -190,8 +211,14 @@ | |||||||
|                   v-model="element.startDate" |                   v-model="element.startDate" | ||||||
|                   placeholder="Wybierz datę" |                   placeholder="Wybierz datę" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.startDate`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.startDate`] }" | ||||||
|                 /> |                 /> | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.startDate`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.startDate`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="items-center py-4 sm:grid sm:grid-cols-2"> |             <div class="items-center py-4 sm:grid sm:grid-cols-2"> | ||||||
| @@ -203,8 +230,14 @@ | |||||||
|                   v-model="element.endDate" |                   v-model="element.endDate" | ||||||
|                   placeholder="Wybierz datę" |                   placeholder="Wybierz datę" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': false, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': true }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`education.${index}.endDate`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`education.${index}.endDate`] }" | ||||||
|                 /> |                 /> | ||||||
|  |                 <p | ||||||
|  |                   v-if="form.errors[`education.${index}.endDate`]" | ||||||
|  |                   class="mt-2 text-sm text-red-600" | ||||||
|  |                 > | ||||||
|  |                   {{ form.errors[`education.${index}.endDate`] }} | ||||||
|  |                 </p> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|           </template> |           </template> | ||||||
| @@ -216,7 +249,10 @@ | |||||||
|           @add-item="addLanguage" |           @add-item="addLanguage" | ||||||
|           @remove-item="(index) => form.languages.splice(index, 1)" |           @remove-item="(index) => form.languages.splice(index, 1)" | ||||||
|         > |         > | ||||||
|           <template #itemHeader="{ element }"> |           <template #itemHeader="{ element, index }"> | ||||||
|  |             <template v-if="hasAnyErrorInSection('languages', index)"> | ||||||
|  |               <ExclamationCircleIcon class="h-6 w-6 mr-2 text-red-600 inline-block" /> | ||||||
|  |             </template> | ||||||
|             <template v-if="element.name"> |             <template v-if="element.name"> | ||||||
|               {{ element.name }} - <span :class="element.level.textColor">{{ element.level.name }}</span> |               {{ element.name }} - <span :class="element.level.textColor">{{ element.level.name }}</span> | ||||||
|             </template> |             </template> | ||||||
| @@ -269,7 +305,10 @@ | |||||||
|           @add-item="addTechnology" |           @add-item="addTechnology" | ||||||
|           @remove-item="(index) => form.technologies.splice(index, 1)" |           @remove-item="(index) => form.technologies.splice(index, 1)" | ||||||
|         > |         > | ||||||
|           <template #itemHeader="{ element }"> |           <template #itemHeader="{ element, index }"> | ||||||
|  |             <template v-if="hasAnyErrorInSection('technologies', index)"> | ||||||
|  |               <ExclamationCircleIcon class="h-6 w-6 mr-2 text-red-600 inline-block" /> | ||||||
|  |             </template> | ||||||
|             <template v-if="element.name"> |             <template v-if="element.name"> | ||||||
|               {{ element.name }} - <span :class="element.level.textColor">{{ element.level.name }}</span> |               {{ element.name }} - <span :class="element.level.textColor">{{ element.level.name }}</span> | ||||||
|             </template> |             </template> | ||||||
| @@ -322,7 +361,10 @@ | |||||||
|           @add-item="addProject" |           @add-item="addProject" | ||||||
|           @remove-item="(index) => form.projects.splice(index, 1)" |           @remove-item="(index) => form.projects.splice(index, 1)" | ||||||
|         > |         > | ||||||
|           <template #itemHeader="{ element }"> |           <template #itemHeader="{ element, index }"> | ||||||
|  |             <template v-if="hasAnyErrorInSection('projects', index)"> | ||||||
|  |               <ExclamationCircleIcon class="h-6 w-6 mr-2 text-red-600 inline-block" /> | ||||||
|  |             </template> | ||||||
|             {{ element.description ? element.description : '(Nieokreślony)' }} |             {{ element.description ? element.description : '(Nieokreślony)' }} | ||||||
|           </template> |           </template> | ||||||
|           <template #form="{ element, index }"> |           <template #form="{ element, index }"> | ||||||
| @@ -425,13 +467,13 @@ | |||||||
|                 Zadania |                 Zadania | ||||||
|               </label> |               </label> | ||||||
|               <div class="mt-1 sm:mt-0"> |               <div class="mt-1 sm:mt-0"> | ||||||
|                 <input |                 <textarea | ||||||
|                   :id="`project-tasks-${index}`" |                   :id="`project-tasks-${index}`" | ||||||
|                   v-model="element.tasks" |                   v-model="element.tasks" | ||||||
|                   type="text" |                   rows="3" | ||||||
|                   class="block w-full rounded-md shadow-sm sm:text-sm" |                   class="block w-full rounded-md shadow-sm sm:text-sm" | ||||||
|                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`projects.${index}.tasks`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`projects.${index}.tasks`] }" |                   :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`projects.${index}.tasks`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`projects.${index}.tasks`] }" | ||||||
|                 > |                 /> | ||||||
|                 <p |                 <p | ||||||
|                   v-if="form.errors[`projects.${index}.tasks`]" |                   v-if="form.errors[`projects.${index}.tasks`]" | ||||||
|                   class="mt-2 text-sm text-red-600" |                   class="mt-2 text-sm text-red-600" | ||||||
| @@ -466,11 +508,13 @@ | |||||||
| <script setup> | <script setup> | ||||||
| import { Listbox, ListboxOption, ListboxOptions, ListboxLabel, ListboxButton } from '@headlessui/vue' | import { Listbox, ListboxOption, ListboxOptions, ListboxLabel, ListboxButton } from '@headlessui/vue' | ||||||
| import { SelectorIcon, CheckIcon } from '@heroicons/vue/outline' | import { SelectorIcon, CheckIcon } from '@heroicons/vue/outline' | ||||||
|  | import { ExclamationCircleIcon } from '@heroicons/vue/solid' | ||||||
| import { useForm } from '@inertiajs/inertia-vue3' | import { useForm } from '@inertiajs/inertia-vue3' | ||||||
| import FlatPickr from 'vue-flatpickr-component' | import FlatPickr from 'vue-flatpickr-component' | ||||||
| import DynamicSection from '@/Shared/Forms/DynamicSection' | import DynamicSection from '@/Shared/Forms/DynamicSection' | ||||||
| import Combobox from '@/Shared/Forms/Combobox' | import Combobox from '@/Shared/Forms/Combobox' | ||||||
| import LevelPicker from '@/Shared/Forms/LevelPicker' | import LevelPicker from '@/Shared/Forms/LevelPicker' | ||||||
|  | import useLevels from '@/Composables/useLevels' | ||||||
|  |  | ||||||
| const props = defineProps({ | const props = defineProps({ | ||||||
|   users: Object, |   users: Object, | ||||||
| @@ -478,106 +522,25 @@ const props = defineProps({ | |||||||
|   resume: Object, |   resume: Object, | ||||||
| }) | }) | ||||||
|  |  | ||||||
| const technologyLevels = [ | const { technologyLevels, languageLevels } = useLevels() | ||||||
|   { |  | ||||||
|     level: 1, |  | ||||||
|     name: 'Poczatkujący', |  | ||||||
|     activeColor: 'bg-rose-400', |  | ||||||
|     backgroundColor: 'bg-rose-100', |  | ||||||
|     textColor: 'text-rose-400', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 2, |  | ||||||
|     name: 'Zaawansowany', |  | ||||||
|     activeColor: 'bg-orange-400', |  | ||||||
|     backgroundColor: 'bg-orange-100', |  | ||||||
|     textColor: 'text-orange-400', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 3, |  | ||||||
|     name: 'Doświadczony', |  | ||||||
|     activeColor: 'bg-amber-400', |  | ||||||
|     backgroundColor: 'bg-amber-100', |  | ||||||
|     textColor: 'text-yellow-500', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 4, |  | ||||||
|     name: 'Ekspert', |  | ||||||
|     activeColor: 'bg-emerald-400', |  | ||||||
|     backgroundColor: 'bg-emerald-100', |  | ||||||
|     textColor: 'text-emerald-400', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 5, |  | ||||||
|     name: 'Chad', |  | ||||||
|     activeColor: 'bg-blumilk-400', |  | ||||||
|     backgroundColor: 'bg-blumilk-100', |  | ||||||
|     textColor: 'text-blumilk-400', |  | ||||||
|   }, |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| const languageLevels = [ |  | ||||||
|   { |  | ||||||
|     level: 1, |  | ||||||
|     name: 'A1', |  | ||||||
|     activeColor: 'bg-rose-400', |  | ||||||
|     backgroundColor: 'bg-rose-100', |  | ||||||
|     textColor: 'text-rose-400', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 2, |  | ||||||
|     name: 'A2', |  | ||||||
|     activeColor: 'bg-orange-400', |  | ||||||
|     backgroundColor: 'bg-orange-100', |  | ||||||
|     textColor: 'text-orange-400', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 3, |  | ||||||
|     name: 'B1', |  | ||||||
|     activeColor: 'bg-amber-400', |  | ||||||
|     backgroundColor: 'bg-amber-100', |  | ||||||
|     textColor: 'text-yellow-500', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 4, |  | ||||||
|     name: 'B2', |  | ||||||
|     activeColor: 'bg-emerald-400', |  | ||||||
|     backgroundColor: 'bg-emerald-100', |  | ||||||
|     textColor: 'text-emerald-400', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 5, |  | ||||||
|     name: 'C1', |  | ||||||
|     activeColor: 'bg-blumilk-400', |  | ||||||
|     backgroundColor: 'bg-blumilk-100', |  | ||||||
|     textColor: 'text-blumilk-400', |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     level: 6, |  | ||||||
|     name: 'C2', |  | ||||||
|     activeColor: 'bg-blumilk-600', |  | ||||||
|     backgroundColor: 'bg-blumilk-200', |  | ||||||
|     textColor: 'text-blumilk-600', |  | ||||||
|   }, |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| const languages = [ | const languages = [ | ||||||
|   'Język polski', |   'Polish', | ||||||
|   'Język angielski', |   'English', | ||||||
|   'Język niemiecki', |   'German', | ||||||
| ] | ] | ||||||
|  |  | ||||||
| const form = useForm({ | const form = useForm({ | ||||||
|   user: props.users.data.find((user) => user.id === props.resume.user), |   user: props.users.data.find((user) => user.id === props.resume.user) ?? null, | ||||||
|   name: props.resume.name, |   name: props.resume.name ?? null , | ||||||
|   educations: props.resume.educations ?? [], |   educations: props.resume.education ?? [], | ||||||
|   projects: props.resume.projects ?? [], |   projects: props.resume.projects ?? [], | ||||||
|   technologies: props.resume.technologies.map((technology) => ({ |   technologies: props.resume.technologies.map((technology) => ({ | ||||||
|     name: props.technologies.find((tech) => tech === technology.name), |     name: props.technologies.find((tech) => tech === technology.name), | ||||||
|     level: technologyLevels.find((level) => level.level === technology.level), |     level: technologyLevels.find((level) => level.level === technology.level), | ||||||
|   })) ?? [], |   })) ?? [], | ||||||
|   languages: props.resume.languages.map((language) => ({ |   languages: props.resume.languages.map((language) => ({ | ||||||
|     name: languages.find((lang) => lang.name === language.name), |     name: languages.find((lang) => lang === language.name), | ||||||
|     level: languageLevels.find((level) => level.level === language.level), |     level: languageLevels.find((level) => level.level === language.level), | ||||||
|   })) ?? [], |   })) ?? [], | ||||||
| }) | }) | ||||||
| @@ -616,6 +579,12 @@ function addLanguage() { | |||||||
|   }) |   }) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function hasAnyErrorInSection(section, index) { | ||||||
|  |   return Object | ||||||
|  |     .keys(form.errors) | ||||||
|  |     .some((error) => error.startsWith(`${section}.${index}.`)) | ||||||
|  | } | ||||||
|  |  | ||||||
| function submitResume() { | function submitResume() { | ||||||
|   form |   form | ||||||
|     .transform((data) => ({ |     .transform((data) => ({ | ||||||
|   | |||||||
							
								
								
									
										76
									
								
								resources/js/Shared/Forms/MultipleCombobox.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								resources/js/Shared/Forms/MultipleCombobox.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | <template> | ||||||
|  |   <Combobox | ||||||
|  |     as="div" | ||||||
|  |     nullable | ||||||
|  |     multiple | ||||||
|  |   > | ||||||
|  |     <ComboboxLabel class="block text-sm font-medium text-gray-700"> | ||||||
|  |       {{ label }} | ||||||
|  |     </ComboboxLabel> | ||||||
|  |     <div class="relative mt-2"> | ||||||
|  |       <ComboboxInput | ||||||
|  |         as="template" | ||||||
|  |         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" | ||||||
|  |         :display-value="(item) => item" | ||||||
|  |         @change="query = $event.target.value" | ||||||
|  |       > | ||||||
|  |         <span>aee</span> | ||||||
|  |       </ComboboxInput> | ||||||
|  |       <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.name }} | ||||||
|  |             </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, | ||||||
|  |   ComboboxLabel, | ||||||
|  |   ComboboxOption, | ||||||
|  |   ComboboxOptions, | ||||||
|  | } from '@headlessui/vue' | ||||||
|  |  | ||||||
|  | const props = defineProps({ | ||||||
|  |   label: null, | ||||||
|  |   items: Array, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | const query = ref('') | ||||||
|  |  | ||||||
|  | const filteredItems = computed(() => | ||||||
|  |   query.value === '' | ||||||
|  |     ? props.items | ||||||
|  |     : props.items.filter((item) => item.name.toLowerCase().includes(query.value.toLowerCase())), | ||||||
|  | ) | ||||||
|  | </script> | ||||||
		Reference in New Issue
	
	Block a user