Documentation Index
Fetch the complete documentation index at: https://mintlify.com/estebansalas94/Prueba-Soporte/llms.txt
Use this file to discover all available pages before exploring further.
The frontend is a Vue.js 2 single-page component embedded in a Blade view. All state is managed centrally by Vuex, and all HTTP calls to the Laravel backend are made through Axios actions in the store.
Component structure
There is one primary component in this application:
resources/js/
├── app.js # Vue bootstrap + Axios config
├── store.js # Vuex store (state, mutations, actions, getters)
└── Components/
└── TaskList.vue # Main UI component
TaskList.vue
TaskList.vue is the only user-facing Vue component. It renders an unordered list of pending tasks and a form to add new ones.
Template responsibilities:
- Iterates over
tasks from the Vuex state with v-for
- Renders each task’s
title, description, and assigned user
- Provides a Complete button that dispatches
completeTask(task.id)
- Provides a Delete button that dispatches
deleteTask(task.id)
- Renders a form bound with
v-model to a local newTask object (title, description, user)
- On form submit, calls the local
addTask() method which validates fields before dispatching to the store
<template>
<div class="container mt-5">
<h1 class="text-center mb-4">Task List</h1>
<ul class="list-group mb-4">
<li v-for="task in tasks" :key="task.id" class="list-group-item d-flex justify-content-between align-items-center">
<div>
<h5 class="mb-1">{{ task.title }}</h5>
<p class="mb-1">{{ task.description }}</p>
<small class="text-muted">Assigned to: {{ task.user }}</small>
</div>
<div>
<button class="btn btn-success btn-sm mr-2" @click="completeTask(task.id)">Complete</button>
<button class="btn btn-danger btn-sm" @click="deleteTask(task.id)">Delete</button>
</div>
</li>
</ul>
<form @submit.prevent="addTask" class="card card-body">
<div class="form-group">
<input v-model="newTask.title" class="form-control" placeholder="Task Title" required>
</div>
<div class="form-group">
<input v-model="newTask.description" class="form-control" placeholder="Task Description" required>
</div>
<div class="form-group">
<input v-model="newTask.user" class="form-control" placeholder="Assigned User" required>
</div>
<button type="submit" class="btn btn-primary btn-block">Add Task</button>
</form>
</div>
</template>
Script responsibilities:
- Maps
tasks from Vuex state via mapState
- Maps
fetchTasks, addTask, completeTask, deleteTask, showAssignedTasks, and showAllTasks from Vuex actions via mapActions
- Calls
fetchTasks() in the mounted lifecycle hook to load tasks on page load
- Local
addTask() method validates that all three fields are non-empty before dispatching to the store
The component defines mounted twice — once as a shorthand method property and once as a full lifecycle hook. Only the second definition (the mounted() hook) is executed by Vue. The first is overridden.
Vuex store
The store is defined in resources/js/store.js and registered globally in app.js.
State
Mutations
Actions
Getters
The store holds a single top-level state property: an array of task objects fetched from the backend.state: {
tasks: [] // Estado inicial para las tareas
},
Each task object in the array mirrors the database row shape returned by the TaskController:| Field | Type | Description |
|---|
id | number | Primary key |
user_id | number | Foreign key to the owning user |
title | string | Task title |
description | string | Task description |
completed | boolean | 0 = pending, 1 = complete |
created_at | string | ISO timestamp |
updated_at | string | ISO timestamp |
Mutations are the only way to synchronously modify state.mutations: {
ADD_TASK(state, task) {
state.tasks.push(task);
},
UPDATE_TASK(state, updatedTask) {
const index = state.tasks.findIndex(t => t.id === updatedTask.id);
if (index !== -1) {
Vue.set(state.tasks, index, updatedTask);
}
},
SET_TASKS(state, tasks) {
state.tasks = tasks;
},
DELETE_TASK(state, taskId) {
state.tasks = state.tasks.filter(t => t.id !== taskId);
}
},
| Mutation | Payload | Effect |
|---|
ADD_TASK | task object | Appends the task to the array |
UPDATE_TASK | updated task object | Replaces the matching task in-place using Vue.set for reactivity |
SET_TASKS | task array | Replaces the entire task list |
DELETE_TASK | task ID | Filters out the task with the given ID |
Actions handle async HTTP calls via Axios and commit mutations on success.actions: {
fetchTasks({ commit }, showAll = false) {
try {
axios.get('/tasks/index', { params: { showAll } })
.then(response => {
commit('SET_TASKS', response.data);
})
.catch(error => {
console.error("Error adding task:", error);
});
} catch (error) {
console.error("Error fetching tasks:", error);
}
},
addTask({ commit }, task) {
axios.post('/tasks', task)
.then(response => {
commit('ADD_TASK', response.data);
})
.catch(error => {
console.error("Error adding task:", error);
});
},
updateTask({ commit }, task) {
axios.put(`/tasks/${task.id}`, {
title: task.title,
description: task.description,
completed: task.completed
})
.then(response => {
commit('UPDATE_TASK', response.data);
})
.catch(error => {
console.error("Error updating task:", error);
});
},
deleteTask({ commit }, taskId) {
axios.delete(`/tasks/${taskId}`)
.then(() => {
commit('DELETE_TASK', taskId);
})
.catch(error => {
console.error("Error deleting task:", error);
});
},
completeTask({ commit }, taskId) {
axios.put(`/tasks/${taskId}/complete`)
.then(response => {
commit('UPDATE_TASK', response.data.task);
})
.catch(error => {
console.error("Error completing task:", error);
});
}
},
| Action | HTTP call | Mutation committed |
|---|
fetchTasks(showAll) | GET /tasks/index?showAll=… | SET_TASKS |
addTask(task) | POST /tasks | ADD_TASK |
updateTask(task) | PUT /tasks/:id | UPDATE_TASK |
deleteTask(taskId) | DELETE /tasks/:id | DELETE_TASK |
completeTask(taskId) | PUT /tasks/:id/complete | UPDATE_TASK |
updateTask is defined in the store but is not dispatched by TaskList.vue. Only completeTask is used to mark tasks as done from the UI.
A single getter re-exposes the task array for components that prefer getter syntax over direct state access.getters: {
tasks: state => state.tasks
}
app.js bootstrapping
app.js is the Webpack entry point. It imports Vue, Vuex, the Vuex store instance, the TaskList component, and Axios, then mounts the Vue application on the #app DOM element.
import Vue from 'vue';
import Vuex from 'vuex';
import TaskList from './Components/TaskList.vue';
import store from './store';
import axios from 'axios';
Vue.use(Vuex);
// Configuración global de Axios
axios.defaults.baseURL = 'http://127.0.0.1:8000'; // Cambia esto a tu URL base si es necesario
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
const app = new Vue({
el: '#app',
store, // Agrega el store a la instancia de Vue
components: { TaskList },
});
Key bootstrap decisions:
axios.defaults.baseURL is set to http://127.0.0.1:8000 — this must be updated to match the deployed server URL in production.
- The
X-Requested-With: XMLHttpRequest header tells Laravel to treat requests as AJAX, which affects how it formats validation error responses.
- The store is passed directly to the root Vue instance, making it available in all child components via
this.$store.
The hardcoded baseURL in app.js will fail in any environment other than a local dev server running on port 8000. Use an environment variable (e.g. process.env.MIX_APP_URL) for deployments.
Build pipeline (Laravel Mix)
Assets are compiled by Laravel Mix 6 (a Webpack wrapper). The entire build configuration lives in webpack.mix.js:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.vue();
This single chain:
- Takes
resources/js/app.js as the Webpack entry point
- Enables the Vue single-file component (
.vue) loader
- Outputs the compiled bundle to
public/js/app.js
| npm script | Command | Purpose |
|---|
npm run dev | webpack with NODE_ENV=development | Development build with source maps |
npm run watch | Same as dev + --watch | Rebuilds on file changes |
npm run hot | webpack-dev-server with HMR | Hot module replacement |
npm run prod | webpack with NODE_ENV=production | Minified production bundle |