You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.6 KiB
JavaScript

// src/store/noticiasStore.js
import { defineStore } from "pinia"
import api from "../axios" // <-- cambia a tu axios (admin) si tienes otro
export const useNoticiasStore = defineStore("noticias", {
state: () => ({
noticias: [],
noticia: null,
loading: false,
saving: false,
deleting: false,
error: null,
// paginación (si tu back manda meta)
meta: {
current_page: 1,
last_page: 1,
per_page: 9,
total: 0,
},
// filtros
filters: {
publicado: null, // true/false/null
categoria: "",
q: "",
per_page: 9,
page: 1,
},
}),
getters: {
// para el público: solo publicadas (si ya las filtras en backend, esto es opcional)
publicadas: (state) => state.noticias.filter((n) => n.publicado),
// para ordenar en frontend (opcional)
ordenadas: (state) =>
[...state.noticias].sort((a, b) => {
const da = a.fecha_publicacion ? new Date(a.fecha_publicacion).getTime() : 0
const db = b.fecha_publicacion ? new Date(b.fecha_publicacion).getTime() : 0
return db - da
}),
},
actions: {
// ========= LISTAR =========
async cargarNoticias(extraParams = {}) {
this.loading = true
this.error = null
try {
const params = {
per_page: this.filters.per_page,
page: this.filters.page,
...extraParams,
}
if (this.filters.publicado !== null && this.filters.publicado !== "") {
params.publicado = this.filters.publicado ? 1 : 0
}
if (this.filters.categoria) params.categoria = this.filters.categoria
if (this.filters.q) params.q = this.filters.q
// Ruta agrupada:
// GET /api/administracion/noticias
const res = await api.get("/admin/noticias", { params })
this.noticias = res.data?.data ?? []
this.meta = res.data?.meta ?? this.meta
} catch (err) {
this.error = err.response?.data?.message || "Error al cargar noticias"
console.error(err)
} finally {
this.loading = false
}
},
// ========= VER 1 =========
async cargarNoticia(id) {
this.loading = true
this.error = null
try {
const res = await api.get(`/admin/noticias/${id}`)
this.noticia = res.data?.data ?? res.data
} catch (err) {
this.error = err.response?.data?.message || "Error al cargar la noticia"
console.error(err)
} finally {
this.loading = false
}
},
// ========= CREAR =========
// payload: { titulo, descripcion_corta, contenido, categoria, tag_color, fecha_publicacion, publicado, destacado, orden, link_url, link_texto, imagen(File) }
async crearNoticia(payload) {
this.saving = true
this.error = null
try {
const form = this._toFormData(payload)
const res = await api.post("/admin/noticias", form, {
headers: { "Content-Type": "multipart/form-data" },
})
const noticia = res.data?.data ?? null
if (noticia) {
// opcional: agrega arriba
this.noticias = [noticia, ...this.noticias]
}
return noticia
} catch (err) {
this.error = err.response?.data?.message || "Error al crear noticia"
console.error(err)
throw err
} finally {
this.saving = false
}
},
// ========= ACTUALIZAR =========
async actualizarNoticia(id, payload) {
this.saving = true
this.error = null
try {
// Si hay imagen (File), conviene multipart
const hasFile = payload?.imagen instanceof File
let res
if (hasFile) {
const form = this._toFormData(payload)
// Si tu ruta es PUT, axios con multipart PUT funciona.
res = await api.put(`/admin/noticias/${id}`, form, {
headers: { "Content-Type": "multipart/form-data" },
})
} else {
// JSON normal
res = await api.put(`/administracion/noticias/${id}`, payload)
}
const updated = res.data?.data ?? null
if (updated) {
this.noticias = this.noticias.map((n) => (n.id === id ? updated : n))
if (this.noticia?.id === id) this.noticia = updated
}
return updated
} catch (err) {
this.error = err.response?.data?.message || "Error al actualizar noticia"
console.error(err)
throw err
} finally {
this.saving = false
}
},
// ========= ELIMINAR =========
async eliminarNoticia(id) {
this.deleting = true
this.error = null
try {
await api.delete(`/admin/noticias/${id}`)
this.noticias = this.noticias.filter((n) => n.id !== id)
if (this.noticia?.id === id) this.noticia = null
return true
} catch (err) {
this.error = err.response?.data?.message || "Error al eliminar noticia"
console.error(err)
throw err
} finally {
this.deleting = false
}
},
// ========= Helpers =========
setFiltro(key, value) {
this.filters[key] = value
},
resetFiltros() {
this.filters = { publicado: null, categoria: "", q: "", per_page: 9, page: 1 }
},
_toFormData(payload = {}) {
const form = new FormData()
Object.entries(payload).forEach(([k, v]) => {
if (v === undefined || v === null) return
// booleans como 1/0 (Laravel feliz)
if (typeof v === "boolean") {
form.append(k, v ? "1" : "0")
return
}
form.append(k, v)
})
return form
},
},
})