mirror of https://github.com/Devoalda/LaDo.git
perf(Project Loading):
Added Lazy load for project Restructured some files
This commit is contained in:
parent
59ffb4bc32
commit
99d37aafb6
|
@ -44,7 +44,7 @@ class DashboardController extends Controller
|
|||
|
||||
$todo_completed_count = $this->all_completed_todos()['completed_count'];
|
||||
|
||||
return view('dashboard', compact(
|
||||
return view('dashboard.index', compact(
|
||||
'todos',
|
||||
'incomplete_count',
|
||||
'project_count',
|
||||
|
|
|
@ -8,9 +8,12 @@ use App\Models\Project;
|
|||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
|
||||
|
||||
class ProjectController extends Controller
|
||||
|
@ -18,15 +21,23 @@ class ProjectController extends Controller
|
|||
/**
|
||||
* Display Listing of all Projects.
|
||||
*/
|
||||
public function index(): Application|Factory|View
|
||||
public function index(Request $request): Application|Factory|View|JsonResponse
|
||||
{
|
||||
$user = User::find(auth()->user()->id);
|
||||
$projects = $user->projects;
|
||||
$projects = $user->projects()->paginate(4);
|
||||
// Aggregate all todos for all projects
|
||||
$todos = $projects->map(function ($project) {
|
||||
return $project->todos;
|
||||
})->flatten();
|
||||
|
||||
if ($request->ajax()){
|
||||
$view = view('project.load-projects', compact('projects'))->render();
|
||||
return Response::json([
|
||||
'view' => $view,
|
||||
'nextPageUrl' => $projects->nextPageUrl(),
|
||||
]);
|
||||
}
|
||||
|
||||
return view('project.index', [
|
||||
'projects' => $projects,
|
||||
'todos' => $todos->whereNull('completed_at')->values(),
|
||||
|
|
|
@ -12,6 +12,14 @@ use App\Models\{
|
|||
|
||||
class Pomos extends Component
|
||||
{
|
||||
public $perPage = 10;
|
||||
|
||||
public function loadMore()
|
||||
{
|
||||
$this->perPage += 10;
|
||||
}
|
||||
|
||||
|
||||
public function render()
|
||||
{
|
||||
$user = User::find(auth()->id());
|
||||
|
|
|
@ -105,16 +105,16 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<livewire:dashboard.pomo-count />
|
||||
<livewire:dashboard.pomo-count/>
|
||||
|
||||
<livewire:dashboard.pomo-time />
|
||||
<livewire:dashboard.pomo-time/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- List out Todos and their details (time left/ago) + checkbox in form to toggle completed -->
|
||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 bg-white dark:bg-gray-800 shadow-sm rounded-lg p-6 mt-4">
|
||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 bg-white dark:bg-gray-800 shadow-sm rounded-lg p-6 mt-4 py-3">
|
||||
<h2 class="text-2xl font-semibold mb-4 text-green-500 dark:text-green-400">
|
||||
Today's Todos
|
||||
({{ $incomplete_count }})
|
||||
|
@ -122,12 +122,11 @@
|
|||
<div class="space-y-4" id="todo-container">
|
||||
@include('dashboard.load-todo')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pagination with CSS -->
|
||||
<div class="invisible">
|
||||
{{ $todos->links() }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
@ -136,12 +135,12 @@
|
|||
$(window).scroll(function () {
|
||||
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
|
||||
if (nextPageUrl) {
|
||||
loadMorePosts();
|
||||
loadMoreTodos();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function loadMorePosts() {
|
||||
function loadMoreTodos() {
|
||||
$.ajax({
|
||||
url: nextPageUrl,
|
||||
type: 'get',
|
||||
|
@ -157,7 +156,7 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</x-app-layout>
|
|
@ -1,6 +1,6 @@
|
|||
<div class="bg-white dark:bg-gray-800 shadow-sm rounded-lg p-6">
|
||||
<h3 class="text-xl font-semibold mb-4 text-blue-500 dark:text-blue-400">
|
||||
<!-- SVG for Pomo Average Cound -->
|
||||
<!-- SVG for Pomo Average Count -->
|
||||
<svg class="inline-block h-6 w-6 text-blue-500 dark:text-blue-400"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
@foreach ($pomos as $pomo)
|
||||
<tr class="hover:bg-blue-100 dark:hover:bg-gray-700">
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
<a href="{{ route('project.todo.edit', ['project' => $pomo->todo->project->id, 'todo' => $pomo->todo->id]) }}">
|
||||
{{ $pomo->todo->title }}
|
||||
</a>
|
||||
</td>
|
||||
<!-- Pomo Start and Pomo End -->
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
{{ \Carbon\Carbon::createFromTimestamp($pomo->pomo_start)->format('Y-m-d H:i:s') }}
|
||||
</td>
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
{{ \Carbon\Carbon::createFromTimestamp($pomo->pomo_end)->format('Y-m-d H:i:s') }}
|
||||
</td>
|
||||
<!-- Duration -->
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
{{
|
||||
\Carbon\Carbon::createFromTimestamp($pomo->pomo_start)->diffInMinutes(\Carbon\Carbon::createFromTimestamp($pomo->pomo_end))
|
||||
}}
|
||||
</td>
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
<!-- Truncate notes to 32 characters -->
|
||||
<div class="max-w-sm truncate">
|
||||
{{ $pomo->notes }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
<!-- Edit and Delete form button groups -->
|
||||
<div class="flex flex-row">
|
||||
<div class="flex flex-col">
|
||||
<a href="{{ route('pomo.edit', $pomo->id) }}"
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Edit</a>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<form action="{{ route('pomo.destroy', $pomo->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit"
|
||||
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">Delete
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
|
@ -10,53 +10,8 @@
|
|||
<th class="px-4 py-2">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($pomos as $pomo)
|
||||
<tr class="hover:bg-blue-100 dark:hover:bg-gray-700">
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
<a href="{{ route('project.todo.edit', ['project' => $pomo->todo->project->id, 'todo' => $pomo->todo->id]) }}">
|
||||
{{ $pomo->todo->title }}
|
||||
</a>
|
||||
</td>
|
||||
<!-- Pomo Start and Pomo End -->
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
{{ \Carbon\Carbon::createFromTimestamp($pomo->pomo_start)->format('Y-m-d H:i:s') }}
|
||||
</td>
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
{{ \Carbon\Carbon::createFromTimestamp($pomo->pomo_end)->format('Y-m-d H:i:s') }}
|
||||
</td>
|
||||
<!-- Duration -->
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
{{
|
||||
\Carbon\Carbon::createFromTimestamp($pomo->pomo_start)->diffInMinutes(\Carbon\Carbon::createFromTimestamp($pomo->pomo_end))
|
||||
}}
|
||||
</td>
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
<!-- Truncate notes to 32 characters -->
|
||||
<div class="max-w-sm truncate">
|
||||
{{ $pomo->notes }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="border px-4 py-2 text-blue-900 dark:text-gray-100">
|
||||
<!-- Edit and Delete form button groups -->
|
||||
<div class="flex flex-row">
|
||||
<div class="flex flex-col">
|
||||
<a href="{{ route('pomo.edit', $pomo->id) }}"
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Edit</a>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<form action="{{ route('pomo.destroy', $pomo->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit"
|
||||
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">Delete
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
<tbody id="pomo-container">
|
||||
@include('livewire.pomo.load-pomo')
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -11,51 +11,14 @@
|
|||
|
||||
<div class="py-4">
|
||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
@foreach($projects as $project)
|
||||
<div class="relative">
|
||||
<a href="{{ route('project.todo.index', $project) }}" class="card-link">
|
||||
<div
|
||||
class="bg-white dark:bg-gray-800 shadow-sm rounded-lg p-6 hover:shadow-md transition duration-300 ease-in-out transform hover:-translate-y-1">
|
||||
<div class="text-gray-800 dark:text-gray-100">
|
||||
<div class="mb-4">
|
||||
<h3 class="font-semibold text-lg mb-2">{{ $project->name }}</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400">{{ $project->description }}</p>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4" id="project-container">
|
||||
@include('project.load-projects')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<form action="{{ route('project.destroy', $project) }}" method="POST"
|
||||
class="delete-project-form absolute top-1 right-1">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="button"
|
||||
class="delete-button text-red-600 hover:text-red-800 transition duration-300 ease-in-out">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="modal hidden">
|
||||
<!-- Small Popover, with a background that is visible when modal is open -->
|
||||
<div class="popover popover-sm bg-white dark:bg-gray-800 shadow-lg rounded-lg p-6">
|
||||
<p class="mb-4">Are you sure you want to delete this project?</p>
|
||||
<button type="submit"
|
||||
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded mr-2">
|
||||
Delete
|
||||
</button>
|
||||
<button type="button"
|
||||
class="cancel-button bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="invisible">
|
||||
{{ $projects->links() }}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
@ -72,6 +35,35 @@
|
|||
modals[index].classList.add('hidden');
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
let nextPageUrl = '{{ $projects->nextPageUrl() }}';
|
||||
|
||||
$(window).scroll(function () {
|
||||
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 2000) {
|
||||
if (nextPageUrl) {
|
||||
loadMoreProjects();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function loadMoreProjects() {
|
||||
$.ajax({
|
||||
url: nextPageUrl,
|
||||
type: 'get',
|
||||
beforeSend: function () {
|
||||
nextPageUrl = '';
|
||||
},
|
||||
success: function (data) {
|
||||
nextPageUrl = data.nextPageUrl;
|
||||
$('#project-container').append(data.view);
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
console.error("Error loading more posts:", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@include('todo.todo_list')
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
@foreach($projects as $project)
|
||||
<div class="relative">
|
||||
<a href="{{ route('project.todo.index', $project) }}" class="card-link">
|
||||
<div
|
||||
class="bg-white dark:bg-gray-800 shadow-sm rounded-lg p-6 hover:shadow-md transition duration-300 ease-in-out transform hover:-translate-y-1">
|
||||
<div class="text-gray-800 dark:text-gray-100">
|
||||
<div class="mb-4">
|
||||
<h3 class="font-semibold text-lg mb-2">{{ $project->name }}</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400">{{ $project->description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<form action="{{ route('project.destroy', $project) }}" method="POST"
|
||||
class="delete-project-form absolute top-1 right-1">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="button"
|
||||
class="delete-button text-red-600 hover:text-red-800 transition duration-300 ease-in-out">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="modal hidden">
|
||||
<!-- Small Popover, with a background that is visible when modal is open -->
|
||||
<div class="popover popover-sm bg-white dark:bg-gray-800 shadow-lg rounded-lg p-6">
|
||||
<p class="mb-4">Are you sure you want to delete this project?</p>
|
||||
<button type="submit"
|
||||
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded mr-2">
|
||||
Delete
|
||||
</button>
|
||||
<button type="button"
|
||||
class="cancel-button bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endforeach
|
|
@ -19,7 +19,7 @@ use Illuminate\Support\Facades\Route;
|
|||
*/
|
||||
|
||||
Route::get('/', function () {
|
||||
return redirect(route('project.index'));
|
||||
return redirect(route('dashboard'));
|
||||
});
|
||||
|
||||
Route::get('/dashboard', [DashboardController::class, 'index'])
|
||||
|
|
Loading…
Reference in New Issue