Skip to content

Commit d3b3a4f

Browse files
committed
UP
1 parent 4da63d3 commit d3b3a4f

File tree

6 files changed

+74
-181
lines changed

6 files changed

+74
-181
lines changed

resources/views/livewire/board.blade.php

Lines changed: 9 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -34,87 +34,12 @@ class="absolute inset-0 bg-white/40 dark:bg-gray-900/40 z-10 backdrop-blur-sm fl
3434
<div class="flex-1 overflow-hidden">
3535
<div class="flex flex-row h-full overflow-x-auto overflow-y-hidden py-4 px-2 gap-5 kanban-board pb-4">
3636
@foreach($columns as $columnId => $column)
37-
<div class="kanban-column w-[300px] min-w-[300px] flex-shrink-0 bg-kanban-column-bg dark:bg-kanban-column-bg border border-kanban-column-border dark:border-gray-700 shadow-kanban-column dark:shadow-md rounded-xl flex flex-col max-h-full overflow-hidden">
38-
<!-- Column Header -->
39-
<div class="kanban-column-header flex items-center justify-between py-3 px-4 border-b border-gray-200 dark:border-gray-700">
40-
<div class="flex items-center">
41-
<h3 class="text-sm font-medium text-kanban-column-header dark:text-kanban-column-header">
42-
{{ $column['name'] }}
43-
</h3>
44-
<div class="ml-2 px-2.5 py-0.5 rounded-full text-xs font-medium kanban-status-{{ str_replace('_', '-', $columnId) }}">
45-
{{ $column['total'] ?? count($column['items']) }}
46-
</div>
47-
</div>
48-
<button
49-
type="button"
50-
wire:click="openCreateForm('{{ $columnId }}')"
51-
x-on:click="$dispatch('open-modal', { id: 'create-card-modal' })"
52-
class="text-gray-400 hover:text-primary-500 dark:text-gray-500 dark:hover:text-primary-400"
53-
>
54-
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
55-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
56-
</svg>
57-
</button>
58-
</div>
59-
60-
<!-- Column Content -->
61-
<div
62-
x-sortable
63-
x-sortable-group="cards"
64-
data-column-id="{{ $columnId }}"
65-
@end.stop="$wire.updateColumnCards($event.to.getAttribute('data-column-id'), $event.to.sortable.toArray())"
66-
class="p-3 flex-1 overflow-y-auto overflow-x-hidden"
67-
style="max-height: calc(100vh - 13rem);"
68-
>
69-
@if (count($column['items']) > 0)
70-
@foreach ($column['items'] as $card)
71-
<div
72-
class="kanban-card mb-3 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden cursor-pointer transition-all duration-150 hover:shadow-md"
73-
x-sortable-item="{{ $card['id'] }}"
74-
wire:click="openEditForm('{{ $card['id'] }}', '{{ $columnId }}')"
75-
x-on:click="$dispatch('open-modal', { id: 'edit-card-modal' })"
76-
>
77-
<div class="p-3">
78-
<h4 class="text-sm font-medium text-gray-900 dark:text-white">{{ $card['title'] }}</h4>
79-
80-
@if(isset($card['description']) && !empty($card['description']))
81-
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400 line-clamp-2">{{ $card['description'] }}</p>
82-
@endif
83-
84-
@if(!empty($config['cardAttributes']))
85-
<div class="mt-2 flex flex-wrap gap-2">
86-
@foreach($config['cardAttributes'] as $attribute => $label)
87-
@if(isset($card[$attribute]) && !empty($card[$attribute]))
88-
<div class="inline-flex items-center px-2 py-1 rounded-full text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300">
89-
<span class="font-medium mr-1">{{ $label }}:</span>
90-
<span>{{ $card[$attribute] }}</span>
91-
</div>
92-
@endif
93-
@endforeach
94-
</div>
95-
@endif
96-
</div>
97-
</div>
98-
@endforeach
99-
100-
@if($column['total'] > count($column['items']))
101-
<button
102-
wire:click="loadMoreItems('{{ $columnId }}')"
103-
class="w-full py-2 text-xs text-center text-primary-600 dark:text-primary-400 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-150 rounded"
104-
>
105-
{{ __('Load more') }} ({{ count($column['items']) }} / {{ $column['total'] }})
106-
</button>
107-
@endif
108-
@else
109-
<div class="kanban-empty-column h-24 border-2 border-dashed border-gray-200 dark:border-gray-700 rounded-lg flex flex-col items-center justify-center text-gray-400 dark:text-gray-500 text-sm">
110-
<svg class="w-5 h-5 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
111-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
112-
</svg>
113-
<span>No items</span>
114-
</div>
115-
@endif
116-
</div>
117-
</div>
37+
<x-flowforge::column
38+
:columnId="$columnId"
39+
:column="$column"
40+
:config="$config"
41+
wire:key="column-{{ $columnId }}"
42+
/>
11843
@endforeach
11944
</div>
12045
</div>
@@ -123,9 +48,9 @@ class="w-full py-2 text-xs text-center text-primary-600 dark:text-primary-400 ho
12348
<x-filament::modal.description>
12449
{{ __('Add a new :recordLabel to the board', ['recordLabel' => strtolower($config['recordLabel'] ?? 'card')]) }}
12550
</x-filament::modal.description>
126-
51+
12752
{{ $this->createForm }}
128-
53+
12954
<x-slot name="footer">
13055
<div class="flex justify-end gap-x-3">
13156
<x-filament::button
@@ -146,7 +71,7 @@ class="w-full py-2 text-xs text-center text-primary-600 dark:text-primary-400 ho
14671

14772
<x-filament::modal id="edit-card-modal" :heading="__('Edit :recordLabel', ['recordLabel' => $config['recordLabel'] ?? 'Card'])">
14873
{{ $this->editForm }}
149-
74+
15075
<x-slot name="footer">
15176
<div class="flex items-center justify-between">
15277
<x-filament::button
Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,7 @@
11
@props(['label' => null, 'value', 'color' => 'gray', 'icon' => null])
22

3-
<div @class([
4-
"kanban-card-badge",
5-
"bg-{$color}-100 text-{$color}-700 dark:bg-{$color}-900/40 dark:text-{$color}-400" => $color !== 'gray',
6-
"bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300" => $color === 'gray',
7-
])>
8-
@if($icon)
9-
<svg class="inline-block w-3 h-3 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
10-
{!! $icon !!}
11-
</svg>
12-
@endif
13-
14-
@if($label)
15-
<span class="font-medium text-primary-600 dark:text-primary-400 mr-1">{{ $label }}:</span>
16-
@endif
17-
3+
<div
4+
class="inline-flex items-center px-2 py-1 rounded-full text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300">
5+
<span class="font-medium mr-1">{{ $label }}:</span>
186
<span>{{ $value }}</span>
197
</div>

resources/views/livewire/card.blade.php

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,31 @@
11
@props(['config', 'columnId', 'card'])
22

33
<div
4+
class="kanban-card mb-3 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden cursor-pointer transition-all duration-150 hover:shadow-md"
45
x-sortable-handle
56
x-sortable-item="{{ $card['id'] }}"
6-
x-on:click.stop="openEditModal({{ json_encode($card) }}, '{{ $columnId }}')"
7-
class="group relative overflow-hidden bg-kanban-card-bg hover:bg-kanban-card-hover dark:bg-kanban-card-bg dark:hover:bg-kanban-card-hover rounded-lg border border-kanban-card-border dark:border-gray-700 shadow-kanban-card hover:shadow-kanban-card-hover mb-3 p-4 transition-kanban kanban-card animate-kanban-card-add {{ isset($card['priority']) ? 'priority-' . strtolower($card['priority']) : '' }}"
7+
wire:click="openEditForm('{{ $card['id'] }}', '{{ $columnId }}')"
8+
x-on:click="$dispatch('open-modal', { id: 'edit-card-modal' })"
89
>
9-
<!-- Priority Indicator (5px vertical bar) -->
10-
@if(isset($card['priority']))
11-
<div class="absolute left-0 top-0 bottom-0 w-1.5 @if($card['priority'] == 'high') bg-kanban-priority-high @elseif($card['priority'] == 'medium') bg-kanban-priority-medium @else bg-kanban-priority-low @endif"></div>
12-
@endif
10+
<div class="p-3">
11+
<h4 class="text-sm font-medium text-gray-900 dark:text-white">{{ $card['title'] }}</h4>
1312

14-
<!-- Card Header -->
15-
<div class="flex items-start justify-between mb-2">
16-
<h4 class="text-sm font-semibold text-gray-900 dark:text-white line-clamp-2 pr-6">{{ $card['title'] }}</h4>
17-
<div class="flex items-center kanban-drag-handle ml-1 mt-0.5">
18-
<svg class="w-4 h-4 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-400 cursor-grab" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
19-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"></path>
20-
</svg>
21-
</div>
22-
</div>
23-
24-
<!-- Card Description -->
25-
@if(isset($card['description']) && $card['description'])
26-
<div class="text-xs text-gray-600 dark:text-gray-400 line-clamp-2 mb-3 pl-0.5">
27-
{{ $card['description'] }}
28-
</div>
29-
@endif
13+
@if(isset($card['description']) && !empty($card['description']))
14+
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400 line-clamp-2">{{ $card['description'] }}</p>
15+
@endif
3016

31-
<!-- Card Attributes -->
32-
<div class="flex flex-wrap gap-1.5 mt-2.5">
33-
@foreach($config['cardAttributes'] as $attribute => $label)
34-
@if(isset($card[$attribute]) && $card[$attribute])
35-
<div class="kanban-card-badge bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 flex items-center">
36-
@if($attribute == 'due_date')
37-
<svg class="w-3 h-3 mr-1 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
38-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
39-
</svg>
40-
@elseif($attribute == 'priority')
41-
<svg class="w-3 h-3 mr-1 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
42-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"></path>
43-
</svg>
17+
@if(!empty($config['cardAttributes']))
18+
<div class="mt-2 flex flex-wrap gap-2">
19+
@foreach($config['cardAttributes'] as $attribute => $label)
20+
@if(isset($card[$attribute]) && !empty($card[$attribute]))
21+
<x-flowforge::card-badge
22+
:label="$label"
23+
:value="$card[$attribute]"
24+
:color="$config['cardAttributeColors'][$attribute] ?? 'gray'"
25+
:icon="$config['cardAttributeIcons'][$attribute] ?? null"
26+
/>
4427
@endif
45-
<span class="whitespace-nowrap overflow-hidden text-ellipsis">{{ $card[$attribute] }}</span>
46-
</div>
47-
@endif
48-
@endforeach
49-
50-
<!-- Optional Indicators -->
51-
@if(isset($card['assignee']))
52-
<div class="kanban-card-badge bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-400 flex items-center">
53-
<svg class="w-3 h-3 mr-1 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
54-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
55-
</svg>
56-
<span class="whitespace-nowrap overflow-hidden text-ellipsis">{{ $card['assignee'] }}</span>
28+
@endforeach
5729
</div>
5830
@endif
5931
</div>
Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
@props(['columnId', 'column', 'config'])
22

3-
<div class="kanban-column w-[300px] min-w-[300px] flex-shrink-0 bg-kanban-column-bg dark:bg-kanban-column-bg border border-kanban-column-border dark:border-gray-700 shadow-kanban-column dark:shadow-md rounded-xl flex flex-col max-h-full overflow-hidden">
3+
<div
4+
class="kanban-column w-[300px] min-w-[300px] flex-shrink-0 bg-kanban-column-bg dark:bg-kanban-column-bg border border-kanban-column-border dark:border-gray-700 shadow-kanban-column dark:shadow-md rounded-xl flex flex-col max-h-full overflow-hidden">
45
<!-- Column Header -->
5-
<div class="kanban-column-header flex items-center justify-between py-3 px-4 border-b border-gray-200 dark:border-gray-700">
6+
<div
7+
class="kanban-column-header flex items-center justify-between py-3 px-4 border-b border-gray-200 dark:border-gray-700">
68
<div class="flex items-center">
79
<h3 class="text-sm font-medium text-kanban-column-header dark:text-kanban-column-header">
810
{{ $column['name'] }}
911
</h3>
10-
<div class="ml-2 px-2.5 py-0.5 rounded-full text-xs font-medium kanban-status-{{ str_replace('_', '-', $columnId) }}">
11-
{{ count($column['items']) }}
12+
<div
13+
class="ml-2 px-2.5 py-0.5 rounded-full text-xs font-medium kanban-status-{{ str_replace('_', '-', $columnId) }}">
14+
{{ $column['total'] ?? count($column['items']) }}
1215
</div>
1316
</div>
1417
<button
1518
type="button"
16-
@click="openCreateModal('{{ $columnId }}')"
19+
wire:click="openCreateForm('{{ $columnId }}')"
20+
x-on:click="$dispatch('open-modal', { id: 'create-card-modal' })"
1721
class="text-gray-400 hover:text-primary-500 dark:text-gray-500 dark:hover:text-primary-400"
1822
>
19-
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
20-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
23+
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"
24+
xmlns="http://www.w3.org/2000/svg">
25+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
26+
d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
2127
</svg>
2228
</button>
2329
</div>
@@ -33,19 +39,26 @@ class="p-3 flex-1 overflow-y-auto overflow-x-hidden"
3339
>
3440
@if (count($column['items']) > 0)
3541
@foreach ($column['items'] as $card)
36-
<x-flowforge::kanban.card
42+
<x-flowforge::card
43+
:card="$card"
3744
:config="$config"
3845
:columnId="$columnId"
39-
:card="$card"
46+
wire:key="card-{{ $card['id'] }}"
4047
/>
4148
@endforeach
49+
50+
@if($column['total'] > count($column['items']))
51+
<button
52+
wire:click="loadMoreItems('{{ $columnId }}')"
53+
class="w-full py-2 text-xs text-center text-primary-600 dark:text-primary-400 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-150 rounded"
54+
>
55+
{{ __('Load more') }} ({{ count($column['items']) }} / {{ $column['total'] }})
56+
</button>
57+
@endif
4258
@else
43-
<div class="kanban-empty-column h-24 border-2 border-dashed border-gray-200 dark:border-gray-700 rounded-lg flex flex-col items-center justify-center text-gray-400 dark:text-gray-500 text-sm">
44-
<svg class="w-5 h-5 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
45-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
46-
</svg>
47-
<span>No items</span>
48-
</div>
59+
<x-flowforge::empty-column
60+
:columnId="$columnId"
61+
/>
4962
@endif
5063
</div>
5164
</div>
Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
@props(['columnId'])
22

3-
<div class="kanban-empty-column h-24 border-2 border-dashed border-gray-200 dark:border-gray-700 rounded-lg flex flex-col items-center justify-center px-4 py-5 text-center">
4-
<div class="flex justify-center items-center">
5-
<svg class="w-6 h-6 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
6-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
7-
</svg>
8-
</div>
9-
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">No items in this column</p>
10-
<button
11-
type="button"
12-
@click="openCreateModal('{{ $columnId }}')"
13-
class="mt-2 inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded text-primary-700 bg-primary-100 hover:bg-primary-200 dark:text-primary-300 dark:bg-primary-900/30 dark:hover:bg-primary-800/40 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors"
14-
>
15-
Add Card
16-
</button>
3+
<div
4+
class="kanban-empty-column h-24 border-2 border-dashed border-gray-200 dark:border-gray-700 rounded-lg flex flex-col items-center justify-center text-gray-400 dark:text-gray-500 text-sm">
5+
<svg class="w-5 h-5 mb-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"
6+
xmlns="http://www.w3.org/2000/svg">
7+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
8+
d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
9+
</svg>
10+
<span>No items</span>
1711
</div>

0 commit comments

Comments
 (0)