commit ef495b7529522e97c42f664c6ac6721ba73286a6 Author: Jose Date: Sun Aug 3 05:52:49 2025 +0200 init commit diff --git a/index.html b/index.html new file mode 100644 index 0000000..187faa0 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + + + +
+ + + diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..30e99a0 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src"] + } \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..b286356 --- /dev/null +++ b/package.json @@ -0,0 +1,39 @@ +{ + "name": "miarma-base", + "private": true, + "version": "1.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@fortawesome/fontawesome-free": "^7.0.0", + "@fortawesome/fontawesome-svg-core": "^7.0.0", + "@fortawesome/free-brands-svg-icons": "^7.0.0", + "@fortawesome/free-regular-svg-icons": "^7.0.0", + "@fortawesome/free-solid-svg-icons": "^7.0.0", + "@fortawesome/react-fontawesome": "^0.2.3", + "axios": "^1.11.0", + "bootstrap": "^5.3.7", + "date-fns": "^4.1.0", + "framer-motion": "^12.23.12", + "react": "^19.1.0", + "react-bootstrap": "^2.10.10", + "react-dom": "^19.1.0", + "react-router-dom": "^7.7.1" + }, + "devDependencies": { + "@eslint/js": "^9.30.1", + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "electron": "^37.2.5", + "eslint": "^9.30.1", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.3.0", + "vite": "^7.0.4" + } +} diff --git a/public/config/settings.dev.json b/public/config/settings.dev.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/public/config/settings.dev.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/public/config/settings.prod.json b/public/config/settings.prod.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/public/config/settings.prod.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/public/fonts/OpenSans.ttf b/public/fonts/OpenSans.ttf new file mode 100644 index 0000000..ac587b4 Binary files /dev/null and b/public/fonts/OpenSans.ttf differ diff --git a/public/fonts/ProductSansBold.ttf b/public/fonts/ProductSansBold.ttf new file mode 100644 index 0000000..d847195 Binary files /dev/null and b/public/fonts/ProductSansBold.ttf differ diff --git a/public/fonts/ProductSansBoldItalic.ttf b/public/fonts/ProductSansBoldItalic.ttf new file mode 100644 index 0000000..129d12d Binary files /dev/null and b/public/fonts/ProductSansBoldItalic.ttf differ diff --git a/public/fonts/ProductSansItalic.ttf b/public/fonts/ProductSansItalic.ttf new file mode 100644 index 0000000..5fc56d4 Binary files /dev/null and b/public/fonts/ProductSansItalic.ttf differ diff --git a/public/fonts/ProductSansRegular.ttf b/public/fonts/ProductSansRegular.ttf new file mode 100644 index 0000000..c0442ee Binary files /dev/null and b/public/fonts/ProductSansRegular.ttf differ diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..38bb067 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,13 @@ +import 'bootstrap/dist/css/bootstrap.min.css' +import 'bootstrap/dist/js/bootstrap.bundle.min.js' + +const App = () => { + return ( + <> +

Hola!

+ Abre este link + + ) +} + +export default App diff --git a/src/css/index.css b/src/css/index.css new file mode 100644 index 0000000..5cf7312 --- /dev/null +++ b/src/css/index.css @@ -0,0 +1,88 @@ +/* ================================ + FUENTES PERSONALIZADAS +================================== */ +@font-face { + font-family: "Open Sans"; + src: url('/fonts/OpenSans.ttf'); +} + +@font-face { + font-family: "Product Sans"; + src: url('/fonts/ProductSansRegular.ttf'); +} + +@font-face { + font-family: "Product Sans Italic"; + src: url('/fonts/ProductSansItalic.ttf'); +} + +@font-face { + font-family: "Product Sans Italic Bold"; + src: url('/fonts/ProductSansBoldItalic.ttf'); +} + +@font-face { + font-family: "Product Sans Bold"; + src: url('/fonts/ProductSansBold.ttf'); +} + +/* ================================ + PALETA DE COLORES +================================== */ + +:root { + +} + +/* Tema Claro */ +.light { + +} + + +/* Tema Oscuro */ +.dark { + +} + +/* ================================ + ESTILOS BASE / RESET SUAVE +================================== */ +html, +body { + font-family: "Open Sans", sans-serif; + color: var(--text-color); + background-color: var(--bg-color); + +} + +body { + background-color: transparent !important; /* compatibilidad navbar fija */ +} + +main { + color: var(--text-color); + background-color: var(--bg-color); +} + +/* TipografĂ­a global */ +div, +label, +input, +p, +span, +a, +button { + font-family: "Open Sans", sans-serif; + color: var(--text-color); +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Product Sans", sans-serif; + color: var(--text-color); +} \ No newline at end of file diff --git a/src/hooks/useData.js b/src/hooks/useData.js new file mode 100644 index 0000000..a1c5dd5 --- /dev/null +++ b/src/hooks/useData.js @@ -0,0 +1,130 @@ +import { useState, useEffect, useCallback, useRef } from "react"; +import axios from "axios"; + +export const useData = (config) => { + const [data, setData] = useState(null); + const [dataLoading, setLoading] = useState(true); + const [dataError, setError] = useState(null); + const configRef = useRef(); + + useEffect(() => { + if (config?.baseUrl) { + configRef.current = config; + } + }, [config]); + + const getAuthHeaders = () => ({ + "Content-Type": "application/json", + "Authorization": `Bearer ${localStorage.getItem("token")}`, + }); + + const fetchData = useCallback(async () => { + const current = configRef.current; + if (!current?.baseUrl) return; + + setLoading(true); + setError(null); + + try { + const response = await axios.get(current.baseUrl, { + headers: getAuthHeaders(), + params: current.params, + }); + setData(response.data.data); + } catch (err) { + setError(err.response?.data?.message || err.message); + } finally { + setLoading(false); + } + }, []); + + useEffect(() => { + if (config?.baseUrl) { + fetchData(); + } + }, [config, fetchData]); + + const getData = async (url, params = {}) => { + try { + const response = await axios.get(url, { + headers: getAuthHeaders(), + params, + }); + return { data: response.data.data, error: null }; + } catch (err) { + return { + data: null, + error: err.response?.data?.message || err.message, + }; + } + }; + + const postData = async (endpoint, payload) => { + const headers = { + Authorization: `Bearer ${localStorage.getItem("token")}`, + ...(payload instanceof FormData ? {} : { "Content-Type": "application/json" }), + }; + const response = await axios.post(endpoint, payload, { headers }); + await fetchData(); + return response.data.data; + }; + + const postDataValidated = async (endpoint, payload) => { + try { + const headers = { + Authorization: `Bearer ${localStorage.getItem("token")}`, + ...(payload instanceof FormData ? {} : { "Content-Type": "application/json" }), + }; + const response = await axios.post(endpoint, payload, { headers }); + return { data: response.data.data, errors: null }; + } catch (err) { + const raw = err.response?.data?.message; + let parsed = {}; + + try { + parsed = JSON.parse(raw); + } catch { + return { data: null, errors: { general: raw || err.message } }; + } + + return { data: null, errors: parsed }; + } + }; + + const putData = async (endpoint, payload) => { + const response = await axios.put(endpoint, payload, { + headers: getAuthHeaders(), + }); + await fetchData(); + return response.data.data; + }; + + const deleteData = async (endpoint) => { + const response = await axios.delete(endpoint, { + headers: getAuthHeaders(), + }); + await fetchData(); + return response.data.data; + }; + + const deleteDataWithBody = async (endpoint, payload) => { + const response = await axios.delete(endpoint, { + headers: getAuthHeaders(), + data: payload, + }); + await fetchData(); + return response.data.data; + }; + + return { + data, + dataLoading, + dataError, + getData, + postData, + postDataValidated, + putData, + deleteData, + deleteDataWithBody, + }; +}; diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 0000000..3226b15 --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,13 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import '@/css/index.css' +import App from '@/App.jsx' +import { BrowserRouter } from 'react-router-dom' + +createRoot(document.getElementById('root')).render( + + + + + +) \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..a8506ad --- /dev/null +++ b/vite.config.js @@ -0,0 +1,17 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import path from 'path' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], + server: { + host: "localhost", + port: 3000, + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, +})