initial commit

This commit is contained in:
2025-03-11 02:09:59 -03:00
commit 7c9c375029
16 changed files with 2232 additions and 0 deletions

24
.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

12
README.md Normal file
View File

@@ -0,0 +1,12 @@
# React + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
## Expanding the ESLint configuration
If you are developing a production application, we recommend using TypeScript and enable type-aware lint rules. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.

33
eslint.config.js Normal file
View File

@@ -0,0 +1,33 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
export default [
{ ignores: ['dist'] },
{
files: ['**/*.{js,jsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...reactHooks.configs.recommended.rules,
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
]

12
index.html Normal file
View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Coord-Keeper</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

4
makefile Normal file
View File

@@ -0,0 +1,4 @@
run:
bun run dev
build:
bun run build

1850
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
package.json Normal file
View File

@@ -0,0 +1,30 @@
{
"name": "coords-keeper",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@tailwindcss/vite": "^4.0.12",
"bootstrap": "^5.3.3",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react-swc": "^3.8.0",
"eslint": "^9.21.0",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^15.15.0",
"tailwindcss": "^4.0.12",
"vite": "^6.2.0"
}
}

1
src/App.css Normal file
View File

@@ -0,0 +1 @@
@import "tailwindcss"

18
src/App.jsx Normal file
View File

@@ -0,0 +1,18 @@
import { useState } from 'react'
import Barra from './components/Barra';
import Keeper from './components/coordkeeper';
function App() {
const [type, setType] = useState("overworld");
return (
<div>
<Barra active={type} setType={setType} />
<div class="container border text-white vw-100 mt-2 rounded p-2">
<Keeper tipo={type}/>
</div>
</div>
)
}
export default App;

40
src/components/Barra.jsx Normal file
View File

@@ -0,0 +1,40 @@
export default function Barra ({active, setType}) {
return (
<nav class="navbar navbar-expand-lg bg-dark-subtle h-fit w-100">
<div class="container-fluid">
<a class="navbar-brand" href="#">
Coords-Keeper
</a>
<div class="justify-content-end">
<ul class="navbar-nav">
<li className="nav-item">
<button
className={`btn bg-primary mx-2 ${active === "overworld" ? "text-black active" : "text-gray-100"}`}
onClick={() => setType("overworld")}
>
Overworld
</button>
</li>
<li className="nav-item">
<button
className={`btn bg-danger mx-2 ${active === "nether" ? "text-black active" : "text-gray-100"}`}
onClick={() => setType("nether")}
>
Nether
</button>
</li>
<li className="nav-item">
<button
className={`btn bg-success mx-2 ${active === "end" ? "text-black active" : "text-gray-100"}`}
onClick={() => setType("end")}
>
End
</button>
</li>
</ul>
</div>
</div>
</nav>
);
}

View File

@@ -0,0 +1,55 @@
import { useState } from "react";
export default function NuevaCoord({coord, setcoord, colapsar, tipo}) {
const [llevaY, setLlevaY] = useState(false);
const [x, setX] = useState("");
const [y, setY] = useState("");
const [z, setZ] = useState("");
const handleAdd = () => {
const newCoord = {
num: coord.length + 1,
x: x,
y: llevaY ? y : null,
z: z,
};
setcoord([...coord, newCoord]);
localStorage.setItem(tipo, JSON.stringify([...coord, newCoord]));
if (colapsar) colapsar();
};
return (
<div>
<input id="1"
type="checkbox" className="form-check-input me-2"
onChange={(e) => setLlevaY(e.target.checked)}
data-bs-toggle="collapse"
data-bs-target="#collapseY"
/>
<label className="form-check-label" htmlFor="1">
Lleva coordenada y?
</label>
<hr/>
<div className="d-flex align-items-center gap-1">
<div className="input-group mb-3">
<span class="input-group-text">x:</span>
<input type="text" className="form-control" onChange={(e) =>setX(e.target.value)}/>
</div>
<div className="input-group mb-3 collapse" id="collapseY">
<span class="input-group-text">y:</span>
<input type="text" className="form-control" onChange={(e) =>setY(e.target.value)}/>
</div>
<div className="input-group mb-3">
<span class="input-group-text">z:</span>
<input type="text" className="form-control" onChange={(e) =>setZ(e.target.value)}/>
</div>
</div>
<hr/>
<button className="btn btn-primary" onClick={handleAdd}>Añadir</button>
</div>
);
}

View File

@@ -0,0 +1,67 @@
import { useEffect, useRef, useState } from "react";
import NuevaCoord from "./NuevaCoord";
export default function Keeper({tipo}){
const [coords,setCoords] = useState(JSON.parse(localStorage.getItem(tipo)||"[]"));
const collapseRef = useRef(null);
console.log(coords);
useEffect(() => {
const storedCoords = JSON.parse(localStorage.getItem(tipo)||"[]");
console.log(storedCoords);
if (storedCoords) {
setCoords(storedCoords);
}
}, [tipo]);
const collapseAccordion = () => {
if (collapseRef.current) {
const bsCollapse = new window.bootstrap.Collapse(collapseRef.current, {
toggle: false,
});
bsCollapse.hide();
}
};
return (
<>
<div className="accordion" id="accordionNuevaCoord">
<div className="accordion-item">
<h2 className="accordion-header" id="headingNuevaCoord">
<button
className="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#collapseNuevaCoord"
aria-expanded="false"
aria-controls="collapseNuevaCoord"
>
Nueva Coordenada
</button>
</h2>
<div
id="collapseNuevaCoord"
className="accordion-collapse collapse"
aria-labelledby="headingNuevaCoord"
data-bs-parent="#accordionNuevaCoord"
ref={collapseRef}
>
<div className="accordion-body">
<NuevaCoord coord={coords} setcoord={setCoords} colapsar={collapseAccordion} tipo={tipo} />
</div>
</div>
</div>
</div>
<hr/>
{coords.length == 0 &&
<h3 className="text-center">No hay Coordenadas que Mostrar.</h3>
}
{coords.length !=0 && coords.map(x=>
<div className="m-2"><b>#{x.num}:</b> x:{x.x} {x.y !== null && `y: ${x.y}`} z:{x.z} <button class="btn btn-outline-warning">Editar</button></div>
)}
</>
);
}

53
src/index.css Normal file
View File

@@ -0,0 +1,53 @@
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

13
src/main.jsx Normal file
View File

@@ -0,0 +1,13 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.bundle.min.js";
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
)

12
tailwind.config.js Normal file
View File

@@ -0,0 +1,12 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,jsx,ts,tsx}"
],
theme: {
extend: {},
},
plugins: [],
};

8
vite.config.js Normal file
View File

@@ -0,0 +1,8 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import tailwindcss from "@tailwindcss/vite";
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), tailwindcss()],
})