Skip to content

Commit

Permalink
implement create contract beetwen landlord and tenatn b00tc4mp#85
Browse files Browse the repository at this point in the history
  • Loading branch information
MatiasSargo committed Aug 26, 2024
1 parent eab25bd commit fa4338a
Show file tree
Hide file tree
Showing 40 changed files with 948 additions and 238 deletions.
15 changes: 15 additions & 0 deletions staff/matias-sargo/project/api/handlers/createContractHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { logic } from '../../cor/index.js';

export default (req, res, next) => {
const { userId } = req; // Asumiendo que el `userId` está incluido en el token JWT y fue verificado por el middleware.

const { propertyId, ownerId, tenantId, startDate, endDate, price } = req.body;

try {
logic.createContract(propertyId, ownerId || userId, tenantId, startDate, endDate, price) // Usa `ownerId` del cuerpo, pero si no está presente, usa `userId`.
.then(() => res.status(201).send())
.catch(error => next(error));
} catch (error) {
next(error);
}
};
6 changes: 3 additions & 3 deletions staff/matias-sargo/project/api/handlers/createPropHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { logic } from '../../cor/index.js';
export default (req, res, next) => {
const { userId } = req;

const { images, title, description, latitude, longitude, price, type } = req.body;
const { images, title, description, address, latitude, longitude, price, type } = req.body;

try {
logic.createProp(userId, images, title, description, latitude, longitude, price, type)
logic.createProp(userId, images, title, description, address, latitude, longitude, price, type)
.then(() => res.status(201).send())
.catch(error => next(error));
} catch (error) {
next(error);
}
};
};
12 changes: 6 additions & 6 deletions staff/matias-sargo/project/api/handlers/getAllPropsHandler.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { logic } from '../../cor/index.js'
import { logic } from '../../cor/index.js';

export default (req, res, next) => {
const { userId } = req
const { userId } = req;

try {
logic.getAllProps(userId)
.then(events => res.json(events))
.catch(error => next(error))
.then(properties => res.json(properties)) // Cambia 'events' por 'properties' para mayor claridad
.catch(error => next(error));
} catch (error) {
next(error)
next(error);
}
}
};
4 changes: 3 additions & 1 deletion staff/matias-sargo/project/api/handlers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import registerUserHandler from '../handlers/registerUserHandler.js'
import authenticateUserHandler from '../handlers/authenticateUserHandler.js'
import createPropHandler from '../handlers/createPropHandler.js'
import getAllPropsHandler from '../handlers/getAllPropsHandler.js'
import createContractHandler from './createContractHandler.js'

export {
registerUserHandler,
authenticateUserHandler,
createPropHandler,
getAllPropsHandler
getAllPropsHandler,
createContractHandler

}
12 changes: 6 additions & 6 deletions staff/matias-sargo/project/api/handlers/registerUserHandler.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { logic } from '../../cor/index.js'
import { logic } from '../../cor/index.js';

export default (req, res, next) => {
const { name, surname, email, username, dni, password, passwordRepeat } = req.body
const { name, surname, email, username, dni, password, passwordRepeat, role } = req.body;

try {
logic.registerUser(name, surname, email, username, dni, password, passwordRepeat)
logic.registerUser(name, surname, email, username, dni, password, passwordRepeat, role)
.then(() => res.status(201).send())
.catch(error => next(error))
.catch(error => next(error));
} catch (error) {
next(error)
next(error);
}
}
};
5 changes: 4 additions & 1 deletion staff/matias-sargo/project/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
registerUserHandler,
authenticateUserHandler,
createPropHandler,
getAllPropsHandler
getAllPropsHandler,
createContractHandler
} from './handlers/index.js';

mongoose.connect(process.env.MONGODB_URI)
Expand All @@ -27,6 +28,8 @@ mongoose.connect(process.env.MONGODB_URI)
api.post('/properties', jsonBodyParser, jwtVerifier, createPropHandler);
api.get('/properties', jwtVerifier, getAllPropsHandler)

api.post('/contracts', jsonBodyParser, jwtVerifier, createContractHandler);

api.use(errorHandler);

api.listen(process.env.PORT, () => console.info(`API listening on PORT ${process.env.PORT}`));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curl -v http://localhost:8080/users/auth -X POST -d '{"username":"matsarg","password":"123123123"}' -H "Content-Type: application/json"
11 changes: 11 additions & 0 deletions staff/matias-sargo/project/api/test/create-contract.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
curl -X POST http://localhost:8080/contracts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmNjOTUyM2ZjOTY2NDc5NWFlNWMzOTIiLCJpYXQiOjE3MjQ2ODQyMzV9.2k87e-M8OeRb1t6lElneipBAslBty8c2aftFrBQl13k" \
-d '{
"propertyId": "66cc971efc9664795ae5c396",
"ownerId": "66cc9523fc9664795ae5c392",
"tenantId": "66cc36e584c8d8294429e65a",
"startDate": "2024-09-01T00:00:00.000Z",
"endDate": "2025-09-01T00:00:00.000Z",
"price": 1200
}'
5 changes: 3 additions & 2 deletions staff/matias-sargo/project/api/test/create-prop.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
curl -X POST http://localhost:8080/properties \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmM0NTY4OWVjZDY2MjNjYmM5ZTA2YzAiLCJpYXQiOjE3MjQyNDUwMDJ9.ZyH0N7naSi4LO8DL8xCOnY_s65DLBxrkuSCslIzXXww" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmNjOTUyM2ZjOTY2NDc5NWFlNWMzOTIiLCJpYXQiOjE3MjQ2ODM2MDN9.zjb08W1WRnPJ5yYN2I4s4tCfII-92eNBOoQevj6krB0" \
-d '{
"title": "Beautiful apartment in the city center",
"images": ["https://example.com/image1.jpg", "https://example.com/image2.jpg"],
"description": "This is a beautiful apartment located in the heart of the city.",
"address": "123 Main St, New York, NY",
"latitude": 40.7128,
"longitude": -74.0060,
"price": 2500,
"type": "apartment"
}'
}'
2 changes: 1 addition & 1 deletion staff/matias-sargo/project/api/test/get-all-props.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
curl -v http://localhost:8080/properties -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmM0NTY4OWVjZDY2MjNjYmM5ZTA2YzAiLCJpYXQiOjE3MjQyNDUwMDJ9.ZyH0N7naSi4LO8DL8xCOnY_s65DLBxrkuSCslIzXXww"
curl -v http://localhost:8080/properties -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmNjMzZlNTg0YzhkODI5NDQyOWU2NWEiLCJpYXQiOjE3MjQ2NjA2Mjl9.VTo9ZTzTAMb414MxOyYsJ2QaiZDawSGtmFDaM2faI94"
1 change: 1 addition & 0 deletions staff/matias-sargo/project/api/test/register-landlord.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curl -v http://localhost:8080/users -X POST -d '{"name":"mat","surname":"sarg","email":"[email protected]","username":"matsarg","dni": "y12345612b", "password":"123123123","passwordRepeat":"123123123", "role": "landlord"}' -H "Content-Type: application/json"
2 changes: 1 addition & 1 deletion staff/matias-sargo/project/api/test/register-user.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
curl -v http://localhost:8080/users -X POST -d '{"name":"Peter","surname":"Pan","email":"[email protected]","username":"peterpan","dni": "y12345612v", "password":"123123123","passwordRepeat":"123123123"}' -H "Content-Type: application/json"
curl -v http://localhost:8080/users -X POST -d '{"name":"Peter","surname":"Pan","email":"[email protected]","username":"peterpan","dni": "y12345612v", "password":"123123123","passwordRepeat":"123123123", "role": "tenant"}' -H "Content-Type: application/json"
41 changes: 41 additions & 0 deletions staff/matias-sargo/project/app/logic/createContract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export default (propertyId, ownerId, tenantId, startDate, endDate, price) => {
// Validaciones
validate.string(propertyId, 'propertyId');
validate.string(ownerId, 'ownerId');
validate.string(tenantId, 'tenantId');
validateDate(startDate, 'startDate');
validateDate(endDate, 'endDate');
validate.number(price, 'price');

return fetch(`${import.meta.env.VITE_API_URL}/contracts`, {
method: 'POST',
headers: {
Authorization: `Bearer ${sessionStorage.token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
propertyId,
ownerId,
tenantId,
startDate,
endDate,
price,
}),
})
.catch(error => {
throw new SystemError(error.message);
})
.then(response => {
const { status } = response;

if (status === 201) return;

return response.json().then(body => {
const { error, message } = body;

const constructor = errors[error];

throw new constructor(message);
});
});
};
8 changes: 6 additions & 2 deletions staff/matias-sargo/project/app/logic/createProp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { validate, errors } from '../../com/index.js';

const { SystemError } = errors;

export default (images, description, latitude, longitude, price, type) => {
export default (images, title, description, address, latitude, longitude, price, type) => {
// Validaciones
validate.array(images, validate.url, 'images'); // Asegura que 'images' sea un array de URLs válidos
validate.string(title, 'title'); // Asegura que 'title' sea un string válido
validate.string(description, 'description');
validate.string(address, 'address'); // Asegura que 'address' sea un string válido
validate.latitude(latitude, 'latitude');
validate.longitude(longitude, 'longitude');
validate.number(price, 'price');
Expand All @@ -20,7 +22,9 @@ export default (images, description, latitude, longitude, price, type) => {
},
body: JSON.stringify({
images,
title,
description,
address,
location: { type: 'Point', coordinates: [longitude, latitude] }, // Formato GeoJSON para la ubicación
price,
type,
Expand All @@ -42,4 +46,4 @@ export default (images, description, latitude, longitude, price, type) => {
throw new constructor(message); // Lanza un error personalizado basado en la respuesta del servidor
});
});
};
};
35 changes: 19 additions & 16 deletions staff/matias-sargo/project/app/logic/getAllProps.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
import { errors } from '../../com/index.js'
import { errors } from '../../com/index.js';

const { SystemError } = errors
const { SystemError } = errors;

export default () => {
return fetch(`${import.meta.env.VITE_API_URL}/properties`, {
headers: {
Authorization: `Bearer ${sessionStorage.token}`
}
Authorization: `Bearer ${sessionStorage.token}`,
'Content-Type': 'application/json', // Especifica el tipo de contenido
},
})
.catch(error => { throw new SystemError(error.message) })
.catch(error => {
throw new SystemError(error.message); // Manejo de errores del sistema
})
.then(response => {
const { status } = response
const { status } = response;

if (status === 200)
if (status === 200) {
return response.json()
.then(events => events)
.then(properties => properties); // Devuelve las propiedades si la solicitud es exitosa
}

return response.json()
.then(body => {
const { error, message } = body
return response.json().then(body => {
const { error, message } = body;

const constructor = errors[error]
const constructor = errors[error]; // Obtiene el constructor del error correspondiente

throw new constructor(message)
})
})
}
throw new constructor(message); // Lanza un error personalizado basado en la respuesta del servidor
});
});
};
5 changes: 4 additions & 1 deletion staff/matias-sargo/project/app/logic/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import isUserLoggedIn from './isUserLoggedIn.js'
import createProp from './createProp.js'
import getUserId from './getUserId.js'
import getAllProps from './getAllProps.js'
import createContract from './createContract.js'


const logic = {

Expand All @@ -12,7 +14,8 @@ const logic = {
isUserLoggedIn,
createProp,
getUserId,
getAllProps
getAllProps,
createContract

}

Expand Down
52 changes: 27 additions & 25 deletions staff/matias-sargo/project/app/logic/registerUser.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
import { validate, errors } from 'com'
import { validate, errors } from 'com';

const { SystemError } = errors
const { SystemError } = errors;

export default (name, surname, email, username, dni, password, passwordRepeat) => {
validate.name(name)
validate.name(surname, 'surname')
validate.email(email)
validate.username(username)
validate.string(dni)
validate.password(password)
validate.password(passwordRepeat, 'passwordRepeat')
export default (name, surname, email, username, dni, password, passwordRepeat, role = 'tenant') => {
validate.name(name);
validate.name(surname, 'surname');
validate.email(email);
validate.username(username);
validate.string(dni);
validate.password(password);
validate.password(passwordRepeat, 'passwordRepeat');

if (password !== passwordRepeat) throw new ValidationError('Passwords do not match');

return fetch(`${import.meta.env.VITE_API_URL}/users`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, surname, email, username, dni, password, passwordRepeat })
body: JSON.stringify({ name, surname, email, username, dni, password, role }), // Asegúrate de incluir el rol en el cuerpo de la solicitud
})
.catch(error => { throw new SystemError(error.message) })
.then(response => {
const { status } = response

if (status === 201) return
.catch((error) => {
throw new SystemError(error.message);
})
.then((response) => {
const { status } = response;

return response.json()
.then(body => {
const { error, message } = body
if (status === 201) return; // Usuario registrado con éxito

const constructor = errors[error]
return response.json().then((body) => {
const { error, message } = body;
const constructor = errors[error];

throw new constructor(message)
})
})
}
throw new constructor(message);
});
});
};
6 changes: 6 additions & 0 deletions staff/matias-sargo/project/app/util/formatDate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
23 changes: 23 additions & 0 deletions staff/matias-sargo/project/app/util/formatTime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default function formatTime(date) {
const seconds = Math.round((Date.now() - date.getTime()) / 1000)
if (seconds < 60) return seconds + ' second' + (seconds === 1 ? '' : 's')

const minutes = Math.round(seconds / 60)
if (minutes < 60) return minutes + ' minute' + (minutes === 1 ? '' : 's')

const hours = Math.round(minutes / 60)
if (hours < 24) return hours + ' hour' + (hours === 1 ? '' : 's')

const days = Math.round(hours / 24)
if (days < 7) return days + ' day' + (days === 1 ? '' : 's')

const weeks = Math.round(days / 7)
if (weeks < 4) return weeks + ' week' + (weeks === 1 ? '' : 's')

const months = Math.round(weeks / 4)
if (months < 12) return months + ' month' + (months === 1 ? '' : 's')

const years = Math.round(months / 12)

return years + ' year' + (years === 1 ? '' : 's')
}
Loading

0 comments on commit fa4338a

Please sign in to comment.