From f2a74d923e375269ebb7f6dcd531057bedef62f0 Mon Sep 17 00:00:00 2001 From: hall9zeha <vmwaretars@gmail.com> Date: Wed, 17 Aug 2022 12:53:04 -0500 Subject: [PATCH 1/5] Backend con express y mongodb terminado --- Project/.gitignore | 2 + Project/API/controllers/patientController.js | 69 ++++++++++++++++++++ Project/API/index.js | 32 +++++++++ Project/API/models/Patient.js | 29 ++++++++ Project/API/package.json | 18 +++++ Project/API/routes/index.js | 27 ++++++++ Project/README.md | 11 ++++ 7 files changed, 188 insertions(+) create mode 100644 Project/.gitignore create mode 100644 Project/API/controllers/patientController.js create mode 100644 Project/API/index.js create mode 100644 Project/API/models/Patient.js create mode 100644 Project/API/package.json create mode 100644 Project/API/routes/index.js create mode 100644 Project/README.md diff --git a/Project/.gitignore b/Project/.gitignore new file mode 100644 index 0000000..6553522 --- /dev/null +++ b/Project/.gitignore @@ -0,0 +1,2 @@ +API/node_modules +API/package-lock.json \ No newline at end of file diff --git a/Project/API/controllers/patientController.js b/Project/API/controllers/patientController.js new file mode 100644 index 0000000..26ede94 --- /dev/null +++ b/Project/API/controllers/patientController.js @@ -0,0 +1,69 @@ +//Importamos el modelo +const Patient = require('../models/Patient'); + + +//Cuando se crea el nuevo cliente +exports.newClient = async (req,res,next) =>{ + //Insertar en la base de datos + + //creamos un objeto con los datos del paciente obtenidos en req.body + + const patient = new Patient(re.body); + + try { + await patient.save(); + res.json({message:'Cliente registrad correctamente'}); + } catch (error) { + console.log(error); + next(); + } + + + +} + +exports.getPatients = async (req, res,next) =>{ + try { + const patients = await Patient.find({}); + res.json(patients) + } catch (error) { + console.log(error); + next(); + } +} + +exports.getPatientById = async(req,res,next) =>{ + try { + //este id en params viene definido del modo como lo pusimos en + //routes index.js + const patient = await Patient.findById(req.params.id) + res.json(patient); + + } catch (error) { + console.log(error); + next(); + } +} + +exports.updatePatient = async(req,res,next) =>{ + try { + const patient = await Patient.findOneAndUpdate({_id: req.params.id}, req.body,{ + new:true + }); + res.json(patient); + } catch (error) { + console.log(error); + next(); + + } +} +exports.deletePatient = async(req,res,next) =>{ + try { + await Patient.findByIdAndDelete({_id : req.params.id}); + res.json({message: 'El registro fue eliminado'}); + } catch (error) { + console.log(error); + next(); + } +} + diff --git a/Project/API/index.js b/Project/API/index.js new file mode 100644 index 0000000..a89f3b5 --- /dev/null +++ b/Project/API/index.js @@ -0,0 +1,32 @@ +const express = require('express') +const mongoose = require('mongoose'); +const routes = require('./routes'); // como contiene un index.js no hay necesidad de ponerlo, JS lo leera automáticamente +//creamos el servidor +const bodyParser = require('body-parser'); + + +const app = express(); + +// conectar a mongoDB + +mongoose.Promise = global.Promise; +//Si nuestra base de datos es local + +mongoose.connect('mongodb://localhost/vet',{//vet es el nombre de la base de datos + useNewUrlParser: true, + useUnifiedTopology: true, + //useFindAndModify:false +}) + +//Habilitamos el body parser con express para leer los datos de los formularios +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({extended: true})); + +//Habilitamos el routing +app.use('/', routes()) + +//puerto del servidor y arranque + +app.listen(4000, ()=>{ + console.log('Servidor funcionando') +}) \ No newline at end of file diff --git a/Project/API/models/Patient.js b/Project/API/models/Patient.js new file mode 100644 index 0000000..3712142 --- /dev/null +++ b/Project/API/models/Patient.js @@ -0,0 +1,29 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const patientSchema = new Schema({ + name:{ + type: String, + trim: true + }, + owner:{ + type: String, + trim: true + }, + date:{ + type: String, + trim: true + }, + time:{ + type: String, + trim: true + }, + signals:{ + type: String, + trim: true + } + + +}); + +module.exports = mongoose.model('Patient',patientSchema) \ No newline at end of file diff --git a/Project/API/package.json b/Project/API/package.json new file mode 100644 index 0000000..6778fc4 --- /dev/null +++ b/Project/API/package.json @@ -0,0 +1,18 @@ +{ + "name": "fullstack-api", + "version": "1.0.0", + "description": "Backend con Mongo db y express", + "main": "index.js", + "scripts": { + "dev": "nodemon ./index.js" + }, + "author": "Barry Zea H.", + "license": "ISC", + "dependencies": { + "express": "^4.18.1", + "mongoose": "^6.5.2" + }, + "devDependencies": { + "nodemon": "^2.0.19" + } +} diff --git a/Project/API/routes/index.js b/Project/API/routes/index.js new file mode 100644 index 0000000..db8b5aa --- /dev/null +++ b/Project/API/routes/index.js @@ -0,0 +1,27 @@ +const express = require('express'); +const router = express.Router(); +const patientController = require('../controllers/patientController') + +module.exports = function() { + //agregamos nuevos pacientes via POST + router.post('/patients', + patientController.newClient + ) + router.get('/patients', + patientController.getPatients + ) + //obtener un paciente por su id + + router.get('/patients/:id', + patientController.getPatientById + ) + //actualizar paciente por id + router.put('/patients/:id', + patientController.updatePatient + ) + //Eliminar pacient por id + router.delete('patients/:id', + patientController.deletePatient + ) + return router; +} \ No newline at end of file diff --git a/Project/README.md b/Project/README.md new file mode 100644 index 0000000..095fdec --- /dev/null +++ b/Project/README.md @@ -0,0 +1,11 @@ +# App full stack de citas de una veterinaria - Con Mongo db y express + +- Mongo db +- Express +- React +- Electron + +# Instalar + +- ``` npm install express mongoose ``` -> Para realizar consultas a mongo db de una manera más sencilla, y para crear un servidor local con express. +- ``` npm install --save-dev nodemon ``` \ No newline at end of file From 5af5b7db3989da379bd5fa0a3b2b4f70b854aadd Mon Sep 17 00:00:00 2001 From: hall9zeha <vmwaretars@gmail.com> Date: Sat, 20 Aug 2022 17:59:36 -0500 Subject: [PATCH 2/5] Frontend terminado,corregir ciertos errores por las dependencias de react-router-dom, por el cambio de versiones --- Project/.gitignore | 21 ++- Project/API/controllers/patientController.js | 2 +- Project/API/index.js | 20 +++ Project/API/models/Patient.js | 4 + Project/API/package.json | 1 + Project/README.md | 18 ++- Project/frontend/.env.development | 1 + Project/frontend/README.md | 70 ++++++++++ Project/frontend/package.json | 41 ++++++ Project/frontend/public/css/app.css | 49 +++++++ Project/frontend/public/favicon.ico | Bin 0 -> 3870 bytes Project/frontend/public/index.html | 46 +++++++ Project/frontend/public/logo192.png | Bin 0 -> 5347 bytes Project/frontend/public/logo512.png | Bin 0 -> 9664 bytes Project/frontend/public/manifest.json | 25 ++++ Project/frontend/public/robots.txt | 3 + Project/frontend/src/App.js | 70 ++++++++++ Project/frontend/src/components/Meeting.js | 100 ++++++++++++++ Project/frontend/src/components/NewDate.js | 136 +++++++++++++++++++ Project/frontend/src/components/Patients.js | 50 +++++++ Project/frontend/src/config/axios.js | 7 + Project/frontend/src/index.js | 17 +++ Project/frontend/src/reportWebVitals.js | 13 ++ Project/frontend/src/setupTests.js | 5 + Project/index.html | 13 -- 25 files changed, 694 insertions(+), 18 deletions(-) create mode 100644 Project/frontend/.env.development create mode 100644 Project/frontend/README.md create mode 100644 Project/frontend/package.json create mode 100644 Project/frontend/public/css/app.css create mode 100644 Project/frontend/public/favicon.ico create mode 100644 Project/frontend/public/index.html create mode 100644 Project/frontend/public/logo192.png create mode 100644 Project/frontend/public/logo512.png create mode 100644 Project/frontend/public/manifest.json create mode 100644 Project/frontend/public/robots.txt create mode 100644 Project/frontend/src/App.js create mode 100644 Project/frontend/src/components/Meeting.js create mode 100644 Project/frontend/src/components/NewDate.js create mode 100644 Project/frontend/src/components/Patients.js create mode 100644 Project/frontend/src/config/axios.js create mode 100644 Project/frontend/src/index.js create mode 100644 Project/frontend/src/reportWebVitals.js create mode 100644 Project/frontend/src/setupTests.js delete mode 100644 Project/index.html diff --git a/Project/.gitignore b/Project/.gitignore index 6553522..1d05cc5 100644 --- a/Project/.gitignore +++ b/Project/.gitignore @@ -1,2 +1,21 @@ API/node_modules -API/package-lock.json \ No newline at end of file +API/package-lock.json +frontend/node_modules +frontend/package-lock.json + +# testing +/coverage + +# production +/build + +# misc +frontend/.DS_Store +frontend/.env.local +frontend/.env.development.local +frontend/.env.test.local +frontend/.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/Project/API/controllers/patientController.js b/Project/API/controllers/patientController.js index 26ede94..402a867 100644 --- a/Project/API/controllers/patientController.js +++ b/Project/API/controllers/patientController.js @@ -8,7 +8,7 @@ exports.newClient = async (req,res,next) =>{ //creamos un objeto con los datos del paciente obtenidos en req.body - const patient = new Patient(re.body); + const patient = new Patient(req.body); try { await patient.save(); diff --git a/Project/API/index.js b/Project/API/index.js index a89f3b5..fc72661 100644 --- a/Project/API/index.js +++ b/Project/API/index.js @@ -3,10 +3,30 @@ const mongoose = require('mongoose'); const routes = require('./routes'); // como contiene un index.js no hay necesidad de ponerlo, JS lo leera automáticamente //creamos el servidor const bodyParser = require('body-parser'); +const cors = require('cors'); const app = express(); + +//escondemos la visibilidad de nuestra api con cors +const whitelist = ['http://localhost:3000']; +const corsOptions = { + origin:(origin, callback) => { + const exist = whitelist.some(domain=> domain === origin); + if(exist){ + callback(null,true) + } + else{ + callback(new Error('no permitido por CORS')) + } + } +} + +//app.use(cors(corsOptions)); +// +//pero mientras lo mantendremos abierto +app.use(cors()); // conectar a mongoDB mongoose.Promise = global.Promise; diff --git a/Project/API/models/Patient.js b/Project/API/models/Patient.js index 3712142..666a312 100644 --- a/Project/API/models/Patient.js +++ b/Project/API/models/Patient.js @@ -21,6 +21,10 @@ const patientSchema = new Schema({ signals:{ type: String, trim: true + }, + phone:{ + type: String, + trim: true } diff --git a/Project/API/package.json b/Project/API/package.json index 6778fc4..0934936 100644 --- a/Project/API/package.json +++ b/Project/API/package.json @@ -9,6 +9,7 @@ "author": "Barry Zea H.", "license": "ISC", "dependencies": { + "cors": "^2.8.5", "express": "^4.18.1", "mongoose": "^6.5.2" }, diff --git a/Project/README.md b/Project/README.md index 095fdec..81caa99 100644 --- a/Project/README.md +++ b/Project/README.md @@ -5,7 +5,19 @@ - React - Electron -# Instalar - +# Instalar Backend +- Creamos una carpeta API dentro de esa carpeta crearemos todos los archivos de nuestro backend, e instalaremos las dependencias necesarias. +- Inicializamos el proyecto con ```npm init ``` - ``` npm install express mongoose ``` -> Para realizar consultas a mongo db de una manera más sencilla, y para crear un servidor local con express. -- ``` npm install --save-dev nodemon ``` \ No newline at end of file +- ``` npm install --save-dev nodemon ``` +- ``` npm install axios ``` para consumir nuestra api hecha en mongodb + +# Frontend + +- Creamos una carpeta "frontend" dentro de esa carpeta crearemos todos los archivos de nuestro backend, también las dependencias necesarias. +- Salimos de la carpeta API y en la raíz del proyecto creamos la app 'frontend' con react +``` npx create-react-app frontend ``` + +- ``` npm install react-router-dom ``` +- ``` npm install cors ``` +- ``` npm install sweetalert2 ``` \ No newline at end of file diff --git a/Project/frontend/.env.development b/Project/frontend/.env.development new file mode 100644 index 0000000..0011ceb --- /dev/null +++ b/Project/frontend/.env.development @@ -0,0 +1 @@ +REACT_APP_BACKEND_URL= http://localhost:4000 \ No newline at end of file diff --git a/Project/frontend/README.md b/Project/frontend/README.md new file mode 100644 index 0000000..58beeac --- /dev/null +++ b/Project/frontend/README.md @@ -0,0 +1,70 @@ +# Getting Started with Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Available Scripts + +In the project directory, you can run: + +### `npm start` + +Runs the app in the development mode.\ +Open [http://localhost:3000](http://localhost:3000) to view it in your browser. + +The page will reload when you make changes.\ +You may also see any lint errors in the console. + +### `npm test` + +Launches the test runner in the interactive watch mode.\ +See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. + +### `npm run build` + +Builds the app for production to the `build` folder.\ +It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.\ +Your app is ready to be deployed! + +See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. + +### `npm run eject` + +**Note: this is a one-way operation. Once you `eject`, you can't go back!** + +If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. + +You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) + +### Analyzing the Bundle Size + +This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) + +### Making a Progressive Web App + +This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) + +### Advanced Configuration + +This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) + +### Deployment + +This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) + +### `npm run build` fails to minify + +This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/Project/frontend/package.json b/Project/frontend/package.json new file mode 100644 index 0000000..1516605 --- /dev/null +++ b/Project/frontend/package.json @@ -0,0 +1,41 @@ +{ + "name": "frontend", + "version": "0.1.0", + "private": true, + "dependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.3.0", + "@testing-library/user-event": "^13.5.0", + "axios": "^0.27.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^5.2.0", + "react-scripts": "5.0.1", + "sweetalert2": "^11.4.29", + "web-vitals": "^2.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/Project/frontend/public/css/app.css b/Project/frontend/public/css/app.css new file mode 100644 index 0000000..e64a596 --- /dev/null +++ b/Project/frontend/public/css/app.css @@ -0,0 +1,49 @@ +html { + box-sizing: border-box; + font-size: 62.5%; +} +*, *:before, *:after { + box-sizing: inherit; +} + +body { + background: #AA076B; + background: -webkit-linear-gradient(to right, #61045F, #AA076B); + background: linear-gradient(to right, #61045F, #AA076B); + font-size: 1.6rem; +} + + +h1 { + text-align: center; + font-family: 'Staatliches', cursive; + color: white; + font-size: 4rem; +} +h2 { + +} +h3 { + font-family: 'Staatliches', cursive; + color:#AA076B; + font-size: 2.4rem; +} +.btn { + font-size:1.4rem; +} +.fecha-alta { + font-family: 'Staatliches', cursive; + color: #AA076B; + font-weight: bold; + font-size: 2rem; +} +.contacto p { + font-size: 1.2rem; + margin: 0; +} +.list-group-item:hover { + background: white; +} +form { + border-radius: .3rem; +} \ No newline at end of file diff --git a/Project/frontend/public/favicon.ico b/Project/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a GIT binary patch literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ literal 0 HcmV?d00001 diff --git a/Project/frontend/public/index.html b/Project/frontend/public/index.html new file mode 100644 index 0000000..42b06e8 --- /dev/null +++ b/Project/frontend/public/index.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#000000" /> + <meta + name="description" + content="Web site created using create-react-app" + /> + <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> + <!-- + manifest.json provides metadata used when your web app is installed on a + user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ + --> + <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> + <!-- + Notice the use of %PUBLIC_URL% in the tags above. + It will be replaced with the URL of the `public` folder during the build. + Only files inside the `public` folder can be referenced from the HTML. + + Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will + work correctly both with client-side routing and a non-root public URL. + Learn how to configure a non-root public URL by running `npm run build`. + --> + <title>Veterinaria</title> + <link href="https://fonts.googleapis.com/css?family=Roboto|Staatliches&display=swap" rel="stylesheet"> + <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> + <link rel="stylesheet" href="/css/app.css"> + </head> + <body> + <noscript>You need to enable JavaScript to run this app.</noscript> + <div id="root"></div> + <!-- + This HTML file is a template. + If you open it directly in the browser, you will see an empty page. + + You can add webfonts, meta tags, or analytics to this file. + The build step will place the bundled scripts into the <body> tag. + + To begin the development, run `npm start` or `yarn start`. + To create a production bundle, use `npm run build` or `yarn build`. + --> + </body> +</html> diff --git a/Project/frontend/public/logo192.png b/Project/frontend/public/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..fc44b0a3796c0e0a64c3d858ca038bd4570465d9 GIT binary patch literal 5347 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 X@eDJUQo;Ye2mwlRs<JiGX2Jghdw)}T literal 0 HcmV?d00001 diff --git a/Project/frontend/public/logo512.png b/Project/frontend/public/logo512.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e47a6545bc15971f8f63fba70e4013df88a664 GIT binary patch literal 9664 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN literal 0 HcmV?d00001 diff --git a/Project/frontend/public/manifest.json b/Project/frontend/public/manifest.json new file mode 100644 index 0000000..080d6c7 --- /dev/null +++ b/Project/frontend/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/Project/frontend/public/robots.txt b/Project/frontend/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/Project/frontend/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/Project/frontend/src/App.js b/Project/frontend/src/App.js new file mode 100644 index 0000000..0ace4b8 --- /dev/null +++ b/Project/frontend/src/App.js @@ -0,0 +1,70 @@ +import React,{useEffect, useState} from 'react' +import {BrowserRouter as Router, Route, Switch} from 'react-router-dom' +import Patients from './components/Patients' +import NewDate from './components/NewDate' +import Meeting from './components/Meeting' +import clientAxios from './config/axios' + + + +function App() { + + //State de la app + + const [meetings, saveMeetings] = useState([]) + const [consult, saveConsult] = useState(true); + + useEffect(()=>{ + if(consult){ + + const checkApi=()=>{ + clientAxios.get('/patients') + .then(response=>{ + // colocar en el state el resultado + saveMeetings(response.data); + + saveConsult(false) + }) + .catch(error=>{ + console.log(error) + }) + } + checkApi() + } + },[consult]) + + console.log(process.env.REACT_APP_BACKEND_URL) + return ( + <Router> + <Switch> + <Route + exact + path="/" + component = {()=><Patients meetings={meetings} />} + /> + <Route + exact + path="/nueva" + component = {()=><NewDate saveConsult={saveConsult}/>} + /> + <Route + exact + path="/cita/:id" + component={(props) =>{ + const meeting = meetings.filter(meeting => meeting._id === props.match.params.id) + return( + <Meeting + meeting={meeting[0]} + saveConsult={saveConsult} + /> + ) + }} + /> + + </Switch> + </Router> + + ); +} + +export default App; diff --git a/Project/frontend/src/components/Meeting.js b/Project/frontend/src/components/Meeting.js new file mode 100644 index 0000000..688d140 --- /dev/null +++ b/Project/frontend/src/components/Meeting.js @@ -0,0 +1,100 @@ +import React ,{Fragment}from 'react' +import {Link, withRouter} from 'react-router-dom' +import clientAxios from '../config/axios' +import Swal from 'sweetalert2'; + +const Meeting = (props) => { + + if(!props.meeting){ + props.history.push('/') + return null; + } + + //extraemos props + const{meeting:{_id,name,owner,date,time,signals,phone}} = props + + const deleteMeeting=id=>{ + + Swal.fire({ + title: 'Estas seguro?', + text: "Una cita eliminada no se puede recuperar!", + icon: 'warning', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: 'Si, Eliminar!' + }).then((result) => { + if (result.isConfirmed) { + Swal.fire( + 'Deleted!', + 'Your file has been deleted.', + 'success' + ) + //Eliminando de la base de datos + clientAxios.delete(`/patients/${id}`) + .then( + response => { + props.saveConsult(true) + console.log(response); + props.history.push('/') + } + ) + + .catch(error=>{ + console.log(error) + }) + } + }) + + + } + return ( + <Fragment> + <h1 className="my-5">Nombre de cita: {props.meeting.name}</h1> + + <div className="container mt-5 py-5"> + <div className="row"> + <div className="col-12 mb-5 d-flex justify-content-center"> + <Link to={'/'} className="btn btn-success text-uppercase py-2 px-5 font-weight-bold">Volver</Link> + + </div> + <div className='col-md-8 mx-auto'> + <div className="p-5 list-group-item list-group-item-action flex-column align-items-center"> + + <div className="d-flex w-100 justify-content-between mb-4"> + + <h3 className="mb-3">{name}</h3> + <small class="fecha-alta"> + {date} - {time} + </small> + + </div> + <p className="mb-0"> + {signals} + </p> + <div className="contacto py-3"> + <p>Dueño: {owner}</p> + <p>Teléfono: {phone}</p> + </div> + <div className="d-flex"> + <button type="button" + className="text-uppercase py-2 px-5 font-weight-bold btn btn-dange col" + onClick={()=> deleteMeeting(_id)} + > + Eliminar × + </button> + + </div> + + + + </div> + + </div> + </div> + </div> + </Fragment> + ); +} + +export default withRouter(Meeting); \ No newline at end of file diff --git a/Project/frontend/src/components/NewDate.js b/Project/frontend/src/components/NewDate.js new file mode 100644 index 0000000..95fef5c --- /dev/null +++ b/Project/frontend/src/components/NewDate.js @@ -0,0 +1,136 @@ +import React, {Fragment, useState} from 'react' +import {Link, withRouter} from 'react-router-dom' +import clientAxios from '../config/axios'; + + +//Los componentes deben comenzar con los nombres en mayúsculas siempre +const NewDate = (props) => { + + + //Generamos el state como objeto + const [meeting, saveMeeting] = useState({ + name: '', + owner: '', + date: '', + time: '', + signals: '', + phone: '' + }); + + //Leer los datos del formulario + const updateState = e =>{ + saveMeeting({ + ...meeting, + [e.target.name] : e.target.value + }) + } + + //Hacemos una petición a la API + const createNewMeeting = e =>{ + e.preventDefault(); + + //enviar petición axios + clientAxios.post('/patients',meeting) + .then(response=>{ + console.log(response); + + }) + + props.saveConsult(true); + //redireccionar + props.history.push('/') + } + + return ( + <Fragment> + <h1 className="my-5">Crear nueva cita</h1> + + <div className="container mt-5 py-5"> + <div className="row"> + <div className="col-12 mb-5 d-flex justify-content-center"> + <Link to={'/'} className="btn btn-success text-uppercase py-2 px-5 font-weight-bold">Volver</Link> + + </div> + <div className="col-md-8 mx-auto"> + <form + onSubmit={createNewMeeting} + className="bg-white p-5 bordered"> + <div className="form-group"> + <label htmlFor="nombre">Nombre Mascota</label> + <input + type="text" + className="form-control form-control-lg" + id="name" + name="name" + placeholder="Nombre Mascota" + onChange={updateState} + /> + </div> + + <div className="form-group"> + <label htmlFor="propietario">Nombre Propietario</label> + <input + type="text" + className="form-control form-control-lg" + id="owner" + name="owner" + placeholder="Nombre Propietario" + onChange={updateState} + /> + </div> + + <div className="form-group"> + <label htmlFor="telefono">Teléfono</label> + <input + type="tel" + className="form-control form-control-lg" + id="phone" + name="phone" + placeholder="Teléfono" + onChange={updateState} + /> + </div> + + <div className="form-group"> + <label htmlFor="fecha">Fecha Alta</label> + <input + type="date" + className="form-control form-control-lg" + id="date" + name="date" + onChange={updateState} + /> + </div> + + <div className="form-group"> + <label htmlFor="hora">Hora Alta</label> + <input + type="time" + className="form-control form-control-lg" + id="time" + name="time" + onChange={updateState} + /> + </div> + + <div className="form-group"> + <label htmlFor="sintomas">Síntomas</label> + <textarea + className="form-control" + name="signals" + rows="6" + onChange={updateState} + ></textarea> + </div> + + + <input type="submit" className="btn btn-primary mt-3 w-100 p-3 text-uppercase font-weight-bold" value="Crear Cita" /> + </form> + </div> + </div> + </div> + </Fragment> + ); +} + +export default withRouter(NewDate); \ No newline at end of file diff --git a/Project/frontend/src/components/Patients.js b/Project/frontend/src/components/Patients.js new file mode 100644 index 0000000..4eb8ebe --- /dev/null +++ b/Project/frontend/src/components/Patients.js @@ -0,0 +1,50 @@ +import React, {Fragment}from 'react' +import {Link} from 'react-router-dom'; +const Patients = ({meetings}) => { + if(meetings.length === 0) return null; + + return ( + //<h1>Correcto</h1> + <Fragment> + <h1 className="my-5">administrador de pacientes</h1> + <div className="container mt-5 py-5"> + <div className="row"> + <div className="col-12 mb-5 d-flex justify-content-center"> + <Link to={'/nueva'} className="btn btn-success text-uppercase py-2 px-5 font-weight-bold">Crear cita</Link> + + </div> + <div className="col-md-8 mx-auto"> + <div className="list-group"> + {meetings.map(meeting =>( + <Link to={`/cita/${meeting._id}`} key={meeting._id} className="p-5 list-group-item list-group-item-action flex-column align-items-start"> + <div className="d-flex w-100 justify-content-between mb-4"> + + <h3 className="mb-3">{meeting.name}</h3> + <small class="fecha-alta"> + {meeting.date} - {meeting.time} + </small> + + </div> + <p className="mb-0"> + {meeting.signals} + </p> + <div className="contacto py-3"> + <p>Dueño: {meeting.owner}</p> + <p>Teléfono: {meeting.phone}</p> + </div> + + </Link> + + ))} + </div> + </div> + </div> + + </div> + </Fragment> + + ) + +} + +export default Patients; \ No newline at end of file diff --git a/Project/frontend/src/config/axios.js b/Project/frontend/src/config/axios.js new file mode 100644 index 0000000..3036777 --- /dev/null +++ b/Project/frontend/src/config/axios.js @@ -0,0 +1,7 @@ +import axios from 'axios'; + +const clientAxios = axios.create({ + baseURL: process.env.REACT_APP_BACKEND_URL +}); + +export default clientAxios; diff --git a/Project/frontend/src/index.js b/Project/frontend/src/index.js new file mode 100644 index 0000000..c3f92cf --- /dev/null +++ b/Project/frontend/src/index.js @@ -0,0 +1,17 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; + +import App from './App'; +import reportWebVitals from './reportWebVitals'; + +const root = ReactDOM.createRoot(document.getElementById('root')); +root.render( + <React.StrictMode> + <App /> + </React.StrictMode> +); + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/Project/frontend/src/reportWebVitals.js b/Project/frontend/src/reportWebVitals.js new file mode 100644 index 0000000..5253d3a --- /dev/null +++ b/Project/frontend/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = onPerfEntry => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/Project/frontend/src/setupTests.js b/Project/frontend/src/setupTests.js new file mode 100644 index 0000000..8f2609b --- /dev/null +++ b/Project/frontend/src/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/Project/index.html b/Project/index.html deleted file mode 100644 index 0fabd60..0000000 --- a/Project/index.html +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Proyectos en JavaScript</title> - -</head> -<body> - -</body> -</html> \ No newline at end of file From f8d43d8a795ca6725bc09fda9183286c6dedaf41 Mon Sep 17 00:00:00 2001 From: hall9zeha <vmwaretars@gmail.com> Date: Mon, 22 Aug 2022 11:40:01 -0500 Subject: [PATCH 3/5] =?UTF-8?q?fixed:=20borrar=20documento=20de=20mongodb?= =?UTF-8?q?=20completa=20y=20redireccionamiento=20usando=20la=20versi?= =?UTF-8?q?=C3=B3n=206.3.0=20de=20react-router-dom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project/API/controllers/patientController.js | 1 + Project/API/routes/index.js | 2 +- Project/frontend/package.json | 3 +- Project/frontend/src/App.js | 35 +++++++++------- Project/frontend/src/components/Meeting.js | 44 ++++++++++++++------ Project/frontend/src/components/NewDate.js | 25 +++++++++-- 6 files changed, 78 insertions(+), 32 deletions(-) diff --git a/Project/API/controllers/patientController.js b/Project/API/controllers/patientController.js index 402a867..e0d69c4 100644 --- a/Project/API/controllers/patientController.js +++ b/Project/API/controllers/patientController.js @@ -59,6 +59,7 @@ exports.updatePatient = async(req,res,next) =>{ } exports.deletePatient = async(req,res,next) =>{ try { + await Patient.findByIdAndDelete({_id : req.params.id}); res.json({message: 'El registro fue eliminado'}); } catch (error) { diff --git a/Project/API/routes/index.js b/Project/API/routes/index.js index db8b5aa..be18095 100644 --- a/Project/API/routes/index.js +++ b/Project/API/routes/index.js @@ -20,7 +20,7 @@ module.exports = function() { patientController.updatePatient ) //Eliminar pacient por id - router.delete('patients/:id', + router.delete('/patients/:id', patientController.deletePatient ) return router; diff --git a/Project/frontend/package.json b/Project/frontend/package.json index 1516605..9b654ea 100644 --- a/Project/frontend/package.json +++ b/Project/frontend/package.json @@ -2,6 +2,7 @@ "name": "frontend", "version": "0.1.0", "private": true, + "dependencies": { "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.3.0", @@ -9,7 +10,7 @@ "axios": "^0.27.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router-dom": "^5.2.0", + "react-router-dom": "^6.3.0", "react-scripts": "5.0.1", "sweetalert2": "^11.4.29", "web-vitals": "^2.1.4" diff --git a/Project/frontend/src/App.js b/Project/frontend/src/App.js index 0ace4b8..90db76a 100644 --- a/Project/frontend/src/App.js +++ b/Project/frontend/src/App.js @@ -1,5 +1,5 @@ -import React,{useEffect, useState} from 'react' -import {BrowserRouter as Router, Route, Switch} from 'react-router-dom' +import React,{useEffect, useState, } from 'react' +import {BrowserRouter as Router, Route, Routes, useParams} from 'react-router-dom' import Patients from './components/Patients' import NewDate from './components/NewDate' import Meeting from './components/Meeting' @@ -34,37 +34,42 @@ function App() { },[consult]) console.log(process.env.REACT_APP_BACKEND_URL) + + + let MeetingRoute = () => { + const props=useParams() + + const meeting = meetings.filter(meeting => meeting._id === props.id) + return ( + <Meeting + meeting={meeting[0]} + saveConsult={saveConsult} /> + ); + }; return ( <Router> - <Switch> + <Routes> <Route exact path="/" - component = {()=><Patients meetings={meetings} />} + element = {<Patients meetings={meetings} />} /> <Route exact path="/nueva" - component = {()=><NewDate saveConsult={saveConsult}/>} + element = {<NewDate saveConsult={saveConsult}/>} /> <Route exact path="/cita/:id" - component={(props) =>{ - const meeting = meetings.filter(meeting => meeting._id === props.match.params.id) - return( - <Meeting - meeting={meeting[0]} - saveConsult={saveConsult} - /> - ) - }} + element={<MeetingRoute/>} /> - </Switch> + </Routes> </Router> ); + } export default App; diff --git a/Project/frontend/src/components/Meeting.js b/Project/frontend/src/components/Meeting.js index 688d140..fcdd4ff 100644 --- a/Project/frontend/src/components/Meeting.js +++ b/Project/frontend/src/components/Meeting.js @@ -1,20 +1,41 @@ import React ,{Fragment}from 'react' -import {Link, withRouter} from 'react-router-dom' +import {Link, useNavigate, useLocation, useParams} from 'react-router-dom' import clientAxios from '../config/axios' import Swal from 'sweetalert2'; +let navigate; +function withRouter(Component) { + function ComponentWithRouterProp(props) { + let location = useLocation(); + navigate = useNavigate(); + let params = useParams(); + return ( + <Component + {...props} + router={{ location, navigate, params }} + /> + ); + } + + return ComponentWithRouterProp; + } + const Meeting = (props) => { + if(!props.meeting){ - props.history.push('/') + //props.history.push('/') + //para las nuevas versiones de react + navigate('/') return null; } - + console.log(props) + //extraemos props const{meeting:{_id,name,owner,date,time,signals,phone}} = props - - const deleteMeeting=id=>{ - + + const deleteMeeting = id =>{ + Swal.fire({ title: 'Estas seguro?', text: "Una cita eliminada no se puede recuperar!", @@ -31,12 +52,13 @@ const Meeting = (props) => { 'success' ) //Eliminando de la base de datos - clientAxios.delete(`/patients/${id}`) - .then( + //clientAxios.delete(`/patients/${id}`) + clientAxios.delete("/patients/"+id) + .then( response => { props.saveConsult(true) console.log(response); - props.history.push('/') + navigate('/') } ) @@ -78,7 +100,7 @@ const Meeting = (props) => { </div> <div className="d-flex"> <button type="button" - className="text-uppercase py-2 px-5 font-weight-bold btn btn-dange col" + className="text-uppercase py-2 px-5 font-weight-bold btn btn-danger col" onClick={()=> deleteMeeting(_id)} > Eliminar × @@ -86,8 +108,6 @@ const Meeting = (props) => { </div> - - </div> </div> diff --git a/Project/frontend/src/components/NewDate.js b/Project/frontend/src/components/NewDate.js index 95fef5c..c19db1a 100644 --- a/Project/frontend/src/components/NewDate.js +++ b/Project/frontend/src/components/NewDate.js @@ -1,12 +1,29 @@ import React, {Fragment, useState} from 'react' -import {Link, withRouter} from 'react-router-dom' +import {Link, useNavigate, useLocation, useParams} from 'react-router-dom' import clientAxios from '../config/axios'; +let navigate; +function withRouter(Component) { + + function ComponentWithRouterProp(props) { + let location = useLocation(); + navigate = useNavigate(); + let params = useParams(); + return ( + <Component + {...props} + router={{ location, navigate, params }} + /> + ); + } + + return ComponentWithRouterProp; + } //Los componentes deben comenzar con los nombres en mayúsculas siempre const NewDate = (props) => { - + //Generamos el state como objeto const [meeting, saveMeeting] = useState({ name: '', @@ -38,7 +55,9 @@ const NewDate = (props) => { props.saveConsult(true); //redireccionar - props.history.push('/') + //props.history.push('/') + //par las nuevas versiones de react + navigate('/'); } return ( From 77fd749101ca1112e77dd914d34b1f905f58c10d Mon Sep 17 00:00:00 2001 From: hall9zeha <vmwaretars@gmail.com> Date: Mon, 22 Aug 2022 14:54:51 -0500 Subject: [PATCH 4/5] =?UTF-8?q?versi=C3=B3n=20de=20escritorio=20con=20elec?= =?UTF-8?q?tr=C3=B3n=20a=C3=B1adida,=20solo=20mostrar=20citas=20de=20veter?= =?UTF-8?q?inaria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project/.gitignore | 2 ++ Project/Desktop/css/app.css | 49 +++++++++++++++++++++++++++++++++++ Project/Desktop/icon.png | Bin 0 -> 18543 bytes Project/Desktop/index.html | 31 ++++++++++++++++++++++ Project/Desktop/index.js | 35 +++++++++++++++++++++++++ Project/Desktop/js/app.js | 35 +++++++++++++++++++++++++ Project/Desktop/package.json | 16 ++++++++++++ Project/README.md | 13 +++++++++- 8 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 Project/Desktop/css/app.css create mode 100644 Project/Desktop/icon.png create mode 100644 Project/Desktop/index.html create mode 100644 Project/Desktop/index.js create mode 100644 Project/Desktop/js/app.js create mode 100644 Project/Desktop/package.json diff --git a/Project/.gitignore b/Project/.gitignore index 1d05cc5..f30b7b1 100644 --- a/Project/.gitignore +++ b/Project/.gitignore @@ -2,6 +2,8 @@ API/node_modules API/package-lock.json frontend/node_modules frontend/package-lock.json +Desktop/node_modules +Desktop/package-lock.json # testing /coverage diff --git a/Project/Desktop/css/app.css b/Project/Desktop/css/app.css new file mode 100644 index 0000000..e64a596 --- /dev/null +++ b/Project/Desktop/css/app.css @@ -0,0 +1,49 @@ +html { + box-sizing: border-box; + font-size: 62.5%; +} +*, *:before, *:after { + box-sizing: inherit; +} + +body { + background: #AA076B; + background: -webkit-linear-gradient(to right, #61045F, #AA076B); + background: linear-gradient(to right, #61045F, #AA076B); + font-size: 1.6rem; +} + + +h1 { + text-align: center; + font-family: 'Staatliches', cursive; + color: white; + font-size: 4rem; +} +h2 { + +} +h3 { + font-family: 'Staatliches', cursive; + color:#AA076B; + font-size: 2.4rem; +} +.btn { + font-size:1.4rem; +} +.fecha-alta { + font-family: 'Staatliches', cursive; + color: #AA076B; + font-weight: bold; + font-size: 2rem; +} +.contacto p { + font-size: 1.2rem; + margin: 0; +} +.list-group-item:hover { + background: white; +} +form { + border-radius: .3rem; +} \ No newline at end of file diff --git a/Project/Desktop/icon.png b/Project/Desktop/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3ee985ec9e3d755e053e7220d7fd84f6d2fb35e3 GIT binary patch literal 18543 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%0A65|eiU{e9PIq$h7b5K= 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 literal 0 HcmV?d00001 diff --git a/Project/Desktop/index.html b/Project/Desktop/index.html new file mode 100644 index 0000000..28cbad7 --- /dev/null +++ b/Project/Desktop/index.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html lang="en"> + + <head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta http-equiv="Content-Security-Policy" content="script-src 'self';"> + <meta http-equiv="X-UA-Compatible"FORM content="ie=edge"> + <title>Pacientes Veterinaria</title> + <link href="https://fonts.googleapis.com/css?family=Roboto|Staatliches&display=swap" rel="stylesheet"> + <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> + <link rel="stylesheet" href="css/app.css"> + </head> + + <body> + <h1>Administrador de Pacientes Veterinaria</h1> + <div class="container mt-5"> + <div class="row"> + <div class="col-md-8 mx-auto"> + <div id="meetings" class="list-group"> + <!-- AGREGAR CITAS AQUI --> + </div> + </div> + </div> + </div> + + <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script> + <script src="js/app.js"></script> + </body> + +</html> \ No newline at end of file diff --git a/Project/Desktop/index.js b/Project/Desktop/index.js new file mode 100644 index 0000000..3781db9 --- /dev/null +++ b/Project/Desktop/index.js @@ -0,0 +1,35 @@ +const {app, BrowserWindow} = require('electron'); + +let appWindow; + +function createWindow(){ + appWindow = new BrowserWindow({ + //Podemos definir el tamaño de la ventana de la aplicación + width: 1000, + height:600, + center:true, + show:false, + //le ponemos un ícono a la aplicación + icon:'icon.png' + //podriamos evitar que el usuario redimencione la pantalla con + //resizable:false + //También podemos limitar un mínimo redimensionable de altura y anchura + //min-width:600, + //min-height:700 + }); + + //Cuando la aplicación es cerrada liberamos los recursos de memoria + appWindow.on('closed', () =>{ + appWindow=null; + }); + + //Cargar html + appWindow.loadFile('./index.html') + + //Cuando la app esté lista, mostrar la ventana + appWindow.once('ready-to-show', ()=>{ + appWindow.show(); + }) +} + +app.on('ready',createWindow); \ No newline at end of file diff --git a/Project/Desktop/js/app.js b/Project/Desktop/js/app.js new file mode 100644 index 0000000..01262fe --- /dev/null +++ b/Project/Desktop/js/app.js @@ -0,0 +1,35 @@ +fetch ('http://localhost:4000/patients') + .then(response => response.json()) + .then(data => showMeetings(data)); + +console.log('Hola ') +function showMeetings(meetings){ + const contentMeetings = document.querySelector('#meetings'); + + let meetingsHtml = ''; + + meetings.forEach(meeting =>{ + meetingsHtml +=` + <div class="p-5 list-group-item list-group-item-action flex-column align-items-start"> + <div class="d-flex w-100 justify-content-between mb-4"> + + <h3 class="mb-3">${meeting.name}</h3> + <small class="fecha-alta"> + ${meeting.date} - ${meeting.time} + </small> + + </div> + <p class="mb-0"> + ${meeting.signals} + </p> + <div class="contacto py-3"> + <p>Dueño: ${meeting.owner}</p> + <p>Teléfono: ${meeting.phone}</p> + </div> + + </div> + `; + }); + + contentMeetings.innerHTML=meetingsHtml; +} \ No newline at end of file diff --git a/Project/Desktop/package.json b/Project/Desktop/package.json new file mode 100644 index 0000000..e0efbb0 --- /dev/null +++ b/Project/Desktop/package.json @@ -0,0 +1,16 @@ +{ + "name": "fullstack_js_desktop", + "version": "1.0.0", + "description": "La misma aplicación pero desarrollada en electrón para escritorio", + "main": "index.js", + "scripts": { + "start": "electron .", + "dist": "electron-builder -l" + }, + "author": "Barry Zea H.", + "license": "ISC", + "devDependencies": { + "electron": "^20.0.3", + "electron-builder": "^23.3.3" + } +} diff --git a/Project/README.md b/Project/README.md index 81caa99..0c2f46f 100644 --- a/Project/README.md +++ b/Project/README.md @@ -20,4 +20,15 @@ - ``` npm install react-router-dom ``` - ``` npm install cors ``` -- ``` npm install sweetalert2 ``` \ No newline at end of file +- ``` npm install sweetalert2 ``` + +# Desktop + +- Inicializamos ``` npm init ``` dentro de la carpeta "Desktop" +- Luego instalamos electrón ``` npm i -D electron@latest ``` +- Instalamos una dependencia para crear los instalables en electrón + -``` npm install --save-dev electron-builder ``` + - Luego en package.json añadir el script: + - "dist": "electron-builder -l" + - En mi caso crearé un instalable para linux con la bandera "-l", (para windows: "-w" y para Mac " -m") +- Finalmente ejecutar ``` npm run dist ``` \ No newline at end of file From a2a3bfa698a3d699bd2a14a1a8b80e431d61ac3c Mon Sep 17 00:00:00 2001 From: hall9zeha <vmwaretars@gmail.com> Date: Mon, 22 Aug 2022 15:54:04 -0500 Subject: [PATCH 5/5] =?UTF-8?q?Reutilizamos=20nuestro=20c=C3=B3digo=20de?= =?UTF-8?q?=20frontend=20para=20convertirlo=20con=20electron=20en=20una=20?= =?UTF-8?q?app=20de=20escritorio,=20proyectos=20finalizados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project/Desktop/index.js | 4 +-- Project/README.md | 18 ++++++++++-- Project/frontend/package.json | 22 ++++++++++---- Project/frontend/public/electron.js | 43 ++++++++++++++++++++++++++++ Project/frontend/public/icon.png | Bin 0 -> 18543 bytes 5 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 Project/frontend/public/electron.js create mode 100644 Project/frontend/public/icon.png diff --git a/Project/Desktop/index.js b/Project/Desktop/index.js index 3781db9..2e5698e 100644 --- a/Project/Desktop/index.js +++ b/Project/Desktop/index.js @@ -14,8 +14,8 @@ function createWindow(){ //podriamos evitar que el usuario redimencione la pantalla con //resizable:false //También podemos limitar un mínimo redimensionable de altura y anchura - //min-width:600, - //min-height:700 + //minWidth:600, + //minHeight:700 }); //Cuando la aplicación es cerrada liberamos los recursos de memoria diff --git a/Project/README.md b/Project/README.md index 0c2f46f..ac8886e 100644 --- a/Project/README.md +++ b/Project/README.md @@ -25,10 +25,22 @@ # Desktop - Inicializamos ``` npm init ``` dentro de la carpeta "Desktop" -- Luego instalamos electrón ``` npm i -D electron@latest ``` -- Instalamos una dependencia para crear los instalables en electrón +- Luego instalamos electron ``` npm i -D electron@latest ``` +- Instalamos una dependencia para crear los instalables en electron -``` npm install --save-dev electron-builder ``` - Luego en package.json añadir el script: - "dist": "electron-builder -l" - En mi caso crearé un instalable para linux con la bandera "-l", (para windows: "-w" y para Mac " -m") -- Finalmente ejecutar ``` npm run dist ``` \ No newline at end of file +- Finalmente ejecutar ``` npm run dist ``` + +## Usar el proyecto de Frontend con electron + +nos ubicamos en la carpeta raiz del "frontend" e instalamos unas dependencias: +- ``` npm install --save cross-env electron-is-dev ```, nos permitirá saber en que entorno estamos, si es de desarrollo o de producción. + +- ``` npm install concurrently wait-on electron electron-builder typescript ``` + * ```concurrently``` para ejecutar dos o mas comandos a la vez + * ```wait-on``` para esperar a que el host esté activo y ejecutar todo lo demás + * ```electron ``` para crear la app de escritorio + * ```electron-builder``` para crear los instalables + * ```typescript``` porque es una dependencia exigida por electron diff --git a/Project/frontend/package.json b/Project/frontend/package.json index 9b654ea..099cafb 100644 --- a/Project/frontend/package.json +++ b/Project/frontend/package.json @@ -2,25 +2,37 @@ "name": "frontend", "version": "0.1.0", "private": true, - "dependencies": { "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^13.5.0", "axios": "^0.27.2", + "concurrently": "^7.3.0", + "cross-env": "^7.0.3", + "electron": "^20.0.3", + "electron-builder": "^23.3.3", + "electron-is-dev": "^2.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.3.0", "react-scripts": "5.0.1", "sweetalert2": "^11.4.29", + "typescript": "^4.7.4", + "wait-on": "^6.0.1", "web-vitals": "^2.1.4" }, "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" + "react-start": "react-scripts start", + "react-build": "react-scripts build", + "react-test": "react-scripts test --env=jsdom", + "react-eject": "react-scripts eject", + "electron-build": "electron-builder", + "release": "yarn react-build && electron-builder --publish=always", + "build": "yarn react-build && yarn electron-build", + "start": "concurrently \"cross-env BROWSER=none npm run react-start\" \"wait-on http://localhost:3000 && electron .\"" }, + "main":"public/electron.js", + "homepage":"./", "eslintConfig": { "extends": [ "react-app", diff --git a/Project/frontend/public/electron.js b/Project/frontend/public/electron.js new file mode 100644 index 0000000..157ba2b --- /dev/null +++ b/Project/frontend/public/electron.js @@ -0,0 +1,43 @@ +const {app, BrowserWindow } = require('electron'); +const path= require('path'); +const isDev = require('electron-is-dev'); + +let appWindow; + +function createWindow(){ + + appWindow = new BrowserWindow({ + width:1000, + height:600, + center:true, + resizable:true, + minWidth:600, + minHeight:400, + show:false, + icon:'icon.png' + }) + appWindow.loadURL( + isDev + ? 'http://localhost:3000' + :`file://${path.join(__dirname,"../build/index.html")}` + + ); + + appWindow.once('ready-to-show',()=>{ + appWindow.show(); + }) +} + +app.on('ready',createWindow); + +app.on('window-all-closed',()=>{ + if(process.platform !== 'darwin'){ + app.quit(); + } +}) + +app.on('activate',()=>{ + if(appWindow === null){ + createWindow(); + } +}) \ No newline at end of file diff --git a/Project/frontend/public/icon.png b/Project/frontend/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3ee985ec9e3d755e053e7220d7fd84f6d2fb35e3 GIT binary patch literal 18543 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%0A65|eiU{e9PIq$h7b5K= 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 literal 0 HcmV?d00001