init commit
This commit is contained in:
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root" class="p-0 m-0"></div>
|
||||||
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
jsconfig.json
Normal file
9
jsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
39
package.json
Normal file
39
package.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
public/config/settings.dev.json
Normal file
1
public/config/settings.dev.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
public/config/settings.prod.json
Normal file
1
public/config/settings.prod.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
BIN
public/fonts/OpenSans.ttf
Normal file
BIN
public/fonts/OpenSans.ttf
Normal file
Binary file not shown.
BIN
public/fonts/ProductSansBold.ttf
Normal file
BIN
public/fonts/ProductSansBold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/ProductSansBoldItalic.ttf
Normal file
BIN
public/fonts/ProductSansBoldItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/ProductSansItalic.ttf
Normal file
BIN
public/fonts/ProductSansItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/ProductSansRegular.ttf
Normal file
BIN
public/fonts/ProductSansRegular.ttf
Normal file
Binary file not shown.
13
src/App.jsx
Normal file
13
src/App.jsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||||
|
import 'bootstrap/dist/js/bootstrap.bundle.min.js'
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h1>Hola!</h1>
|
||||||
|
<a href="https://gallardo.dev">Abre este link</a>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
||||||
88
src/css/index.css
Normal file
88
src/css/index.css
Normal file
@@ -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);
|
||||||
|
}
|
||||||
130
src/hooks/useData.js
Normal file
130
src/hooks/useData.js
Normal file
@@ -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,
|
||||||
|
};
|
||||||
|
};
|
||||||
13
src/main.jsx
Normal file
13
src/main.jsx
Normal file
@@ -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(
|
||||||
|
<StrictMode>
|
||||||
|
<BrowserRouter>
|
||||||
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
|
</StrictMode>
|
||||||
|
)
|
||||||
17
vite.config.js
Normal file
17
vite.config.js
Normal file
@@ -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'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user