Merge branch 'dev' into US-42-EliminarInquilino

This commit is contained in:
Mariela 2022-08-21 23:17:02 -06:00
commit 64097d735e
55 changed files with 23939 additions and 25951 deletions

BIN
.DS_Store vendored

Binary file not shown.

12
.envrc Normal file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env bash
# ^ added for shellcheck and file-type detection
# Watch & reload direnv on change
watch_file devshell.toml
if [[ $(type -t use_flake) != function ]]; then
echo "ERROR: use_flake function missing."
echo "Please update direnv to v2.30.0 or later."
exit 1
fi
use flake

15
.expo/README.md Normal file
View File

@ -0,0 +1,15 @@
> Why do I have a folder named ".expo" in my project?
The ".expo" folder is created when an Expo project is started using "expo start" command.
> What do the files contain?
- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
- "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.
- "settings.json": contains the server configuration that is used to serve the application manifest.
> Should I commit the ".expo" folder?
No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
Upon project creation, the ".expo" folder is already added to your ".gitignore" file.

8
.expo/settings.json Normal file
View File

@ -0,0 +1,8 @@
{
"hostType": "lan",
"lanType": "ip",
"dev": true,
"minify": false,
"urlRandomness": null,
"https": false
}

View File

@ -29,22 +29,3 @@ jobs:
cd ./api-gateway cd ./api-gateway
npm ci npm ci
npm run build --if-present npm run build --if-present
build-web:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: checkout
uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Test
run: |
cd ./web-ui/web-react/
npm ci
npm run build --if-present

View File

@ -1,4 +1,4 @@
import { Controller, Get, Post, Body, Param, Delete } from '@nestjs/common'; import { Controller, Get, Post, Put, Body, Param, Delete } from '@nestjs/common';
import { AppService } from './app.service'; import { AppService } from './app.service';
@Controller() @Controller()
export class AppController { export class AppController {
@ -80,6 +80,33 @@ export class AppController {
); );
} }
@Put('user/updateUser')
updateUser(
@Body('dni') dni: string,
@Body('name') name: string,
@Body('last_name') last_name: string,
@Body('email') email: string,
@Body('phone') phone: number,
@Body('password') password: string,
@Body('user_type') user_type: string,
@Body('status') status: string,
@Body('date_entry') date_entry: Date,
@Body('community_id') community_id: string,
) {
return this.appService.updateUser(
dni,
name,
last_name,
email,
phone,
password,
user_type,
status,
date_entry,
community_id,
);
}
@Get('user/allUsers') @Get('user/allUsers')
allUsers() { allUsers() {
return this.appService.allUsers(); return this.appService.allUsers();
@ -128,6 +155,16 @@ export class AppController {
return this.appService.deleteAdminSystem(id); return this.appService.deleteAdminSystem(id);
} }
@Delete('user/deleteAdminCommunity/:id')
deleteAdminCommunity(@Param('id') id: string) {
return this.appService.deleteAdminCommunity(id);
}
@Delete('user/deleteTenant/:id')
deleteTenant(@Param('id') id: string) {
return this.appService.deleteTenant(id);
}
@Post('user/changeStatus') @Post('user/changeStatus')
changeStatusUser( changeStatusUser(
@Body('id') pId: string, @Body('id') pId: string,
@ -188,6 +225,8 @@ export class AppController {
) { ) {
return this.appService.changeStatusCommunity(pId, pStatus); return this.appService.changeStatusCommunity(pId, pStatus);
} }
// #==== API Common Areas // #==== API Common Areas
@Post('commonArea/createCommonArea') @Post('commonArea/createCommonArea')
createCommonArea( createCommonArea(
@ -227,6 +266,14 @@ export class AppController {
return this.appService.deleteCommonArea(id); return this.appService.deleteCommonArea(id);
} }
@Post('commonArea/changeStatus')
changeStatusCommonArea(
@Body('id') pId: string,
@Body('status') pStatus: string,
) {
return this.appService.changeStatusCommonArea(pId, pStatus);
}
// #==== API GUEST // #==== API GUEST
//#API userService - create user //#API userService - create user
@Post('guest/createGuest') @Post('guest/createGuest')

View File

@ -53,6 +53,36 @@ export class AppService {
.pipe(map((message: string) => ({ message }))); .pipe(map((message: string) => ({ message })));
} }
updateUser(
dni: string,
name: string,
last_name: string,
email: string,
phone: number,
password: string,
user_type: string,
status: string,
date_entry: Date,
community_id: string,
) {
const pattern = { cmd: 'updateUser' };
const payload = {
dni: dni,
name: name,
last_name: last_name,
email: email,
phone: phone,
password: password,
user_type: user_type,
status: status,
date_entry: date_entry,
community_id: community_id,
};
return this.clientUserApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
//POST parameter from API //POST parameter from API
createAdminSystem(dni: string, name: string, last_name: string, email: string, phone: number createAdminSystem(dni: string, name: string, last_name: string, email: string, phone: number
, user_type: string, status: string, date_entry: Date) { , user_type: string, status: string, date_entry: Date) {
@ -163,6 +193,22 @@ export class AppService {
.pipe(map((message: string) => ({ message }))); .pipe(map((message: string) => ({ message })));
} }
deleteAdminCommunity(id: string) {
const pattern = { cmd: 'deleteAdminCommunity' };
const payload = { id: id };
return this.clientUserApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
deleteTenant(id: string) {
const pattern = { cmd: 'deleteTenant' };
const payload = { id: id };
return this.clientUserApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
inicioSesion(pEmail: string, pPassword: string) { inicioSesion(pEmail: string, pPassword: string) {
const pattern = { cmd: 'loginUser' }; const pattern = { cmd: 'loginUser' };
const payload = { email: pEmail, password: pPassword }; const payload = { email: pEmail, password: pPassword };
@ -269,6 +315,7 @@ export class AppService {
hourMax: hourMax, hourMax: hourMax,
bookable: bookable, bookable: bookable,
community_id: community_id, community_id: community_id,
status: '1'
}; };
return this.clientCommonAreaApp return this.clientCommonAreaApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
@ -312,6 +359,15 @@ export class AppService {
.pipe(map((message: string) => ({ message }))); .pipe(map((message: string) => ({ message })));
} }
changeStatusCommonArea(pId: string, pStatus: string) {
const pattern = { cmd: 'changeStatus' };
const payload = { id: pId, status: pStatus };
return this.clientCommonAreaApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
// ====================== GUESTS =============================== // ====================== GUESTS ===============================
//POST parameter from API //POST parameter from API

8
devshell.toml Normal file
View File

@ -0,0 +1,8 @@
# https://numtide.github.io/devshell
[[commands]]
package = "devshell.cli"
help = "Per project developer environments"
[[commands]]
package = "nodejs"
help = "Node.js"

92
flake.lock Normal file
View File

@ -0,0 +1,92 @@
{
"nodes": {
"devshell": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1658746384,
"narHash": "sha256-CCJcoMOcXyZFrV1ag4XMTpAPjLWb4Anbv+ktXFI1ry0=",
"owner": "numtide",
"repo": "devshell",
"rev": "0ffc7937bb5e8141af03d462b468bd071eb18e1b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"locked": {
"lastModified": 1656928814,
"narHash": "sha256-RIFfgBuKz6Hp89yRr7+NR5tzIAbn52h8vT6vXkYjZoM=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "7e2a3b3dfd9af950a856d66b0a7d01e3c18aa249",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1643381941,
"narHash": "sha256-pHTwvnN4tTsEKkWlXQ8JMY423epos8wUOhthpwJjtpc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5efc8ca954272c4376ac929f4c5ffefcc20551d5",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1659782844,
"narHash": "sha256-tM/qhHFE61puBxh9ebP3BIG1fkRAT4rHqD3jCM0HXGY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c85e56bb060291eac3fb3c75d4e0e64f6836fcfe",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"devshell": "devshell",
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_2"
}
}
},
"root": "root",
"version": 7
}

20
flake.nix Normal file
View File

@ -0,0 +1,20 @@
{
description = "virtual environments";
inputs.devshell.url = "github:numtide/devshell";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, flake-utils, devshell, nixpkgs }:
flake-utils.lib.eachDefaultSystem (system: {
devShell =
let pkgs = import nixpkgs {
inherit system;
overlays = [ devshell.overlay ];
};
in
pkgs.devshell.mkShell {
imports = [ (pkgs.devshell.importTOML ./devshell.toml) ];
};
});
}

View File

@ -1,6 +1,5 @@
node_modules/ node_modules/
.expo/ .expo/
dist/
npm-debug.* npm-debug.*
*.jks *.jks
*.p8 *.p8
@ -9,6 +8,6 @@ npm-debug.*
*.mobileprovision *.mobileprovision
*.orig.* *.orig.*
web-build/ web-build/
.vscode
# macOS
.DS_Store .DS_Store

60
mobile-ui/App.js Normal file
View File

@ -0,0 +1,60 @@
import React,{useState} from "react";
import {
NativeBaseProvider,
Icon
} from "native-base";
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import LogIn from "./components/LogIn";
import Home from "./components/Home";
import RecoverPassword from "./components/RecoverPassword";
import Reservas from "./components/Reservas";
import Profile from "./components/Profile";
import { MaterialCommunityIcons } from '@expo/vector-icons';
import AreaComun from "./components/AreaComun";
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
function HomeTab() {
const [selected, setSelected] = useState(0);
return (
<Tab.Navigator initialRouteName="Comunicados" >
<Tab.Screen name="Comunicados" component={Home} options={{headerStyle: {
backgroundColor: "#D7A86E"
}, tabBarIcon: () => (<Icon mb="2" as={<MaterialCommunityIcons name={selected === 0 ? 'home' : 'home-outline'} />} color="#D7A86E" size="md" />)}} onclick={() => setSelected(0)} />
<Tab.Screen name="Reservas" component={Reservas } options={{headerStyle: {
backgroundColor: "#D7A86E"
}, tabBarIcon: () => (<Icon mb="2" as={<MaterialCommunityIcons name={selected === 1 ? 'tree' : 'tree-outline'} />} color="#D7A86E" size="md" />)} } onclick={() => setSelected(1)} />
<Tab.Screen name="Perfil" component={Profile} options={{headerStyle: {
backgroundColor: "#D7A86E"
}, tabBarIcon: () => (<Icon mb="2" as={<MaterialCommunityIcons name={selected === 2 ? 'account' : 'account-outline'} />} color="#D7A86E" size="md" />)}} onclick={() => setSelected(2)} />
</Tab.Navigator>
)
}
export default function App() {
return (
<NativeBaseProvider>
<NavigationContainer>
<Stack.Navigator initialRouteName="LogIn">
<Stack.Screen name="Inicio" component={LogIn} options={{headerStyle: {
backgroundColor: "#D7A86E"
}}} />
<Stack.Screen name="Comunicados" component={HomeTab} options={{headerShown: false}} />
<Stack.Screen name="Password" component={RecoverPassword} />
<Stack.Screen name="area" component={AreaComun} options={{headerStyle: {
backgroundColor: "#D7A86E"
}}} />
</Stack.Navigator>
</NavigationContainer>
</NativeBaseProvider>
);
}

View File

@ -1,20 +0,0 @@
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

9
mobile-ui/Readme.md Normal file
View File

@ -0,0 +1,9 @@
# NativeBase Expo Template
The official NativeBase template for [Expo](https://docs.expo.io/)
## Usage
```sh
expo init my-app --template @native-base/expo-template
```

View File

@ -1,11 +1,10 @@
{ {
"expo": { "expo": {
"name": "mobile-ui", "name": "my-app",
"slug": "mobile-ui", "slug": "my-app",
"version": "1.0.0", "version": "1.0.0",
"orientation": "portrait", "orientation": "portrait",
"icon": "./assets/icon.png", "icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": { "splash": {
"image": "./assets/splash.png", "image": "./assets/splash.png",
"resizeMode": "contain", "resizeMode": "contain",

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -0,0 +1,53 @@
import React from "react";
import {
Box,
Heading,
VStack,
FormControl,
Input,
Button,
Center
} from "native-base";
export default function AreaComun({navigation}){
return (
<Center>
<Box safeArea p="2" w="90%" maxW="290" py="8">
<Heading size="lg" color="coolGray.800" _dark={{
color: "warmGray.50"
}} fontWeight="semibold">
Katoikia
</Heading>
<Heading mt="1" color="coolGray.600" _dark={{
color: "warmGray.200"
}} fontWeight="medium" size="xs">
Reserve su área común
</Heading>
<VStack space={3} mt="5">
<FormControl>
<FormControl.Label>Hora de inicio</FormControl.Label>
<Input type="text"/>
</FormControl>
<FormControl>
<FormControl.Label>Hora de finalización</FormControl.Label>
<Input type="text" />
</FormControl>
<FormControl>
<FormControl.Label>Lugar</FormControl.Label>
<Input type="text" />
</FormControl>
<Button mt="2" backgroundColor="orange.300">
Reservar
</Button>
<Button mt="6" colorScheme="error" onPress={() => navigation.navigate('Comunicados')}>
Cancelar
</Button>
</VStack>
</Box>
</Center>
)
}

View File

@ -0,0 +1,101 @@
import React from "react";
import {
Text,
HStack,
Badge,
Box,
Pressable,
Spacer,
} from "native-base";
import { MaterialCommunityIcons } from '@expo/vector-icons';
export default function Home(){
const [selected, setSelected] = React.useState(0);
return (
<Box alignItems="center">
<Pressable onPress={() => console.log("I'm Pressed")} rounded="8" overflow="hidden" borderWidth="1" borderColor="coolGray.300" maxW="96" shadow="3" bg="coolGray.100" p="5" marginTop="4">
<Box>
<HStack alignItems="center">
<Badge colorScheme="darkBlue" _text={{
color: "white"
}} variant="solid" rounded="4">
Comunicado
</Badge>
<Spacer />
<Text fontSize={10} color="coolGray.800">
1 month ago
</Text>
</HStack>
<Text color="coolGray.800" mt="3" fontWeight="medium" fontSize="xl">
Administrador de Comunidad
</Text>
<Text mt="2" fontSize="sm" color="coolGray.700">
Notificacion sobre la aplicacion
</Text>
</Box>
</Pressable>
<Pressable onPress={() => console.log("I'm Pressed")} rounded="8" overflow="hidden" borderWidth="1" borderColor="coolGray.300" maxW="96" shadow="3" bg="coolGray.100" p="5" marginTop="4">
<Box>
<HStack alignItems="center">
<Badge colorScheme="darkBlue" _text={{
color: "white"
}} variant="solid" rounded="4">
Comunicado
</Badge>
<Spacer />
<Text fontSize={10} color="coolGray.800">
1 month ago
</Text>
</HStack>
<Text color="coolGray.800" mt="3" fontWeight="medium" fontSize="xl">
Administrador General
</Text>
<Text mt="2" fontSize="sm" color="coolGray.700">
Notificacion sobre la aplicacion
</Text>
</Box>
</Pressable>
</Box>
// <Center width={"100%"} marginTop={"auto"}>
// <Box safeAreaTop bg="#D7A86E" flex={1} />
// <HStack bg="#D7A86E" px="2" py="4" justifyContent="space-between" alignItems="center" w="100%" maxW="100%">
// <Pressable opacity={selected === 0 ? 1 : 0.5} py="3" flex={1} onPress={() => setSelected(0) && navigation.navigate('Home')}>
// <Center>
// <Icon mb="2" as={<MaterialCommunityIcons name={selected === 0 ? 'home' : 'home-outline'} />} color="white" size="md" />
// <Text color="white" fontSize="15">
// Inicio
// </Text>
// </Center>
// </Pressable>
// <Pressable opacity={selected === 1 ? 1 : 0.5} py="3" flex={1} onPress={() => setSelected(1) && ( () => navigation.navigate('Reservas'))}>
// <Center>
// <Icon mb="2" as={<MaterialCommunityIcons name={selected === 1 ? 'tree' : 'tree-outline'} />} color="white" size="md" />
// <Text color="white" fontSize="15">
// Reservas
// </Text>
// </Center>
// </Pressable>
// <Pressable opacity={selected === 2 ? 1 : 0.5} py="3" flex={1} onPress={() => setSelected(2)}>
// <Center>
// <Icon mb="2" as={<MaterialCommunityIcons name={selected === 2 ? 'account' : 'account-outline'} />} color="white" size="md" />
// <Text color="white" fontSize="15">
// Perfil
// </Text>
// </Center>
// </Pressable>
// </HStack>
// </Center>
)
}

View File

@ -0,0 +1,175 @@
import React from "react";
import Cookies from 'universal-cookie';
import {
Text,
Link,
Center,
Heading,
VStack,
Box,
FormControl,
Button,
Image
} from "native-base";
import logo from "../assets/logo-katoikia.png";
import { Entypo } from '@expo/vector-icons';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { View, TextInput, StyleSheet } from "react-native";
const baseURL = "http://localhost:4000/user/loginUser";
const cookies = new Cookies();
const styles = StyleSheet.create({
input: {
height: 40,
margin: 10,
borderWidth: 0.5,
padding: 5,
flex: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10,
paddingLeft: 0,
marginTop: 50,
marginBottom: 10
},
iconStyle: {
padding: 10,
},
viewSection: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
margin: 10
},
container: {
}
})
const iniciarSesion = async() => {
try {
await fetch(baseURL, {
cache: 'no-cache',
method: 'POST',
body: JSON.stringify(),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
if (response.status != 201){
console.log('ocurrio un error ');
}else{
return response.json();
}
})
.then( response => {
const user = response.message
if(user.user_type == '3'){
cookies.set('id',user._id, {path: "/"} )
cookies.set('name',user.name, {path: "/"} )
cookies.set('email',user.email, {path: "/"} )
cookies.set('type',user.user_type, {path: "/"} )
}
})
} catch (error) {
}
}
export default function LogIn({navigation}) {
return (
<Center w="100%">
<Box safeArea p="2" py="8" w="90%" maxW="290">
<Center>
<Image source={
logo
} width={500} height={550} m='2'
alt="Katoikia logo" size="xl" justifyContent="center" />
</Center>
<Heading
size="lg"
fontWeight="600"
color="coolGray.800"
_dark={{
color: "warmGray.50",
}}
>
Bienvenido a Katoikia
</Heading>
<Heading
mt="1"
_dark={{
color: "warmGray.200",
}}
color="coolGray.600"
fontWeight="medium"
size="xs"
>
Su app de comunidad de confianza
</Heading>
<View style={styles.container}>
<VStack space={3} mt="5">
<FormControl>
<FormControl.Label> Correo Electrónico </FormControl.Label>
<View style={styles.viewSection}>
<Entypo name="email" size={20} color="grey" style={styles.iconStyle} />
<TextInput type="text" style={styles.input} />
</View>
</FormControl>
<FormControl>
<FormControl.Label> Contraseña </FormControl.Label>
<View style={styles.viewSection}>
<MaterialCommunityIcons name="form-textbox-password" size={20} color="grey" style={styles.iconStyle}/>
<TextInput type="password" style={styles.input} />
</View>
<Link
_text={{
fontSize: "xs",
fontWeight: "500",
color: "indigo.500",
marginTop: "10"
}}
alignSelf="flex-end"
mt="1"
onPress={() => navigation.navigate('Password')}
>
Recuperar contraseña
</Link>
</FormControl>
<Button mt="2" backgroundColor="#D7A86E" onPress={() => navigation.navigate('Comunicados')}
>
<Text>Continuar</Text>
</Button>
</VStack></View>
</Box>
</Center>
);
}

View File

@ -0,0 +1,44 @@
import React from "react";
import { Icon } from "native-base";
import { G, Path } from "react-native-svg";
const NativeBaseIcon = () => {
return (
<Icon size="220px" viewBox="0 0 602.339 681.729">
<G
id="Group_403"
data-name="Group 403"
transform="translate(14575 1918.542)"
>
<Path
id="Path_1"
data-name="Path 1"
d="M488.722,0A45.161,45.161,0,0,1,527.83,22.576L675.676,278.584a45.162,45.162,0,0,1,0,45.171L527.83,579.763a45.162,45.162,0,0,1-39.108,22.576H193.008A45.162,45.162,0,0,1,153.9,579.763L6.053,323.755a45.162,45.162,0,0,1,0-45.171L153.9,22.576A45.162,45.162,0,0,1,193.008,0Z"
transform="translate(-13972.661 -1918.542) rotate(90)"
fill="#356290"
/>
<Path
id="Path_252"
data-name="Path 252"
d="M401.1,0A60.816,60.816,0,0,1,453.77,30.405L567.2,226.844a60.816,60.816,0,0,1,0,60.82L453.77,484.1A60.816,60.816,0,0,1,401.1,514.509H174.241A60.816,60.816,0,0,1,121.575,484.1L8.149,287.665a60.816,60.816,0,0,1,0-60.82L121.575,30.405A60.816,60.816,0,0,1,174.241,0Z"
transform="translate(-14016.576 -1865.281) rotate(90)"
fill="#1784b2"
/>
<Path
id="Path_251"
data-name="Path 251"
d="M345.81,0a36.573,36.573,0,0,1,31.674,18.288L480.566,196.856a36.573,36.573,0,0,1,0,36.569L377.484,411.993a36.573,36.573,0,0,1-31.674,18.288H139.655a36.572,36.572,0,0,1-31.674-18.288L4.9,233.425a36.573,36.573,0,0,1,0-36.569L107.981,18.288A36.573,36.573,0,0,1,139.655,0Z"
transform="translate(-14058.69 -1820.41) rotate(90)"
fill="#50bfc3"
/>
<Path
id="_x3C__x2F__x3E_"
d="M187.066,335.455V297.993l-65.272-21.949,65.272-22.523V216.059L81,259.5v32.521Zm38.726,29.3L286.123,174H256.7l-60.33,190.759Zm72.052-29.3,106.066-43.783V259.267L297.844,216.059V254.44l59.3,23.328-59.3,19.421Z"
transform="translate(-14516.286 -1846.988)"
fill="#fff"
/>
</G>
</Icon>
);
};
export default NativeBaseIcon;

View File

@ -0,0 +1,57 @@
import React from "react";
import {
Box,
Heading,
VStack,
FormControl,
Input,
Button,
Center
} from "native-base";
export default function Profile({navigation}){
return (
<Center>
<Box safeArea p="2" w="90%" maxW="290" py="8">
<Heading size="lg" color="coolGray.800" _dark={{
color: "warmGray.50"
}} fontWeight="semibold">
Katoikia
</Heading>
<Heading mt="1" color="coolGray.600" _dark={{
color: "warmGray.200"
}} fontWeight="medium" size="xs">
Modifique sus datos
</Heading>
<VStack space={3} mt="5">
<FormControl>
<FormControl.Label>Nombre</FormControl.Label>
<Input type="text"/>
</FormControl>
<FormControl>
<FormControl.Label>Correo Electrónico</FormControl.Label>
<Input type="text" />
</FormControl>
<FormControl>
<FormControl.Label>Teléfono</FormControl.Label>
<Input type="text" />
</FormControl>
<FormControl>
<FormControl.Label>Contraseña actual</FormControl.Label>
<Input type="password" />
</FormControl>
<Button mt="2" backgroundColor="orange.300">
Actualizar
</Button>
<Button mt="6" colorScheme="error" onPress={() => navigation.navigate('Inicio')}>
Cerrar sesión
</Button>
</VStack>
</Box>
</Center>
)
}

View File

@ -0,0 +1,56 @@
import React from "react";
import {
Text,
Link,
Center,
Heading,
VStack,
Box,
FormControl,
Input,
Button
} from "native-base";
export default function RecoverPassword () {
return (
<Center w="100%">
<Box safeArea p="2" py="8" w="90%" maxW="290">
<Heading
size="lg"
fontWeight="600"
color="coolGray.800"
_dark={{
color: "warmGray.50",
}}
>
Recupere su contraseña
</Heading>
<Heading
mt="1"
_dark={{
color: "warmGray.200",
}}
color="coolGray.600"
fontWeight="medium"
size="xs"
>
Se le enviaran las instrucciones al correo electrónico
</Heading>
<VStack space={3} mt="5">
<FormControl>
<FormControl.Label> Correo Electrónico</FormControl.Label>
<Input />
</FormControl>
<Button mt="2" colorScheme="primary" onPress={() => navigation.navigate('Home')}
>
<Text>Recuperar contraseña</Text>
</Button>
</VStack>
</Box>
</Center>
)
}

View File

@ -0,0 +1,148 @@
import React from "react";
import {
Text,
HStack,
AntDesign,
Heading,
Stack,
Box,
ScrollView,
Fab,
Icon
} from "native-base";
import logo from "../assets/logo-katoikia.png";
import { Entypo } from '@expo/vector-icons';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { View, TextInput, StyleSheet } from "react-native";
const styles = StyleSheet.create({
input: {
height: 40,
margin: 10,
borderWidth: 0.5,
padding: 5,
flex: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10,
paddingLeft: 0,
marginTop: 50,
marginBottom: 10
},
iconStyle: {
padding: 10,
},
viewSection: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
margin: 10
},
container: {
}
})
export default function Reservas({navigation}) {
return (
<ScrollView showsVerticalScrollIndicator={false}>
<Box alignItems="center">
<Box width="80" rounded="lg" overflow="hidden" borderColor="coolGray.200" borderWidth="1" _dark={{
borderColor: "coolGray.600",
backgroundColor: "gray.700"
}} _web={{
shadow: 2,
borderWidth: 0
}} _light={{
backgroundColor: "gray.50"
}}>
<Stack p="4" space={3}>
<Stack space={2}>
<Heading size="md" ml="-1">
Reserva #1
</Heading>
<Text fontSize="xs" _light={{
color: "violet.500"
}} _dark={{
color: "violet.400"
}} fontWeight="500" ml="-0.5" mt="-1">
horario de Reserva
</Text>
</Stack>
<Text fontWeight="400">
Descripcion
</Text>
<HStack alignItems="center" space={4} justifyContent="space-between">
<HStack alignItems="center">
<Text color="coolGray.600" _dark={{
color: "warmGray.200"
}} fontWeight="400">
6 mins ago
</Text>
</HStack>
</HStack>
</Stack>
</Box>
</Box>
<Box alignItems="center" width={"100%"}>
<Box width="80" rounded="lg" overflow="hidden" borderColor="coolGray.200" borderWidth="1" _dark={{
borderColor: "coolGray.600",
backgroundColor: "gray.700"
}} _web={{
shadow: 2,
borderWidth: 0
}} _light={{
backgroundColor: "gray.50"
}}>
<Stack p="4" space={3}>
<Stack space={2}>
<Heading size="md" ml="-1">
Reserva #1
</Heading>
<Text fontSize="xs" _light={{
color: "violet.500"
}} _dark={{
color: "violet.400"
}} fontWeight="500" ml="-0.5" mt="-1">
horario de Reserva
</Text>
</Stack>
<Text fontWeight="400">
Descripcion
</Text>
<HStack alignItems="center" space={4} justifyContent="space-between">
<HStack alignItems="center">
<Text color="coolGray.600" _dark={{
color: "warmGray.200"
}} fontWeight="400">
6 mins ago
</Text>
</HStack>
</HStack>
</Stack>
</Box>
</Box>
<Box height="200" w="300" shadow="2" rounded="lg" m='5' ml='9' _dark={{
bg: "coolGray.200:alpha.20"
}} _light={{
bg: "coolGray.200:alpha.20"
}}>
<Fab renderInPortal={false} shadow={2} size="sm" icon={<Icon mb="0.5" as={<MaterialCommunityIcons name={'plus'} />} color="white" size="sm" />} onPress={() => navigation.navigate('area')}/>
</Box>
</ScrollView>
);
}

30065
mobile-ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,14 @@
{ {
"name": "mobile-ui", "name": "my-app",
"version": "1.0.0", "version": "1.0.0",
"main": "node_modules/expo/AppEntry.js", "main": "node_modules/expo/AppEntry.js",
"keywords": [
"react",
"expo",
"template",
"nativebase"
],
"license": "MIT",
"scripts": { "scripts": {
"start": "expo start", "start": "expo start",
"android": "expo start --android", "android": "expo start --android",
@ -10,20 +17,32 @@
"eject": "expo eject" "eject": "expo eject"
}, },
"dependencies": { "dependencies": {
"expo": "~45.0.0", "@react-native-community/masked-view": "^0.1.11",
"expo-cli": "^5.4.12", "@react-navigation/bottom-tabs": "^6.3.2",
"expo-status-bar": "~1.3.0", "@react-navigation/native": "^6.0.11",
"react": "17.0.2", "@react-navigation/native-stack": "^6.7.0",
"react-dom": "17.0.2", "@react-navigation/stack": "^6.2.2",
"react-native": "0.68.2", "expo": "^44.0.0",
"react-native-web": "0.17.7", "expo-status-bar": "~1.2.0",
"sharp-cli": "^2.1.1" "native-base": "3.4.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-gesture-handler": "~2.1.0",
"react-native-reanimated": "~2.3.1",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.10.1",
"react-native-svg": "12.1.1",
"react-native-web": "0.17.1",
"universal-cookie": "^4.0.4"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.9", "@babel/core": "^7.12.9"
"@types/react": "~17.0.21",
"@types/react-native": "~0.66.13",
"typescript": "~4.3.5"
}, },
"bugs": {
"url": "https://github.com/GeekyAnts/nativebase-templates/issues"
},
"homepage": "https://github.com/GeekyAnts/nativebase-templates#readme",
"author": "Aditya Jamuar",
"private": true "private": true
} }

View File

@ -1,6 +0,0 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
}
}

15233
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -24,5 +24,8 @@
"js-beautify --config .jsbeautifyrc --type 'html' --replace", "js-beautify --config .jsbeautifyrc --type 'html' --replace",
"git add" "git add"
] ]
},
"dependencies": {
"@react-navigation/native": "^6.0.11"
} }
} }

View File

@ -39,4 +39,12 @@ export class CommonAreasController {
let _community_id = id['community_id']; let _community_id = id['community_id'];
return this.commonAreasService.findByCommunity(_community_id); return this.commonAreasService.findByCommunity(_community_id);
} }
//cambiar de estado
@MessagePattern({ cmd: 'changeStatus' })
changeStatus(@Payload() body: string) {
let pid = body['id'];
let pstatus = body['status'];
return this.commonAreasService.changeStatus(pid,pstatus);
}
} }

View File

@ -41,4 +41,10 @@ export class CommonAreasService {
return this.commonAreaModel.find({ community_id: community_id }).exec(); return this.commonAreaModel.find({ community_id: community_id }).exec();
} }
async changeStatus(id: string, status: string) {
return this.commonAreaModel.findOneAndUpdate({ _id: id }, {status: status}, {
new: true,
});
}
} }

View File

@ -5,6 +5,7 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "servicio-comunidad-viviendas",
"version": "0.0.1", "version": "0.0.1",
"license": "UNLICENSED", "license": "UNLICENSED",
"dependencies": { "dependencies": {

View File

@ -112,11 +112,18 @@ export class UsersController {
@MessagePattern({ cmd: 'deleteAdminSystem' }) @MessagePattern({ cmd: 'deleteAdminSystem' })
deleteAdminSystem(@Payload() user: any) { deleteAdminSystem(@Payload() user: any) {
console.log('entró');
return this.userService.deleteAdminSystem(user['id']); return this.userService.deleteAdminSystem(user['id']);
} }
@MessagePattern({ cmd: 'deleteAdminCommunity' })
deleteAdminCommunity(@Payload() user: any) {
return this.userService.deleteAdminCommunity(user['id']);
}
@MessagePattern({ cmd: 'deleteTenant' })
deleteTenant(@Payload() user: any) {
return this.userService.deleteTenant(user['id']);
}
@MessagePattern({ cmd: 'changeStatus' }) @MessagePattern({ cmd: 'changeStatus' })
changeStatus(@Payload() body: string) { changeStatus(@Payload() body: string) {

View File

@ -14,8 +14,8 @@ export class UsersService {
@InjectModel(User.name) private readonly userModel: Model<UserDocument>, @InjectModel(User.name) private readonly userModel: Model<UserDocument>,
@Inject('SERVICIO_NOTIFICACIONES') private readonly clientNotificationtApp: ClientProxy, @Inject('SERVICIO_NOTIFICACIONES') private readonly clientNotificationtApp: ClientProxy,
@Inject('SERVICIO_COMUNIDADES') private readonly clientCommunityApp: ClientProxy, @Inject('SERVICIO_COMUNIDADES') private readonly clientCommunityApp: ClientProxy,
) { } ) { }
private publicKey: string; private publicKey: string;
async create(user: UserDocument): Promise<User> { async create(user: UserDocument): Promise<User> {
let passwordEncriptada = Md5.init(user.password); let passwordEncriptada = Md5.init(user.password);
@ -78,14 +78,14 @@ export class UsersService {
}); });
} }
/* async remove(id: string) { /* async remove(id: string) {
return this.userModel.findByIdAndRemove({ _id: id }).exec(); return this.userModel.findByIdAndRemove({ _id: id }).exec();
}*/ }*/
async remove(id: string) { async remove(id: string) {
return this.userModel.findOneAndUpdate({ _id: id }, {status: '-1'}, { return this.userModel.findOneAndUpdate({ _id: id }, { status: '-1' }, {
new: true, new: true,
}); });
} }
//inicio de sesion //inicio de sesion
@ -99,8 +99,12 @@ export class UsersService {
reject(err); reject(err);
} else { } else {
let passwordEncriptada = Md5.init(password); let passwordEncriptada = Md5.init(password);
if (res[0].password == passwordEncriptada) { if (res.length > 0) {
resolve(res[0]); if (res[0].password == passwordEncriptada) {
resolve(res[0]);
} else {
resolve(null);
}
} else { } else {
resolve(null); resolve(null);
} }
@ -180,9 +184,21 @@ export class UsersService {
} }
async deleteAdminSystem(id: string) { async deleteAdminSystem(id: string) {
return this.userModel.findOneAndUpdate({ _id: id }, {status: '-1'}, { return this.userModel.findOneAndUpdate({ _id: id }, { status: '-1' }, {
new: true, new: true,
}); });
}
deleteAdminCommunity(id: string) {
return this.userModel.findOneAndUpdate({ _id: id }, { status: '-1' }, {
new: true,
});
}
async deleteTenant(id: string) {
return this.userModel.findOneAndUpdate({ _id: id }, { status: '-1' }, {
new: true,
});
} }
async validateEmail(email: string) { async validateEmail(email: string) {
@ -202,31 +218,31 @@ export class UsersService {
}); });
} }
async findNumHouseTenant(community_id: string, tenant_id: string) { async findNumHouseTenant(community_id: string, tenant_id: string): Promise<string> {
const pattern = { cmd: 'findOneCommunity' } const pattern = { cmd: 'findOneCommunity' }
const payload = { _id: community_id } const payload = { _id: community_id }
let callback = await this.clientCommunityApp let callback = this.clientCommunityApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
.pipe( .pipe(map((response: string) => ({ response })))
map((response: string) => ({ response }))
)
const finalValue = await lastValueFrom(callback); const finalValue = await lastValueFrom(callback);
const response = finalValue['response']; const response = finalValue['response'];
const houses = response['houses']; const houses = response['houses'];
let num_house = ""; let num_house = "";
await houses.forEach(async house => { await houses.forEach(async (house: { [x: string]: string; }) => {
if (tenant_id == house.tenants.tenant_id) { if (house['tenant_id'] !== undefined) {
num_house = house.number_house; if (house['tenant_id'] === tenant_id) {
num_house = house['number_house'];
} }
}
}) })
return num_house; return num_house;
} }
async changeStatus(id: string, status: string) { async changeStatus(id: string, status: string) {
return this.userModel.findOneAndUpdate({ _id: id }, {status: status}, { return this.userModel.findOneAndUpdate({ _id: id }, { status: status }, {
new: true, new: true,
}); });
} }
} }

BIN
web-ui/.DS_Store vendored

Binary file not shown.

View File

@ -17,7 +17,8 @@
"@fullcalendar/interaction": "^5.7.2", "@fullcalendar/interaction": "^5.7.2",
"@fullcalendar/react": "^5.7.0", "@fullcalendar/react": "^5.7.0",
"@fullcalendar/timegrid": "^5.7.2", "@fullcalendar/timegrid": "^5.7.2",
"axios": "^0.19.0", "axios": "^0.19.2",
"bootstrap": "^5.2.0",
"chart.js": "3.3.2", "chart.js": "3.3.2",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"cors": "^2.8.5", "cors": "^2.8.5",
@ -2288,6 +2289,16 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/@popperjs/core": {
"version": "2.11.6",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
"integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@svgr/babel-plugin-add-jsx-attribute": { "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz",
@ -4210,6 +4221,24 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
}, },
"node_modules/bootstrap": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.0.tgz",
"integrity": "sha512-qlnS9GL6YZE6Wnef46GxGv1UpGGzAwO0aPL1yOjzDIJpeApeMvqV24iL+pjr2kU4dduoBA9fINKWKgMToobx9A==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"peerDependencies": {
"@popperjs/core": "^2.11.5"
}
},
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -19688,6 +19717,12 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
}, },
"@popperjs/core": {
"version": "2.11.6",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
"integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
"peer": true
},
"@svgr/babel-plugin-add-jsx-attribute": { "@svgr/babel-plugin-add-jsx-attribute": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz",
@ -21217,6 +21252,12 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
}, },
"bootstrap": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.0.tgz",
"integrity": "sha512-qlnS9GL6YZE6Wnef46GxGv1UpGGzAwO0aPL1yOjzDIJpeApeMvqV24iL+pjr2kU4dduoBA9fINKWKgMToobx9A==",
"requires": {}
},
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",

View File

@ -17,7 +17,8 @@
"@fullcalendar/interaction": "^5.7.2", "@fullcalendar/interaction": "^5.7.2",
"@fullcalendar/react": "^5.7.0", "@fullcalendar/react": "^5.7.0",
"@fullcalendar/timegrid": "^5.7.2", "@fullcalendar/timegrid": "^5.7.2",
"axios": "^0.19.0", "axios": "^0.19.2",
"bootstrap": "^5.2.0",
"chart.js": "3.3.2", "chart.js": "3.3.2",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"cors": "^2.8.5", "cors": "^2.8.5",

View File

@ -7156,4 +7156,11 @@
.status.status--1 { .status.status--1 {
background: #565656; background: #565656;
color: #f7f9f7; color: #f7f9f7;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -1,6 +1,6 @@
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { Route, useLocation } from 'react-router-dom'; import { BrowserRouter, Switch, Route, useLocation } from 'react-router-dom';
import { CSSTransition } from 'react-transition-group'; import { CSSTransition } from 'react-transition-group';
import { AppTopbar } from './AppTopbar'; import { AppTopbar } from './AppTopbar';
@ -33,6 +33,8 @@ import AdministradoresComunidad from './components/AdministradoresComunidad';
import GuardasSeguridad from './components/GuardasSeguridad'; import GuardasSeguridad from './components/GuardasSeguridad';
import Communities from './components/ComunidadViviendas'; import Communities from './components/ComunidadViviendas';
import Inquilinos from './components/Inquilinos'; import Inquilinos from './components/Inquilinos';
import RegistroComunicado from './components/RegistroComunicado';
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Crud from './pages/Crud'; import Crud from './pages/Crud';
import EmptyPage from './pages/EmptyPage'; import EmptyPage from './pages/EmptyPage';
@ -49,406 +51,480 @@ import './assets/demo/flags/flags.css';
import './assets/demo/Demos.scss'; import './assets/demo/Demos.scss';
import './assets/layout/layout.scss'; import './assets/layout/layout.scss';
import './App.scss'; import './App.scss';
import LogIn from './components/LogIn';
import { PrimeIcons } from 'primereact/api'; import { PrimeIcons } from 'primereact/api';
import AreasComunes from './components/AreasComunes'; import AreasComunes from './components/AreasComunes';
import { useCookies } from "react-cookie";
import LogInUser from './components/LogInUser';
import Page404 from './components/Page404'
const App = () => { const App = () => {
const [layoutMode, setLayoutMode] = useState('static'); const [layoutMode, setLayoutMode] = useState('static');
const [layoutColorMode, setLayoutColorMode] = useState('light'); const [layoutColorMode, setLayoutColorMode] = useState('light')
const [inputStyle, setInputStyle] = useState('outlined'); const [inputStyle, setInputStyle] = useState('outlined');
const [ripple, setRipple] = useState(true); const [ripple, setRipple] = useState(true);
const [staticMenuInactive, setStaticMenuInactive] = useState(false); const [staticMenuInactive, setStaticMenuInactive] = useState(false);
const [overlayMenuActive, setOverlayMenuActive] = useState(false); const [overlayMenuActive, setOverlayMenuActive] = useState(false);
const [mobileMenuActive, setMobileMenuActive] = useState(false); const [mobileMenuActive, setMobileMenuActive] = useState(false);
const [mobileTopbarMenuActive, setMobileTopbarMenuActive] = useState(false); const [mobileTopbarMenuActive, setMobileTopbarMenuActive] = useState(false);
const copyTooltipRef = useRef(); const copyTooltipRef = useRef();
const location = useLocation(); const location = useLocation();
const [cookies, setCookies] = useCookies();
const [logged, setLogged] = useState()
PrimeReact.ripple = true; PrimeReact.ripple = true;
let menuClick = false; let menuClick = false;
let mobileTopbarMenuClick = false; let mobileTopbarMenuClick = false;
useEffect(() => { useEffect(() => {
if (mobileMenuActive) { if (mobileMenuActive) {
addClass(document.body, 'body-overflow-hidden'); addClass(document.body, 'body-overflow-hidden');
} else { } else {
removeClass(document.body, 'body-overflow-hidden'); removeClass(document.body, 'body-overflow-hidden');
} }
}, [mobileMenuActive]); }, [mobileMenuActive]);
useEffect(() => { useEffect(() => {
copyTooltipRef && copyTooltipRef &&
copyTooltipRef.current && copyTooltipRef.current &&
copyTooltipRef.current.updateTargetEvents(); copyTooltipRef.current.updateTargetEvents();
}, [location]); }, [location]);
const onInputStyleChange = (inputStyle) => {
setInputStyle(inputStyle);
};
const onRipple = (e) => {
PrimeReact.ripple = e.value;
setRipple(e.value);
};
const onLayoutModeChange = (mode) => {
setLayoutMode(mode);
};
const onColorModeChange = (mode) => {
setLayoutColorMode(mode);
};
const onWrapperClick = (event) => {
if (!menuClick) {
setOverlayMenuActive(false);
setMobileMenuActive(false);
}
if (!mobileTopbarMenuClick) {
setMobileTopbarMenuActive(false);
}
mobileTopbarMenuClick = false; const onInputStyleChange = (inputStyle) => {
menuClick = false; setInputStyle(inputStyle);
}; };
const onToggleMenuClick = (event) => { const onRipple = (e) => {
menuClick = true; PrimeReact.ripple = e.value;
setRipple(e.value);
};
if (isDesktop()) { const onLayoutModeChange = (mode) => {
if (layoutMode === 'overlay') { setLayoutMode(mode);
if (mobileMenuActive === true) { };
setOverlayMenuActive(true);
const onColorModeChange = (mode) => {
setLayoutColorMode(mode);
};
const onWrapperClick = (event) => {
if (!menuClick) {
setOverlayMenuActive(false);
setMobileMenuActive(false);
} }
setOverlayMenuActive((prevState) => !prevState); if (!mobileTopbarMenuClick) {
setMobileMenuActive(false); setMobileTopbarMenuActive(false);
} else if (layoutMode === 'static') { }
setStaticMenuInactive((prevState) => !prevState);
} mobileTopbarMenuClick = false;
} else { menuClick = false;
setMobileMenuActive((prevState) => !prevState); };
const onToggleMenuClick = (event) => {
menuClick = true;
if (isDesktop()) {
if (layoutMode === 'overlay') {
if (mobileMenuActive === true) {
setOverlayMenuActive(true);
}
setOverlayMenuActive((prevState) => !prevState);
setMobileMenuActive(false);
} else if (layoutMode === 'static') {
setStaticMenuInactive((prevState) => !prevState);
}
} else {
setMobileMenuActive((prevState) => !prevState);
}
event.preventDefault();
};
const onSidebarClick = () => {
menuClick = true;
};
const onMobileTopbarMenuClick = (event) => {
mobileTopbarMenuClick = true;
setMobileTopbarMenuActive((prevState) => !prevState);
event.preventDefault();
};
const onMobileSubTopbarMenuClick = (event) => {
mobileTopbarMenuClick = true;
event.preventDefault();
};
const onMenuItemClick = (event) => {
if (!event.item.items) {
setOverlayMenuActive(false);
setMobileMenuActive(false);
}
};
const isDesktop = () => {
return window.innerWidth >= 992;
};
const menu2 = [
{
label: 'Inicio',
items: [
{ label: 'Dashboard', icon: 'pi pi-fw pi-home', to: '/' },
{ label: 'Administradores del sistema', icon: PrimeIcons.USERS, to: '/administradoresSistema' },
{ label: 'Administradores de comunidad', icon: PrimeIcons.USERS, to: '/administradoresComunidad' },
{ label: 'Comunidades', icon: PrimeIcons.BUILDING, to: '/comunidadesViviendas' },
]
}
]
const menu3 = [
{
label: 'Inicio',
items: [
{ label: 'Dashboard', icon: 'pi pi-fw pi-home', to: '/' },
{ label: 'Inquilinos', icon: PrimeIcons.USERS, to: '/inquilinos' },
{ label: 'Guardas de seguridad', icon: PrimeIcons.LOCK, to: '/guardasSeguridad' },
{
label: 'Áreas Comunes de Comunidad',
icon: PrimeIcons.BUILDING,
to: '/areasComunes',
},
{ label: 'Comunicados', icon: PrimeIcons.COMMENTS, to: '/registroComunicado'},
]
},
]
const menuLogin = [
{
label: 'Inicio',
items: [
{
label: 'Inicio de sesion',
icon: PrimeIcons.BUILDING,
to: '/login'
},
]
},
]
function menu4() {
if (cookies.type == '1') {
return menu2;
} else if (cookies.type == '2') {
return menu3;
} else {
return menuLogin;
}
} }
event.preventDefault(); const menu = [
};
const onSidebarClick = () => {
menuClick = true;
};
const onMobileTopbarMenuClick = (event) => {
mobileTopbarMenuClick = true;
setMobileTopbarMenuActive((prevState) => !prevState);
event.preventDefault();
};
const onMobileSubTopbarMenuClick = (event) => {
mobileTopbarMenuClick = true;
event.preventDefault();
};
const onMenuItemClick = (event) => {
if (!event.item.items) {
setOverlayMenuActive(false);
setMobileMenuActive(false);
}
};
const isDesktop = () => {
return window.innerWidth >= 992;
};
const menu = [
{
label: 'Home',
items: [
{ label: 'Dashboard', icon: 'pi pi-fw pi-home', to: '/' },
{ {
label: 'Administradores del sistema', label: 'Inicio',
icon: PrimeIcons.USERS, items:
to: '/administradoresSistema', [
{
label: 'Administradores del sistema',
icon: PrimeIcons.USERS,
to: '/administradoresSistema',
},
{
label: 'Administradores de comunidad',
icon: PrimeIcons.USERS,
to: '/administradoresComunidad',
},
{
label: 'Guardas de seguridad',
icon: PrimeIcons.LOCK,
to: '/guardasSeguridad',
},
{
label: 'Comunidades',
icon: PrimeIcons.BUILDING,
to: '/comunidadesViviendas',
},
{
label: 'Inquilinos',
icon: PrimeIcons.USER,
to: '/inquilinos'
},
{
label: 'Áreas Comunes de Comunidad',
icon: PrimeIcons.BUILDING,
to: '/areasComunes',
},
{ label: 'Log in', icon: 'pi pi-fw pi-id-card', to: '/logIn' },
],
}, },
{ {
label: 'Administradores de comunidad', label: 'UI Components',
icon: PrimeIcons.USERS, icon: 'pi pi-fw pi-sitemap',
to: '/administradoresComunidad', items: [
{
label: 'Form Layout',
icon: 'pi pi-fw pi-id-card',
to: '/formlayout',
},
{ label: 'Input', icon: 'pi pi-fw pi-check-square', to: '/input' },
{
label: 'Float Label',
icon: 'pi pi-fw pi-bookmark',
to: '/floatlabel',
},
{
label: 'Invalid State',
icon: 'pi pi-fw pi-exclamation-circle',
to: 'invalidstate',
},
{ label: 'Button', icon: 'pi pi-fw pi-mobile', to: '/button' },
{ label: 'Table', icon: 'pi pi-fw pi-table', to: '/table' },
{ label: 'List', icon: 'pi pi-fw pi-list', to: '/list' },
{ label: 'Tree', icon: 'pi pi-fw pi-share-alt', to: '/tree' },
{ label: 'Panel', icon: 'pi pi-fw pi-tablet', to: '/panel' },
{ label: 'Overlay', icon: 'pi pi-fw pi-clone', to: '/overlay' },
{ label: 'Media', icon: 'pi pi-fw pi-image', to: '/media' },
{ label: 'Menu', icon: 'pi pi-fw pi-bars', to: '/menu' },
{ label: 'Message', icon: 'pi pi-fw pi-comment', to: '/messages' },
{ label: 'File', icon: 'pi pi-fw pi-file', to: '/file' },
{ label: 'Chart', icon: 'pi pi-fw pi-chart-bar', to: '/chart' },
{ label: 'Misc', icon: 'pi pi-fw pi-circle-off', to: '/misc' },
],
}, },
{ {
label: 'Guardas de seguridad', label: 'UI Blocks',
icon: PrimeIcons.LOCK, items: [
to: '/guardasSeguridad', {
label: 'Free Blocks',
icon: 'pi pi-fw pi-eye',
to: '/blocks',
badge: 'NEW',
},
{
label: 'All Blocks',
icon: 'pi pi-fw pi-globe',
url: 'https://www.primefaces.org/primeblocks-react',
},
],
}, },
{ {
label: 'Comunidades', label: 'Icons',
icon: PrimeIcons.BUILDING, items: [{ label: 'PrimeIcons', icon: 'pi pi-fw pi-prime', to: '/icons' }],
to: '/comunidadesViviendas',
}, },
{ {
label: 'Inquilinos', label: 'Pages',
icon: PrimeIcons.USER, icon: 'pi pi-fw pi-clone',
to: '/inquilinos' items: [
{ label: 'Crud', icon: 'pi pi-fw pi-user-edit', to: '/crud' },
{ label: 'Timeline', icon: 'pi pi-fw pi-calendar', to: '/timeline' },
{ label: 'Empty', icon: 'pi pi-fw pi-circle-off', to: '/empty' },
],
}, },
{ {
label: 'Áreas Comunes de Comunidad', label: 'Menu Hierarchy',
icon: PrimeIcons.BUILDING, icon: 'pi pi-fw pi-search',
to: '/areasComunes', items: [
{
label: 'Submenu 1',
icon: 'pi pi-fw pi-bookmark',
items: [
{
label: 'Submenu 1.1',
icon: 'pi pi-fw pi-bookmark',
items: [
{ label: 'Submenu 1.1.1', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 1.1.2', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 1.1.3', icon: 'pi pi-fw pi-bookmark' },
],
},
{
label: 'Submenu 1.2',
icon: 'pi pi-fw pi-bookmark',
items: [
{ label: 'Submenu 1.2.1', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 1.2.2', icon: 'pi pi-fw pi-bookmark' },
],
},
],
},
{
label: 'Submenu 2',
icon: 'pi pi-fw pi-bookmark',
items: [
{
label: 'Submenu 2.1',
icon: 'pi pi-fw pi-bookmark',
items: [
{ label: 'Submenu 2.1.1', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 2.1.2', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 2.1.3', icon: 'pi pi-fw pi-bookmark' },
],
},
{
label: 'Submenu 2.2',
icon: 'pi pi-fw pi-bookmark',
items: [
{ label: 'Submenu 2.2.1', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 2.2.2', icon: 'pi pi-fw pi-bookmark' },
],
},
],
},
],
}, },
{ label: 'Log in', icon: 'pi pi-fw pi-id-card', to: '/logIn' }, ];
],
},
{
label: 'UI Components',
icon: 'pi pi-fw pi-sitemap',
items: [
{
label: 'Form Layout',
icon: 'pi pi-fw pi-id-card',
to: '/formlayout',
},
{ label: 'Input', icon: 'pi pi-fw pi-check-square', to: '/input' },
{
label: 'Float Label',
icon: 'pi pi-fw pi-bookmark',
to: '/floatlabel',
},
{
label: 'Invalid State',
icon: 'pi pi-fw pi-exclamation-circle',
to: 'invalidstate',
},
{ label: 'Button', icon: 'pi pi-fw pi-mobile', to: '/button' },
{ label: 'Table', icon: 'pi pi-fw pi-table', to: '/table' },
{ label: 'List', icon: 'pi pi-fw pi-list', to: '/list' },
{ label: 'Tree', icon: 'pi pi-fw pi-share-alt', to: '/tree' },
{ label: 'Panel', icon: 'pi pi-fw pi-tablet', to: '/panel' },
{ label: 'Overlay', icon: 'pi pi-fw pi-clone', to: '/overlay' },
{ label: 'Media', icon: 'pi pi-fw pi-image', to: '/media' },
{ label: 'Menu', icon: 'pi pi-fw pi-bars', to: '/menu' },
{ label: 'Message', icon: 'pi pi-fw pi-comment', to: '/messages' },
{ label: 'File', icon: 'pi pi-fw pi-file', to: '/file' },
{ label: 'Chart', icon: 'pi pi-fw pi-chart-bar', to: '/chart' },
{ label: 'Misc', icon: 'pi pi-fw pi-circle-off', to: '/misc' },
],
},
{
label: 'UI Blocks',
items: [
{
label: 'Free Blocks',
icon: 'pi pi-fw pi-eye',
to: '/blocks',
badge: 'NEW',
},
{
label: 'All Blocks',
icon: 'pi pi-fw pi-globe',
url: 'https://www.primefaces.org/primeblocks-react',
},
],
},
{
label: 'Icons',
items: [{ label: 'PrimeIcons', icon: 'pi pi-fw pi-prime', to: '/icons' }],
},
{
label: 'Pages',
icon: 'pi pi-fw pi-clone',
items: [
{ label: 'Crud', icon: 'pi pi-fw pi-user-edit', to: '/crud' },
{ label: 'Timeline', icon: 'pi pi-fw pi-calendar', to: '/timeline' },
{ label: 'Empty', icon: 'pi pi-fw pi-circle-off', to: '/empty' },
],
},
{
label: 'Menu Hierarchy',
icon: 'pi pi-fw pi-search',
items: [
{
label: 'Submenu 1',
icon: 'pi pi-fw pi-bookmark',
items: [
{
label: 'Submenu 1.1',
icon: 'pi pi-fw pi-bookmark',
items: [
{ label: 'Submenu 1.1.1', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 1.1.2', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 1.1.3', icon: 'pi pi-fw pi-bookmark' },
],
},
{
label: 'Submenu 1.2',
icon: 'pi pi-fw pi-bookmark',
items: [
{ label: 'Submenu 1.2.1', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 1.2.2', icon: 'pi pi-fw pi-bookmark' },
],
},
],
},
{
label: 'Submenu 2',
icon: 'pi pi-fw pi-bookmark',
items: [
{
label: 'Submenu 2.1',
icon: 'pi pi-fw pi-bookmark',
items: [
{ label: 'Submenu 2.1.1', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 2.1.2', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 2.1.3', icon: 'pi pi-fw pi-bookmark' },
],
},
{
label: 'Submenu 2.2',
icon: 'pi pi-fw pi-bookmark',
items: [
{ label: 'Submenu 2.2.1', icon: 'pi pi-fw pi-bookmark' },
{ label: 'Submenu 2.2.2', icon: 'pi pi-fw pi-bookmark' },
],
},
],
},
],
},
];
const addClass = (element, className) => { const addClass = (element, className) => {
if (element.classList) element.classList.add(className); if (element.classList) element.classList.add(className);
else element.className += ' ' + className; else element.className += ' ' + className;
}; };
const removeClass = (element, className) => { const removeClass = (element, className) => {
if (element.classList) element.classList.remove(className); if (element.classList) element.classList.remove(className);
else else
element.className = element.className.replace( element.className = element.className.replace(
new RegExp( new RegExp(
'(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', '(^|\\b)' + className.split(' ').join('|') + '(\\b|$)',
'gi', 'gi',
), ),
' ', ' ',
); );
}; };
const wrapperClass = classNames('layout-wrapper', { const wrapperClass = classNames('layout-wrapper', {
'layout-overlay': layoutMode === 'overlay', 'layout-overlay': layoutMode === 'overlay',
'layout-static': layoutMode === 'static', 'layout-static': layoutMode === 'static',
'layout-static-sidebar-inactive': 'layout-static-sidebar-inactive':
staticMenuInactive && layoutMode === 'static', staticMenuInactive && layoutMode === 'static',
'layout-overlay-sidebar-active': 'layout-overlay-sidebar-active':
overlayMenuActive && layoutMode === 'overlay', overlayMenuActive && layoutMode === 'overlay',
'layout-mobile-sidebar-active': mobileMenuActive, 'layout-mobile-sidebar-active': mobileMenuActive,
'p-input-filled': inputStyle === 'filled', 'p-input-filled': inputStyle === 'filled',
'p-ripple-disabled': ripple === false, 'p-ripple-disabled': ripple === false,
'layout-theme-light': layoutColorMode === 'light', 'layout-theme-light': layoutColorMode === 'light',
}); });
return (
<div className={wrapperClass} onClick={onWrapperClick}>
<Tooltip
ref={copyTooltipRef}
target=".block-action-copy"
position="bottom"
content="Copied to clipboard"
event="focus"
/>
<AppTopbar
onToggleMenuClick={onToggleMenuClick}
layoutColorMode={layoutColorMode}
mobileTopbarMenuActive={mobileTopbarMenuActive}
onMobileTopbarMenuClick={onMobileTopbarMenuClick}
onMobileSubTopbarMenuClick={onMobileSubTopbarMenuClick}
/>
<div className="layout-sidebar" onClick={onSidebarClick}>
<AppMenu
model={menu}
onMenuItemClick={onMenuItemClick}
layoutColorMode={layoutColorMode}
/>
</div>
<div className="layout-main-container"> return (
<div className="layout-main">
<Route
path="/"
exact
render={() => (
<Dashboard colorMode={layoutColorMode} location={location} />
)}
/>
<Route path="/formlayout" component={FormLayoutDemo} />
<Route path="/input" component={InputDemo} />
<Route path="/floatlabel" component={FloatLabelDemo} />
<Route path="/invalidstate" component={InvalidStateDemo} />
<Route path="/button" component={ButtonDemo} />
<Route path="/table" component={TableDemo} />
<Route path="/list" component={ListDemo} />
<Route path="/tree" component={TreeDemo} />
<Route path="/panel" component={PanelDemo} />
<Route path="/overlay" component={OverlayDemo} />
<Route path="/media" component={MediaDemo} />
<Route path="/menu" component={MenuDemo} />
<Route path="/messages" component={MessagesDemo} />
<Route path="/blocks" component={BlocksDemo} />
<Route path="/icons" component={IconsDemo} />
<Route path="/file" component={FileDemo} />
<Route
path="/chart"
render={() => (
<ChartDemo colorMode={layoutColorMode} location={location} />
)}
/>
<Route path="/misc" component={MiscDemo} />
<Route path="/timeline" component={TimelineDemo} />
<Route path="/crud" component={Crud} />
<Route path="/empty" component={EmptyPage} />
<Route path="/documentation" component={Documentation} />
<Route
path="/administradoresSistema"
component={AdministradoresSistema}
/>
<Route
path="/administradoresComunidad"
component={AdministradoresComunidad}
/>
<Route path="/guardasSeguridad" component={GuardasSeguridad} />
<Route path="/comunidadesViviendas" component={Communities} />
<Route path="/inquilinos" component={Inquilinos} />
<Route path="/areasComunes" component={AreasComunes} />
<Route path="/logIn" component={LogIn} />
</div>
<AppFooter layoutColorMode={layoutColorMode} /> <BrowserRouter>
</div> <Switch>
<AppConfig <div className={wrapperClass} onClick={onWrapperClick}>
rippleEffect={ripple}
onRippleEffect={onRipple}
inputStyle={inputStyle}
onInputStyleChange={onInputStyleChange}
layoutMode={layoutMode}
onLayoutModeChange={onLayoutModeChange}
layoutColorMode={layoutColorMode}
onColorModeChange={onColorModeChange}
/>
<CSSTransition
classNames="layout-mask" <Tooltip ref={copyTooltipRef} target=".block-action-copy" position="bottom" content="Copied to clipboard" event="focus" />
timeout={{ enter: 200, exit: 200 }}
in={mobileMenuActive} <AppTopbar onToggleMenuClick={onToggleMenuClick} layoutColorMode={layoutColorMode}
unmountOnExit mobileTopbarMenuActive={mobileTopbarMenuActive} onMobileTopbarMenuClick={onMobileTopbarMenuClick} onMobileSubTopbarMenuClick={onMobileSubTopbarMenuClick} />
>
<div className="layout-mask p-component-overlay"></div> <div className="layout-sidebar" onClick={onSidebarClick}>
</CSSTransition> <AppMenu model={menu4()} onMenuItemClick={onMenuItemClick} layoutColorMode={layoutColorMode} />
</div> </div>
);
}; <div className="layout-main-container">
<div className="layout-main">
{(() => {
if (!cookies.email) {
return (
<>
<Route path="/login" exact component={LogInUser} />
</>
)
} else {
if (cookies.type == '1') {
return (
<>
<Route path="/" exact render={() => <Dashboard colorMode={layoutColorMode} location={location} />} />
<Route path="/administradoresSistema" component={AdministradoresSistema} />
<Route path="/administradoresComunidad" component={AdministradoresComunidad} />
<Route path="/comunidadesViviendas" component={Communities} />
</>
)
} else if (cookies.type == '2') {
return (
<>
<Route path="/" exact render={() => <Dashboard colorMode={layoutColorMode} location={location} />} />
<Route path="/guardasSeguridad" component={GuardasSeguridad} />
<Route path="/inquilinos" component={Inquilinos} />
<Route path="/areasComunes" component={AreasComunes} />
<Route path="/registroComunicado" component={RegistroComunicado} />
</>
)
} else {
return (
<Route path="/page404" exact component={Page404} />
)
}
return (
<>
<Route path="/" exact render={() => <Dashboard colorMode={layoutColorMode} location={location} />} />
<Route path="/formlayout" component={FormLayoutDemo} />
<Route path="/input" component={InputDemo} />
<Route path="/floatlabel" component={FloatLabelDemo} />
<Route path="/invalidstate" component={InvalidStateDemo} />
<Route path="/button" component={ButtonDemo} />
<Route path="/table" component={TableDemo} />
<Route path="/list" component={ListDemo} />
<Route path="/tree" component={TreeDemo} />
<Route path="/panel" component={PanelDemo} />
<Route path="/overlay" component={OverlayDemo} />
<Route path="/media" component={MediaDemo} />
<Route path="/menu" component={MenuDemo} />
<Route path="/messages" component={MessagesDemo} />
{/*<Route path="/blocks" component={BlocksDemo} />*/}
<Route path="/icons" component={IconsDemo} />
<Route path="/file" component={FileDemo} />
<Route path="/chart" render={() => <ChartDemo colorMode={layoutColorMode} location={location} />} />
<Route path="/misc" component={MiscDemo} />
<Route path="/timeline" component={TimelineDemo} />
<Route path="/crud" component={Crud} />
<Route path="/empty" component={EmptyPage} />
<Route path="/documentation" component={Documentation} />
</>
)
}
})()}
</div>
<AppFooter layoutColorMode={layoutColorMode} />
</div>
<AppConfig />
<CSSTransition classNames="layout-mask" timeout={{ enter: 200, exit: 200 }} in={mobileMenuActive} unmountOnExit>
<div className="layout-mask p-component-overlay"></div>
</CSSTransition>
</div>
</Switch>
</BrowserRouter>
);
}
export default App; export default App;

View File

@ -6,171 +6,161 @@ import { Ripple } from 'primereact/ripple';
import { Badge } from 'primereact/badge'; import { Badge } from 'primereact/badge';
const AppSubmenu = (props) => { const AppSubmenu = (props) => {
const [activeIndex, setActiveIndex] = useState(null); const [activeIndex, setActiveIndex] = useState(null);
const onMenuItemClick = (event, item, index) => { const onMenuItemClick = (event, item, index) => {
//avoid processing disabled items //avoid processing disabled items
if (item.disabled) { if (item.disabled) {
event.preventDefault(); event.preventDefault();
return true; return true;
} }
//execute command //execute command
if (item.command) { if (item.command) {
item.command({ originalEvent: event, item: item }); item.command({ originalEvent: event, item: item });
} }
if (index === activeIndex) setActiveIndex(null); if (index === activeIndex) setActiveIndex(null);
else setActiveIndex(index); else setActiveIndex(index);
if (props.onMenuItemClick) { if (props.onMenuItemClick) {
props.onMenuItemClick({ props.onMenuItemClick({
originalEvent: event, originalEvent: event,
item: item, item: item,
}); });
} }
}; };
const onKeyDown = (event) => { const onKeyDown = (event) => {
if (event.code === 'Enter' || event.code === 'Space') { if (event.code === 'Enter' || event.code === 'Space') {
event.preventDefault(); event.preventDefault();
event.target.click(); event.target.click();
} }
}; };
const renderLinkContent = (item) => { const renderLinkContent = (item) => {
let submenuIcon = item.items && ( let submenuIcon = item.items && (
<i className="pi pi-fw pi-angle-down menuitem-toggle-icon"></i> <i className="pi pi-fw pi-angle-down menuitem-toggle-icon"></i>
); );
let badge = item.badge && <Badge value={item.badge} />; let badge = item.badge && <Badge value={item.badge} />;
return (
<React.Fragment>
<i className={item.icon}></i>
<span>{item.label}</span>
{submenuIcon}
{badge}
<Ripple />
</React.Fragment>
);
};
const renderLink = (item, i) => {
let content = renderLinkContent(item);
if (item.to) {
return (
<NavLink
aria-label={item.label}
onKeyDown={onKeyDown}
role="menuitem"
className="p-ripple"
activeClassName="router-link-active router-link-exact-active"
to={item.to}
onClick={(e) => onMenuItemClick(e, item, i)}
exact
target={item.target}
>
{content}
</NavLink>
);
} else {
return (
<a
tabIndex="0"
aria-label={item.label}
onKeyDown={onKeyDown}
role="menuitem"
href={item.url}
className="p-ripple"
onClick={(e) => onMenuItemClick(e, item, i)}
target={item.target}
>
{content}
</a>
);
}
};
let items =
props.items &&
props.items.map((item, i) => {
let active = activeIndex === i;
let styleClass = classNames(item.badgeStyleClass, {
'layout-menuitem-category': props.root,
'active-menuitem': active && !item.to,
});
if (props.root) {
return ( return (
<li className={styleClass} key={i} role="none"> <React.Fragment>
{props.root === true && ( <i className={item.icon}></i>
<React.Fragment> <span>{item.label}</span>
<div {submenuIcon}
className="layout-menuitem-root-text" {badge}
aria-label={item.label} <Ripple />
</React.Fragment>
);
};
const renderLink = (item, i) => {
let content = renderLinkContent(item);
if (item.to) {
return (
<NavLink
aria-label={item.label}
onKeyDown={onKeyDown}
role="menuitem"
className="p-ripple"
activeClassName="router-link-active router-link-exact-active"
to={item.to}
onClick={(e) => onMenuItemClick(e, item, i)}
exact
target={item.target}
> >
{item.label} {content}
</div> </NavLink>
<AppSubmenu );
items={item.items} } else {
onMenuItemClick={props.onMenuItemClick} return (
/> <a
</React.Fragment> tabIndex="0"
)} aria-label={item.label}
</li> onKeyDown={onKeyDown}
); role="menuitem"
} else { href={item.url}
return ( className="p-ripple"
<li className={styleClass} key={i} role="none"> onClick={(e) => onMenuItemClick(e, item, i)}
{renderLink(item, i)} target={item.target}
<CSSTransition >
classNames="layout-submenu-wrapper" {content}
timeout={{ enter: 1000, exit: 450 }} </a>
in={active} );
unmountOnExit }
> };
<AppSubmenu
items={item.items}
onMenuItemClick={props.onMenuItemClick}
/>
</CSSTransition>
</li>
);
}
});
return items ? ( let items =
<ul className={props.className} role="menu"> props.items &&
{items} props.items.map((item, i) => {
</ul> let active = activeIndex === i;
) : null; let styleClass = classNames(item.badgeStyleClass, {
'layout-menuitem-category': props.root,
'active-menuitem': active && !item.to,
});
if (props.root) {
return (
<li className={styleClass} key={i} role="none">
{props.root === true && (
<React.Fragment>
<div
className="layout-menuitem-root-text"
aria-label={item.label}
>
{item.label}
</div>
<AppSubmenu
items={item.items}
onMenuItemClick={props.onMenuItemClick}
/>
</React.Fragment>
)}
</li>
);
} else {
return (
<li className={styleClass} key={i} role="none">
{renderLink(item, i)}
<CSSTransition
classNames="layout-submenu-wrapper"
timeout={{ enter: 1000, exit: 450 }}
in={active}
unmountOnExit
>
<AppSubmenu
items={item.items}
onMenuItemClick={props.onMenuItemClick}
/>
</CSSTransition>
</li>
);
}
});
return items ? (
<ul className={props.className} role="menu">
{items}
</ul>
) : null;
}; };
export const AppMenu = (props) => { export const AppMenu = (props) => {
return ( return (
<div className="layout-menu-container"> <div className="layout-menu-container">
<AppSubmenu <AppSubmenu
items={props.model} items={props.model}
className="layout-menu" className="layout-menu"
onMenuItemClick={props.onMenuItemClick} onMenuItemClick={props.onMenuItemClick}
root={true} root={true}
role="menu" role="menu"
/> />
<a
href="https://www.primefaces.org/primeblocks-react" </div>
className="block mt-3" );
>
<img
alt="primeblocks"
className="w-full" }
src={
props.layoutColorMode === 'light'
? 'assets/layout/images/banner-primeblocks.png'
: 'assets/layout/images/banner-primeblocks-dark.png'
}
/>
</a>
</div>
);
};

View File

@ -1,46 +1,118 @@
import React from 'react'; import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import classNames from 'classnames'; import classNames from 'classnames';
import Cookies from 'universal-cookie';
import { Button } from 'primereact/button';
import { Menubar } from 'primereact/menubar';
const cookies = new Cookies();
export const AppTopbar = (props) => { export const AppTopbar = (props) => {
return ( const [logged, setLogged] = useState(null);
<div className="layout-topbar">
<Link to="/" className="layout-topbar-logo">
<img src={'assets/layout/images/logo-dark.svg'} alt="logo" />
<span>KATOIKIA</span>
</Link>
{/* <button type="button" className="p-link layout-menu-button layout-topbar-button" onClick={props.onToggleMenuClick}>
function cerrarSesion() {
cookies.remove('id', { path: "/" });
cookies.remove('email', { path: "/" });
cookies.remove('name', { path: "/" });
cookies.remove('type', { path: "/" });
cookies.remove('community_id', { path: "/" });
window.location.href = '/login';
}
useEffect(() => {
if (cookies.get('email')) {
setLogged(true);
} else {
setLogged(false);
};
}, [])
const buttonLogout = () => {
return (
<>
<div className="my-2">
<Button label="Cerrar Sesión"
className="p-button-danger"
onClick={cerrarSesion}
disabled={logged} />
</div>
</>
)
}
const menuProfile = [
{
label: 'Perfil',
icon: 'pi pi-user',
items: [
{
label: 'Cerrar Sesion',
icon: 'pi pi-fw pi-lock',
}
],
},
]
return (
<div className="layout-topbar">
<Link to="/" className="layout-topbar-logo">
<img src={'images/Logo_Katoikia.svg'} alt="logo" />
<span>KATOIKIA</span>
</Link>
{/* <button type="button" className="p-link layout-menu-button layout-topbar-button" onClick={props.onToggleMenuClick}>
<i className="pi pi-bars"/> <i className="pi pi-bars"/>
</button> */} </button> */}
<button <button
type="button" type="button"
className="p-link layout-topbar-menu-button layout-topbar-button" className="p-link layout-topbar-menu-button layout-topbar-button"
> >
<i className="pi pi-ellipsis-v" /> <i className="pi pi-ellipsis-v" />
</button> </button>
<ul className="layout-topbar-menu lg:flex origin-top"> <ul className="layout-topbar-menu lg:flex origin-top">
{/* <li> {/* <li>
<button className="p-link layout-topbar-button" onClick={props.onMobileSubTopbarMenuClick}> <button className="p-link layout-topbar-button" onClick={props.onMobileSubTopbarMenuClick}>
<i className="pi pi-calendar"/> <i className="pi pi-calendar"/>
<span>Events</span> <span>Events</span>
</button> </button>
</li> */} </li> */}
{/* <li> {/* <li>
<button className="p-link layout-topbar-button" onClick={props.onMobileSubTopbarMenuClick}> <button className="p-link layout-topbar-button" onClick={props.onMobileSubTopbarMenuClick}>
<i className="pi pi-cog"/> <i className="pi pi-cog"/>
<span>Settings</span> <span>Settings</span>
</button> </button>
</li> */} </li> */}
<li> <li className='mx-2' hidden={!logged}>
<button className="p-link layout-topbar-button"> <button className="p-link layout-topbar-button" >
<i className="pi pi-user" /> <i className="pi pi-user" />
<span>Profile</span> <span>Perfil</span>
</button> </button>
</li> </li>
</ul> <li className='mx-2' hidden={!logged}>
</div> <button className="p-link layout-topbar-button" onClick={cerrarSesion} >
); <i className="pi pi-sign-out" />
}; <span>Cerrar Sesión</span>
</button>
</li>
{/*
<Menubar model={menuProfile} ></Menubar>
</li>
<li hidden={!logged}>
<div className="my-2" >
<Button label="Cerrar Sesión"
className="p-button-danger"
onClick={cerrarSesion}
/>
</div>
</li>*/}
</ul>
</div>
);
}

View File

@ -11,7 +11,7 @@ import { faHome, faUserAlt } from '@fortawesome/free-solid-svg-icons';
import { faPhoneAlt } from '@fortawesome/free-solid-svg-icons'; import { faPhoneAlt } from '@fortawesome/free-solid-svg-icons';
import { faAt } from '@fortawesome/free-solid-svg-icons'; import { faAt } from '@fortawesome/free-solid-svg-icons';
import { faIdCardAlt } from '@fortawesome/free-solid-svg-icons'; import { faIdCardAlt } from '@fortawesome/free-solid-svg-icons';
import { faEllipsis } from '@fortawesome/free-solid-svg-icons'; import { faCircleQuestion } from '@fortawesome/free-solid-svg-icons';
import { faHomeAlt } from '@fortawesome/free-solid-svg-icons'; import { faHomeAlt } from '@fortawesome/free-solid-svg-icons';
import { Dropdown } from 'primereact/dropdown'; import { Dropdown } from 'primereact/dropdown';
import classNames from 'classnames'; import classNames from 'classnames';
@ -31,7 +31,8 @@ const AdministradoresComunidad = () => {
community_name: '', community_name: '',
user_type: '2', user_type: '2',
date_entry: new Date(), date_entry: new Date(),
status: '1' status: '1',
status_text: '',
}; };
const [listaAdmins, setListaAdmins] = useState([]); const [listaAdmins, setListaAdmins] = useState([]);
@ -47,12 +48,23 @@ const AdministradoresComunidad = () => {
const toast = useRef(null); const toast = useRef(null);
const dt = useRef(null); const dt = useRef(null);
const [changeStatusAdminCommunityDialog, setChangeStatusAdminCommunityDialog] = useState(false);
async function listaAdmin() { async function listaAdmin() {
let nombres = await fetch('http://localhost:4000/user/findAdminComunidad/', { method: 'GET' }) await fetch('http://localhost:4000/user/findAdminComunidad/', { method: 'GET' })
.then((response) => response.json()) .then((response) => response.json())
.then((data) => { .then((data) => {
return Promise.all(data.message.map(item => { return Promise.all(data.message.map(item => {
if (item.status == '1') {
item.status_text = 'Activo';
} else if (item.status == '0') {
item.status_text = 'Inactivo';
} else {
item.status_text = 'Eliminado';
}
//item.full_name returns the repositorie name //item.full_name returns the repositorie name
return fetch(`http://localhost:4000/community/findCommunityName/${item.community_id}`, { method: 'GET' }) return fetch(`http://localhost:4000/community/findCommunityName/${item.community_id}`, { method: 'GET' })
.then((response2) => response2.json()) .then((response2) => response2.json())
@ -63,7 +75,13 @@ const AdministradoresComunidad = () => {
}) })
})); }));
}) })
.then(data => setListaAdmins(data)); .then(data => {
data = data.filter(
(val) => val.status != -1,
);
console.log(data)
setListaAdmins(data);
});
} }
@ -72,11 +90,16 @@ const AdministradoresComunidad = () => {
async function getCommunites() { async function getCommunites() {
let response = await fetch('http://localhost:4000/community/allCommunities', { method: 'GET' }); let response = await fetch('http://localhost:4000/community/allCommunities', { method: 'GET' })
let resList = await response.json(); .then((response) => response.json())
let list = await resList.message; .then(data => data.message)
.then(data => {
data = data.filter(
(val) => val.status != -1,
)
setCommunitiesList(data);
setCommunitiesList(await list); })
} }
useEffect(() => { useEffect(() => {
@ -85,7 +108,7 @@ const AdministradoresComunidad = () => {
useEffect(() => { useEffect(() => {
getCommunites(); getCommunites();
},[]) }, [])
const cList = communitiesList.map((item) => ({ const cList = communitiesList.map((item) => ({
label: item.name, label: item.name,
@ -94,64 +117,56 @@ const AdministradoresComunidad = () => {
const deleteAdminCommunity = () => { const deleteAdminCommunity = () => {
/* fetch('http://localhost:4000/community/deleteCommunity/' + community._id, { fetch('http://localhost:4000/user/deleteAdminCommunity/' + adminCommunity._id, {
cache: 'no-cache', cache: 'no-cache',
method: 'DELETE', method: 'DELETE',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
}) })
.then( .then(
function (response) { function (response) {
if (response.status != 201) if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status); console.log('Ocurrió un error con el servicio: ' + response.status);
else else
return response.json(); return response.json();
} }
) )
.then( .then(
function (response) { function (response) {
let _community = communities.filter(val => val._id !== community._id); let _administrators = listaAdmins.filter(
setCommunities(_community); (val) => val._id !== adminCommunity._id,
setDeleteCommunityDialog(false); );
setCommunity(emptyCommunity); setListaAdmins(_administrators);
toast.current.show({ severity: 'success', summary: 'Exito', detail: 'Comunidad de Viviendas Eliminada', life: 3000 }); setDeleteAdminCommunityDialog(false);
} setAdminCommunity(emptyAdminCommunity);
) toast.current.show({ severity: 'success', summary: 'Exito', detail: 'Administrador Comunidad Eliminada', life: 3000 });
.catch( }
err => { )
console.log('Ocurrió un error con el fetch', err) .catch(
toast.current.show({ severity: 'danger', summary: 'Error', detail: 'Comunidad de Viviendas no se pudo eliminar', life: 3000 }); err => {
} console.log('Ocurrió un error con el fetch', err)
); toast.current.show({ severity: 'danger', summary: 'Error', detail: 'Administrador Comunidad no se pudo eliminar', life: 3000 });
*/ }
let _administrators = listaAdmins.filter( );
(val) => val._id !== adminCommunity._id,
);
setListaAdmins(_administrators);
setDeleteAdminCommunityDialog(false);
setAdminCommunity(emptyAdminCommunity);
toast.current.show({
severity: 'success',
summary: 'Administrador de Comunidad Eliminada',
life: 3000,
});
}; };
const deleteSelectedAdminsCommunity = () => { const deleteSelectedAdminsCommunity = () => {
let _admins = listaAdmins.filter( let _admins = listaAdmins.filter(
(val) => !selectedAdminsCommunities.includes(val), (val) => !selectedAdminsCommunities.includes(val),
); );
/* selectedCommunities.map((item) => { selectedAdminsCommunities.map((item) => {
fetch('http://localhost:4000/user/deleteCommunity/' + item._id, { fetch('http://localhost:4000/user/deleteAdminCommunity/' + item._id, {
cache: 'no-cache', cache: 'no-cache',
method: 'DELETE', method: 'DELETE',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
}) })
})*/ })
setListaAdmins(_admins); setListaAdmins(_admins);
setDeleteAdminsCommunitiesDialog(false); setDeleteAdminsCommunitiesDialog(false);
setSelectedAdminsCommunities(null); setSelectedAdminsCommunities(null);
@ -163,6 +178,52 @@ const AdministradoresComunidad = () => {
}); });
}; };
const cambiarStatusAdminCommuniy = () => {
if (adminCommunity.status == '1') {
adminCommunity.status = '0';
adminCommunity.status_text = 'Inactivo';
} else if (adminCommunity.status == '0') {
adminCommunity.status = '1';
adminCommunity.status_text = 'Activo';
}
var data = {
id: adminCommunity._id,
status: adminCommunity.status,
};
fetch('http://localhost:4000/user/changeStatus', {
cache: 'no-cache',
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(
function (response) {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else
return response.json();
}
)
.then(
function (response) {
setChangeStatusAdminCommunityDialog(false);
toast.current.show({
severity: 'success',
summary: 'Éxito',
detail: 'Administrador de Comunidad Actualizado',
life: 3000,
});
}
)
.catch(
err => console.log('Ocurrió un error con el fetch', err)
);
}
const saveAdminCommunity = () => { const saveAdminCommunity = () => {
if (adminCommunity.name && adminCommunity.dni && adminCommunity.last_name && adminCommunity.email && adminCommunity.phone) { if (adminCommunity.name && adminCommunity.dni && adminCommunity.last_name && adminCommunity.email && adminCommunity.phone) {
@ -228,11 +289,33 @@ const AdministradoresComunidad = () => {
setDeleteAdminsCommunitiesDialog(true); setDeleteAdminsCommunitiesDialog(true);
}; };
const hideChangeStatusAdmimCommunityDialog = () => {
setChangeStatusAdminCommunityDialog(false);
};
const confirmChangeStatuAdminCommunity = (adminCommunity) => {
setAdminCommunity(adminCommunity);
setChangeStatusAdminCommunityDialog(true);
};
const actionsAdminCommunity = (rowData) => { const actionsAdminCommunity = (rowData) => {
let icono = '';
let text = '';
if (rowData.status == '0') {
icono = "pi pi-eye";
text = "Activar Administrador de Comunidad"
} else if (rowData.status == '1') {
icono = "pi pi-eye-slash";
text = "Inactivar Administrador de Comunidad"
}
return ( return (
<div className="actions"> <div className="actions">
<Button
icon={`${icono}`}
className="p-button-rounded p-button-warning mt-2 mx-2"
onClick={() => confirmChangeStatuAdminCommunity(rowData)}
title={`${text}`}
/>
<Button <Button
icon="pi pi-trash" icon="pi pi-trash"
className="p-button-rounded p-button-danger mt-2" className="p-button-rounded p-button-danger mt-2"
@ -257,6 +340,22 @@ const AdministradoresComunidad = () => {
</> </>
); );
const changeStatusAdminCommunityDialogFooter = (
<>
<Button
label="No"
icon="pi pi-times"
className="p-button-text"
onClick={hideChangeStatusAdmimCommunityDialog}
/>
<Button
label="Yes"
icon="pi pi-check"
className="p-button-text"
onClick={cambiarStatusAdminCommuniy}
/>
</>
);
const leftToolbarTemplate = () => { const leftToolbarTemplate = () => {
return ( return (
@ -344,7 +443,16 @@ const AdministradoresComunidad = () => {
</> </>
) )
const headerStatus = (
<>
<p> {' '}
<FontAwesomeIcon icon={faCircleQuestion} style={{ color: "#C08135" }} />{' '}
Estado
</p>
</>
)
const onInputChange = (e, name) => { const onInputChange = (e, name) => {
const val = (e.target && e.target.value) || ''; const val = (e.target && e.target.value) || '';
@ -360,6 +468,18 @@ const AdministradoresComunidad = () => {
console.log(getCommunityValue) console.log(getCommunityValue)
} }
const statusBodyTemplate = (rowData) => {
return (
<>
<span
className={`status status-${rowData.status}`}
>
{rowData.status_text}
</span>
</>
);
};
return ( return (
@ -380,9 +500,10 @@ const AdministradoresComunidad = () => {
<Column field="dni" sortable header={headerDNI} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}> <Column field="dni" sortable header={headerDNI} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}>
</Column> </Column>
<Column field="email" sortable header={headerEmail} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column> <Column field="email" sortable header={headerEmail} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column>
<Column field="phone" header={headerPhone} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column> <Column field="phone" header={headerPhone} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column>
<Column field="community_name" sortable header={headerCommuntiy} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column> <Column field="community_name" sortable header={headerCommuntiy} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column>
<Column style={{ flexGrow: 1, flexBasis: '130px', minWidth: '130px' }} body={actionsAdminCommunity}></Column> <Column field="status" sortable header={headerStatus} body={statusBodyTemplate} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column>
<Column style={{ flexGrow: 1, flexBasis: '130px', minWidth: '130px' }} body={actionsAdminCommunity}></Column>
</DataTable> </DataTable>
<Dialog visible={deleteAdminCommunityDialog} style={{ width: '450px' }} header="Confirmar" modal footer={deleteAdminCommunityDialogFooter} onHide={hideDeleteAdminCommunityDialog}> <Dialog visible={deleteAdminCommunityDialog} style={{ width: '450px' }} header="Confirmar" modal footer={deleteAdminCommunityDialogFooter} onHide={hideDeleteAdminCommunityDialog}>
<div className="flex align-items-center justify-content-center"> <div className="flex align-items-center justify-content-center">
@ -396,6 +517,26 @@ const AdministradoresComunidad = () => {
{selectedAdminsCommunities && <span>¿Está seguro eliminar los administradores de las comunidades de viviendas seleccionados?</span>} {selectedAdminsCommunities && <span>¿Está seguro eliminar los administradores de las comunidades de viviendas seleccionados?</span>}
</div> </div>
</Dialog> </Dialog>
<Dialog
visible={changeStatusAdminCommunityDialog}
style={{ width: '450px' }}
header="Confirmar"
modal
footer={changeStatusAdminCommunityDialogFooter}
onHide={hideChangeStatusAdmimCommunityDialog}
>
<div className="flex align-items-center justify-content-center">
<i
className="pi pi-exclamation-triangle mr-3"
style={{ fontSize: '2rem' }}
/>
{adminCommunity && (
<span>
¿Estás seguro que desea cambiar estado a <b>{adminCommunity.name}</b>?
</span>
)}
</div>
</Dialog>
</div> </div>
</div> </div>
<div className="col-12"> <div className="col-12">

View File

@ -44,7 +44,6 @@ const AdministradoresSistema = () => {
status_text: '', status_text: '',
}; };
async function fetchP() { async function fetchP() {
let nombres = await fetch(urlFetch, { method: 'GET' }); let nombres = await fetch(urlFetch, { method: 'GET' });
let adminRes = await nombres.json(); let adminRes = await nombres.json();
@ -60,11 +59,11 @@ const AdministradoresSistema = () => {
}) })
setAdministrators(await data); setAdministrators(await data);
} }
useEffect(() => { useEffect(() => {
fetchP(); fetchP();
}, []) }, [])
function registrarAdmin() { function registrarAdmin() {
var data = { var data = {
dni: document.getElementById('identificacion').value, dni: document.getElementById('identificacion').value,

View File

@ -15,16 +15,15 @@ import { faIdCardAlt } from '@fortawesome/free-solid-svg-icons';
import { faClipboardCheck } from '@fortawesome/free-solid-svg-icons'; import { faClipboardCheck } from '@fortawesome/free-solid-svg-icons';
import classNames from 'classnames'; import classNames from 'classnames';
import { useCookies } from "react-cookie"; import { useCookies } from "react-cookie";
import { RadioButton } from 'primereact/radiobutton';
const AreasComunes = () => { const AreasComunes = () => {
let emptyCommonArea = { let emptyCommonArea = {
_id: null, _id: null,
dni: '',
name: '', name: '',
hourMin: '', hourMin: '00:00',
hourMax: '', hourMax: '01:00',
community_id: '', community_id: '',
bookable: '1', bookable: '1',
bookable_text: '', bookable_text: '',
@ -32,6 +31,7 @@ const AreasComunes = () => {
status_text: '', status_text: '',
}; };
const [commonAreaList, setCommonAreaList] = useState([]); const [commonAreaList, setCommonAreaList] = useState([]);
const [commonArea, setCommonArea] = useState(emptyCommonArea); const [commonArea, setCommonArea] = useState(emptyCommonArea);
const [selectedCommonAreas, setSelectedCommonAreas] = useState(null); const [selectedCommonAreas, setSelectedCommonAreas] = useState(null);
@ -43,6 +43,9 @@ const AreasComunes = () => {
const dt = useRef(null); const dt = useRef(null);
const [cookies, setCookie] = useCookies(); const [cookies, setCookie] = useCookies();
const [changeStatusAreaDialog, setChangeStatusAreaDialog] = useState(false);
async function getCommonAreas() { async function getCommonAreas() {
await fetch(`http://localhost:4000/commonArea/findByCommunity/${cookies.community_id}`, { method: 'GET' }) await fetch(`http://localhost:4000/commonArea/findByCommunity/${cookies.community_id}`, { method: 'GET' })
@ -78,6 +81,74 @@ const AreasComunes = () => {
getCommonAreas(); getCommonAreas();
}, []); }, []);
const saveCommonArea = () => {
if (
commonArea.name &&
commonArea.hourMin < commonArea.hourMax
) {
let _common_areas = [...commonAreaList];
let _common_area = { ...commonArea };
_common_area.community_id = cookies.community_id;
// console.log(houses)
fetch('http://localhost:4000/commonArea/createCommonArea', {
cache: 'no-cache',
method: 'POST',
body: JSON.stringify(_common_area),
headers: {
'Content-Type': 'application/json',
},
})
.then(function (response) {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else return response.json();
})
.then(function (data) {
return data.message;
})
.then((data) => {
if (data) {
if (data.bookable == '1') {
data.bookable_text = 'Necesaria';
} else {
data.bookable_text = 'No es necesaria';
}
if (data.status == '1') {
data.status_text = 'Activo';
} else if (data.status == '0') {
data.status_text = 'Inactivo';
} else {
data.status_text = 'Eliminado';
}
}
_common_areas.push(data);
toast.current.show({
severity: 'success',
summary: 'Registro exitoso',
detail: 'Área Común Creada',
life: 3000,
});
setCommonAreaList(_common_areas);
setCommonArea(emptyCommonArea);
})
.catch((err) => {
console.log('Ocurrió un error con el fetch', err);
toast.current.show({
severity: 'danger',
summary: 'Error',
detail: 'No se pudo registrar el área común',
life: 3000
});
});
} else {
setSubmitted(true);
}
};
const deleteCommonArea = () => { const deleteCommonArea = () => {
fetch('http://localhost:4000/commonArea/deleteCommonArea/' + commonArea._id, { fetch('http://localhost:4000/commonArea/deleteCommonArea/' + commonArea._id, {
@ -150,6 +221,51 @@ const AreasComunes = () => {
}); });
}; };
const cambiarStatuscommonArea = () => {
if (commonArea.status == '1') {
commonArea.status = '0';
commonArea.status_text = 'Inactivo';
} else if (commonArea.status == '0') {
commonArea.status = '1';
commonArea.status_text = 'Activo';
}
var data = {
id: commonArea._id,
status: commonArea.status,
};
fetch('http://localhost:4000/commonArea/changeStatus', {
cache: 'no-cache',
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(
function (response) {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else
return response.json();
}
)
.then(
function (response) {
setChangeStatusAreaDialog(false);
toast.current.show({
severity: 'success',
summary: 'Éxito',
detail: 'Área Común Actualizada',
life: 3000,
});
}
)
.catch(
err => console.log('Ocurrió un error con el fetch', err)
);
}
const hideDeleteCommonAreaDialog = () => { const hideDeleteCommonAreaDialog = () => {
setDeleteCommonAreaDialog(false); setDeleteCommonAreaDialog(false);
} }
@ -169,9 +285,34 @@ const AreasComunes = () => {
const hideChangeStatusAreaDialog = () => {
setChangeStatusAreaDialog(false);
};
const confirmChangeStatusArea = (commonArea) => {
setCommonArea(commonArea);
setChangeStatusAreaDialog(true);
};
const actionsCommonArea = (rowData) => { const actionsCommonArea = (rowData) => {
let icono = '';
let text = '';
if (rowData.status == '0') {
icono = "pi pi-eye";
text = "Activar Área Común"
} else if (rowData.status == '1') {
icono = "pi pi-eye-slash";
text = "Inactivar Área Común"
}
return ( return (
<div className="actions"> <div className="actions">
<Button
icon={`${icono}`}
className="p-button-rounded p-button-warning mt-2 mx-2"
onClick={() => confirmChangeStatusArea(rowData)}
title={`${text}`}
/>
<Button <Button
icon="pi pi-trash" icon="pi pi-trash"
className="p-button-rounded p-button-danger mt-2" className="p-button-rounded p-button-danger mt-2"
@ -181,6 +322,18 @@ const AreasComunes = () => {
); );
}; };
const onBookableChange = (e) => {
let _commonArea = { ...commonArea };
_commonArea['bookable'] = e.value;
setCommonArea(_commonArea);
};
const onInputChange = (e, name) => {
const val = (e.target && e.target.value) || '';
let _commonArea = { ...commonArea };
_commonArea[`${name}`] = val;
setCommonArea(_commonArea);
};
const deleteCommonAreaDialogFooter = ( const deleteCommonAreaDialogFooter = (
<> <>
@ -196,6 +349,22 @@ const AreasComunes = () => {
</> </>
); );
const changeStatusAreaDialogFooter = (
<>
<Button
label="No"
icon="pi pi-times"
className="p-button-text"
onClick={hideChangeStatusAreaDialog}
/>
<Button
label="Yes"
icon="pi pi-check"
className="p-button-text"
onClick={cambiarStatuscommonArea}
/>
</>
);
const leftToolbarTemplate = () => { const leftToolbarTemplate = () => {
return ( return (
@ -278,7 +447,7 @@ const AreasComunes = () => {
const bookableBodyTemplate = (rowData) => { const bookableBodyTemplate = (rowData) => {
let class_color = ''; let class_color = '';
if(rowData.bookable == '1') { if (rowData.bookable == '1') {
class_color = '0'; class_color = '0';
} else { } else {
class_color = '1'; class_color = '1';
@ -307,6 +476,18 @@ const AreasComunes = () => {
); );
}; };
function compareTimesMinRequired(hour1, hour2) {
var timeFormat1 = Number(hour1.replace(/[:]/g, ''));
var timeFormat2 = Number(hour2.replace(/[:]/g, ''));
if (timeFormat1 <= timeFormat2) {
return true;
} else {
return false;
}
}
return ( return (
<div className="grid"> <div className="grid">
<div className="col-12"> <div className="col-12">
@ -339,8 +520,146 @@ const AreasComunes = () => {
{selectedCommonAreas && <span>¿Está seguro eliminar las áreas comunes seleccionadas?</span>} {selectedCommonAreas && <span>¿Está seguro eliminar las áreas comunes seleccionadas?</span>}
</div> </div>
</Dialog> </Dialog>
<Dialog
visible={changeStatusAreaDialog}
style={{ width: '450px' }}
header="Confirmar"
modal
footer={changeStatusAreaDialogFooter}
onHide={hideChangeStatusAreaDialog}
>
<div className="flex align-items-center justify-content-center">
<i
className="pi pi-exclamation-triangle mr-3"
style={{ fontSize: '2rem' }}
/>
{commonArea && (
<span>
¿Estás seguro que desea cambiar estado a <b>{commonArea.name}</b>?
</span>
)}
</div>
</Dialog>
</div> </div>
</div> </div>
<div className="col-12">
<div className="card">
<h5>Registro de área común</h5>
<div className="p-fluid formgrid grid">
<div className="field col-12 md:col-6">
<label htmlFor="name">Nombre</label>
<div className="p-0 col-12 md:col-12">
<div className="p-inputgroup">
<span className="p-inputgroup-addon p-button p-icon-input-khaki">
<i className="pi pi-home"></i>
</span>
<InputText id="name"
type="text"
onChange={(e) => onInputChange(e, 'name')}
value={commonArea.name}
required
autoFocus
className={classNames({
'p-invalid': submitted && commonArea.name === '',
})}
/>
</div>
{submitted && commonArea.name === '' && (
<small className="p-invalid">Nombre es requirido.</small>
)}
</div>
</div>
<div className="field col-12 md:col-6">
<label htmlFor="hourMin">Hora apertura</label>
<div className="p-0 col-12 md:col-12">
<div className="p-inputgroup">
<span className="p-inputgroup-addon p-button p-icon-input-khaki">
<i className="pi pi-home"></i>
</span>
<InputText id="hourMin"
type="time"
min="00:00" max="23:59"
step="3600000"
onChange={(e) => onInputChange(e, 'hourMin')}
value={commonArea.hourMin}
required
autoFocus
className={classNames({
'p-invalid': submitted && compareTimesMinRequired(commonArea.hourMax, commonArea.hourMin),
})}
/>
</div>
{submitted && compareTimesMinRequired(commonArea.hourMax, commonArea.hourMin) && (
<small className="p-invalid">La hora de apertura debe ser menor que la hora de cierre.</small>
)}
</div>
</div>
<div className="field col-12 md:col-6">
<label htmlFor="hourMax">Hora de cierre</label>
<div className="p-0 col-12 md:col-12">
<div className="p-inputgroup">
<span className="p-inputgroup-addon p-button p-icon-input-khaki">
<i className="pi pi-home"></i>
</span>
<InputText id="hourMax"
type="time"
min="00:00" max="23:59"
step="3600000"
onChange={(e) => onInputChange(e, 'hourMax')}
value={commonArea.hourMax}
required
autoFocus
className={classNames({
'p-invalid': submitted && compareTimesMinRequired(commonArea.hourMax, commonArea.hourMin),
})}
/>
</div>
{submitted && compareTimesMinRequired(commonArea.hourMax, commonArea.hourMin) && (
<small className="p-invalid">La hora de cierre debe ser mayor que la hora de apertura</small>
)}
</div>
</div>
<div className="field col-12 md:col-6">
<label htmlFor="bookable">¿Necesita Reservación?</label>
<div className="formgrid grid align-items-end" style={{ marginTop: '12px', width: '300px' }}>
<div className="field-radiobutton col-6">
<RadioButton
inputId="bookable1"
name="bookable"
value="1"
onChange={onBookableChange}
checked={commonArea.bookable === '1'}
/>
<label htmlFor="bookable1">
<span className="p-icon-input-khaki">
<i className="pi pi-check status status-1"></i> Sí
</span>
</label>
</div>
<div className="field-radiobutton col-6">
<RadioButton
inputId="bookable2"
name="bookable"
value="0"
onChange={onBookableChange}
checked={commonArea.bookable === '0'}
/>
<label htmlFor="bookable2">
<span className="p-icon-input-khaki">
<i className="pi pi-times status status-0"></i> No
</span>
</label>
</div>
</div>
</div>
<Button label="Registrar" onClick={saveCommonArea}></Button>
</div>
</div>
</div>
</div> </div>
); );

View File

@ -708,7 +708,11 @@ const Communities = () => {
const tenantsBodyTemplate = (rowData) => { const tenantsBodyTemplate = (rowData) => {
let tenants = rowData.tenants; let tenants = rowData.tenants;
let name = findNameTenant(tenants.tenant_id); let name = 'Sin inquilino';
if (rowData.tenants) {
name = findNameTenant(tenants.tenant_id);
}
return ( return (
<> <>
{name} {name}

View File

@ -15,8 +15,23 @@ import { faCircleQuestion } from '@fortawesome/free-solid-svg-icons';
import { useCookies } from "react-cookie"; import { useCookies } from "react-cookie";
const GuardasSeguridad = () => { const GuardasSeguridad = () => {
let emptyGuarda = {
_id: null,
dni: '',
name: '',
last_name: '',
email: '',
phone: '',
password: '',
user_type: '1',
status: '1',
status_text: '',
};
const [listaGuardas, setListaGuardas] = useState([]); const [listaGuardas, setListaGuardas] = useState([]);
const [urlFetch, setUrlFetch] = useState('http://localhost:4000/user/findGuards/62be68215692582bbfd77134'); const [urlFetch, setUrlFetch] = useState('http://localhost:4000/user/findGuards/');
const [guarda, setGuarda] = useState(emptyGuarda); const [guarda, setGuarda] = useState(emptyGuarda);
const [selectedGuardas, setSelectedGuardas] = useState(null); const [selectedGuardas, setSelectedGuardas] = useState(null);
const [globalFilter, setGlobalFilter] = useState(null); const [globalFilter, setGlobalFilter] = useState(null);
@ -28,23 +43,12 @@ const GuardasSeguridad = () => {
const [cookies, setCookie] = useCookies(); const [cookies, setCookie] = useCookies();
const [changeStatusGuardDialog, setChangeStatusGuardDialog] = useState(false); const [changeStatusGuardDialog, setChangeStatusGuardDialog] = useState(false);
let emptyGuarda = { const [guardDialog, setGuardDialog] = useState(false);
_id: null, const [submitted, setSubmitted] = useState(false);
dni: '',
name: '',
last_name: '',
email: '',
phone: '',
password: '',
user_type: '1',
status: '',
status_text: '',
};
async function listaGuardasF() { async function listaGuardasF() {
let nombres = await fetch(urlFetch, { method: 'GET' }); let nombres = await fetch((urlFetch + cookies.community_id), { method: 'GET' });
let listaGuardasRes = await nombres.json(); let listaGuardasRes = await nombres.json();
let data = await listaGuardasRes.message.filter( let data = await listaGuardasRes.message.filter(
(val) => val.status != -1, (val) => val.status != -1,
@ -58,6 +62,7 @@ const GuardasSeguridad = () => {
}) })
setListaGuardas(await data); setListaGuardas(await data);
} }
useEffect(() => { useEffect(() => {
listaGuardasF(); listaGuardasF();
}, []) }, [])
@ -236,8 +241,18 @@ const GuardasSeguridad = () => {
setChangeStatusGuardDialog(true); setChangeStatusGuardDialog(true);
}; };
const hideGuardDialog = () => {
setSubmitted(false);
setGuardDialog(false);
};
const actionsAdmin = (rowData) => { const infoGuard = (guard) => {
setGuarda(guard);
setGuardDialog(true);
};
const actionsGuard = (rowData) => {
let icono = ''; let icono = '';
let text = ''; let text = '';
if (rowData.status == '0') { if (rowData.status == '0') {
@ -250,6 +265,11 @@ const GuardasSeguridad = () => {
} }
return ( return (
<div className="actions"> <div className="actions">
<Button
icon="pi pi-exclamation-circle"
className="p-button-rounded p-button-info mt-2 mx-2"
onClick={() => infoGuard(rowData)}
/>
<Button <Button
icon={`${icono}`} icon={`${icono}`}
className="p-button-rounded p-button-warning mt-2 mx-2" className="p-button-rounded p-button-warning mt-2 mx-2"
@ -328,6 +348,19 @@ const GuardasSeguridad = () => {
</> </>
); );
const guardDialogFooter = (
<>
<Button
label="Cerrar"
icon="pi pi-times"
className="p-button-text"
onClick={hideGuardDialog}
/>
</>
);
const headerName = ( const headerName = (
<> <>
<p>{' '} <p>{' '}
@ -420,8 +453,78 @@ const GuardasSeguridad = () => {
body={statusBodyTemplate} body={statusBodyTemplate}
style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}> style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}>
</Column> </Column>
<Column style={{ flexGrow: 1, flexBasis: '80px', minWidth: '80px' }} body={actionsAdmin}></Column> <Column style={{ flexGrow: 1, flexBasis: '80px', minWidth: '80px' }} body={actionsGuard}></Column>
</DataTable> </DataTable>
<Dialog
visible={guardDialog}
style={{ width: '650px' }}
header="Información del Guarda de Seguridad"
modal
className="p-fluid"
footer={guardDialogFooter}
onHide={hideGuardDialog}>
<div className='container text-center'>
<div className='row my-4'>
<div className=" col-4 md:col-4">
<p>Nombre</p>
<div className="p-0 col-2 md:col-2" style={{ margin: '0 auto' }}>
<div className="p-inputgroup align-items-center justify-content-evenly">
<i className="pi pi-user icon-khaki"></i>
<p>{guarda.name}</p>
</div>
</div>
</div>
<div className=" col-4 md:col-4">
<p>Apellido(s)</p>
<div className="p-0 col-6 md:col-6" style={{ margin: '0 auto' }}>
<div className="p-inputgroup align-items-center justify-content-evenly">
<i className="pi pi-user icon-khaki"></i>
<p>{guarda.last_name}</p>
</div>
</div>
</div>
<div className=" col-4 col-md-4 md:col-4">
<p>Identificación</p>
<div className="p-0 col-10 md:col-10" style={{ margin: '0 auto' }}>
<div className="p-inputgroup align-items-center justify-content-evenly">
<i className="pi pi-id-card icon-khaki"></i>
<p>{guarda.dni}</p>
</div>
</div>
</div>
</div>
<div className='row my-5 justify-content-center'>
</div>
<div className='row my-5 justify-content-center'>
<div className=" col-4 md:col-4">
<p>Teléfono</p>
<div className="p-0 col-10 md:col-10">
<div className="p-inputgroup align-items-center justify-content-evenly">
<i className="pi pi-phone icon-khaki"></i>
<p>{guarda.phone}</p>
</div>
</div>
</div>
<div className=" col-6 md:col-6">
<p>Correo Electrónico</p>
<div className="p-0 col-10 md:col-10" style={{ margin: '0 auto' }}>
<div className="p-inputgroup align-items-center justify-content-evenly">
<i className="pi pi-envelope icon-khaki"></i>
<p>{guarda.email}</p>
</div>
</div>
</div>
</div>
</div>
</Dialog>
<Dialog visible={deleteGuardaDialog} style={{ width: '450px' }} header="Confirmar" modal footer={deleteAdminSystemDialogFooter} onHide={hideDeleteGuardaDialog}> <Dialog visible={deleteGuardaDialog} style={{ width: '450px' }} header="Confirmar" modal footer={deleteAdminSystemDialogFooter} onHide={hideDeleteGuardaDialog}>
<div className="flex align-items-center justify-content-center"> <div className="flex align-items-center justify-content-center">
<i className="pi pi-exclamation-triangle mr-3" style={{ fontSize: '2rem' }} /> <i className="pi pi-exclamation-triangle mr-3" style={{ fontSize: '2rem' }} />

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
import React from 'react';
import { InputText } from 'primereact/inputtext';
const LogIn = () => {
return (
<div className="grid">
<div className="col-12">
<div className="card">
<h5>Iniciar Sesión</h5>
<div className="p-fluid formgrid grid">
<div className="field col-12">
<label htmlFor="nombre">Correo electrónico</label>
<InputText id="nombre" type="text" />
</div>
<div className="field col-12 ">
<label htmlFor="apellidos">Contraseña</label>
<InputText id="apellidos" type="text" />
</div>
{/* <Button label="Registrar" onClick={registrarAdmin}></Button> */}
</div>
</div>
</div>
</div>
);
};
export default LogIn;
/* image 1 */

View File

@ -0,0 +1,226 @@
import React, { Component, Fragment, useRef } from 'react';
import Cookies from 'universal-cookie';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import { Toast } from 'primereact/toast';
const baseUrl = "http://localhost:4000/user/loginUser";
const cookies = new Cookies();
class LogInUser extends Component {
constructor(props) {
super(props);
this.state = {
form: {
email: '',
password: ''
},
errorEmail: false,
errorPassword: false,
logged: null
}
}
handleChange = async e => {
await this.setState({
form: {
...this.state.form,
[e.target.name]: e.target.value
}
});
}
validaciones = (data) => {
let error = false;
if (data.email == '') {
this.setState({
errorEmail: true
})
error = true;
} else {
this.setState({
errorEmail: false
})
}
if (data.password == '') {
this.setState({
errorPassword: true
})
error = true;
} else {
this.setState({
errorPassword: false
})
}
return error;
}
iniciarSesion = async () => {
const data = {
email: this.state.form.email,
password: this.state.form.password
}
console.log(data);
if (!this.validaciones(data)) {
this.setState({
email: true,
password: true
})
await fetch(baseUrl, {
cache: 'no-cache',
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else return response.json();
})
.then(response => {
console.log(response.message);
if (response.message) {
const user = response.message;
if(user.user_type == '1' || user.user_type == '2'){
cookies.set('id', user._id, { path: "/" });
cookies.set('name', user.name, { path: "/" });
cookies.set('email', user.email, { path: "/" });
cookies.set('type', user.user_type, { path: "/" });
if (user.user_type != '1') {
cookies.set('community_id', user.community_id, { path: "/" });
}
// alert(`Bienvenido ${user.name}`);
document.getElementById('notification').hidden = true;
document.getElementById('notification2').hidden = false;
document.getElementById("message2").innerHTML = `Bienvenido ${user.name}`;
window.location.href = "/";
}
window.location.href = "/page404";
} else {
document.getElementById('notification2').hidden = true;
document.getElementById('notification').hidden = false;
//alert('El usuario o la contraseña no son correctos');
document.getElementById("message").innerHTML = "El usuario o la contraseña son incorrectos";
}
})
.catch(error => {
console.log(error);
})
}
}
componentDidMount() {
if (cookies.get('email')) {
window.location.href = "/";
}
}
renderErrorMessage = (name) =>
name === this.state.errorMessages.name && (
<div className="error">{this.state.errorMessages.message}</div>
);
errors = {
email: "Correo requerido",
pass: "Contraseña requerida"
};
render() {
return (
<Fragment>
<div className="grid ">
<div className="col-10 xl:col-8">
<div id="notification" className="p-message p-message-error" hidden={true} >
<div className="card">
<h5 className='card-header' id="message">
</h5>
</div>
</div>
<div id="notification2" className="p-message p-message-success" hidden={true} >
<div className="card">
<h5 className='card-header' id="message2">
</h5>
</div>
</div>
</div>
<div className="col-10 xl:col-8">
<div className="card">
<h5 className='card-header'>Iniciar Sesión</h5>
<div className="p-fluid formgrid grid">
<div className="field col-12 md:col-12">
<label htmlFor="email">Correo electrónico</label>
<div className="p-0 col-12 md:col-12">
<div className="p-inputgroup">
<span className="p-inputgroup-addon p-button p-icon-input-khaki">
<i className="pi pi-user"></i>
</span>
<InputText id="email"
type="email"
name="email"
onChange={this.handleChange}
placeholder='Correo electrónico'
className={this.state.errorEmail ? 'p-invalid' : ''}
/>
</div>
{this.state.errorEmail && (
<small className="p-invalid">Correo electrónico es requerido</small>
)}
</div>
</div>
<div className="field col-12 md:col-12">
<label htmlFor="v">Contraseña</label>
<div className="p-0 col-12 md:col-12">
<div className="p-inputgroup">
<span className="p-inputgroup-addon p-button p-icon-input-khaki">
<i className="pi pi-lock"></i>
</span>
<InputText id="password"
type="password"
name="password"
onChange={this.handleChange}
placeholder='Contraseña'
className={this.state.errorPassword ? 'p-invalid' : ''}
/>
</div>
{this.state.errorPassword && (
<small className="p-invalid">Contraseña es requerida</small>
)}
</div>
</div>
<Button label="Iniciar sesión" type="button" onClick={() => this.iniciarSesion()}></Button>
</div>
</div>
</div>
</div>
</Fragment>
);
}
}
export default LogInUser;

View File

@ -0,0 +1,20 @@
import React from 'react';
const Page404 = () => {
return (
<div className="col-12 xl:col-12">
<div className="card">
<div className="surface-section px-4 py-8 md:px-6 lg:px-8">
<div className="text-700 text-center">
<div className="text-900 font-bold text-5xl mb-3">404</div>
<div className="text-700 text-2xl mb-5">No se encuentra la página</div>
</div>
</div>
</div>
</div>
)
}
export default React.memo(Page404)

View File

@ -0,0 +1,165 @@
import React, { useEffect, useState, useRef } from 'react';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import { InputTextarea } from 'primereact/inputtextarea';
import { useCookies } from "react-cookie";
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { Toast } from 'primereact/toast';
import { Dialog } from 'primereact/dialog';
import { Toolbar } from 'primereact/toolbar';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faHome, faUserAlt } from '@fortawesome/free-solid-svg-icons';
import { faCommentAlt } from '@fortawesome/free-solid-svg-icons';
import { faPhoneAlt } from '@fortawesome/free-solid-svg-icons';
import { faAt } from '@fortawesome/free-solid-svg-icons';
import { faIdCardAlt } from '@fortawesome/free-solid-svg-icons';
import { faEllipsis } from '@fortawesome/free-solid-svg-icons';
import { faHomeAlt } from '@fortawesome/free-solid-svg-icons';
import { Dropdown } from 'primereact/dropdown';
import classNames from 'classnames';
const RegistroComunicado = () => {
let emptyComunicado = {
_id: null,
post: '',
user_id: '',
community_id: ''
};
useEffect(()=>{
listaComunis();
},[])
const [comunicado, setComunicado] = useState(emptyComunicado);
const [comunicados,setComuicados]=useState([]);
const [comunicadoId, setComunicadoId] = useState(null);
const [submitted, setSubmitted] = useState(false);
const toast = useRef(null);
const dt = useRef(null);
const [cookies, setCookie] = useCookies();
const [globalFilter, setGlobalFilter] = useState(null);
async function listaComunis() {
let comunicadosA=await fetch('http://localhost:4000/post/allPosts', {method:'GET'});
let comunicadosRes= await comunicadosA.json();
setComuicados(comunicadosRes.message);
console.log(comunicadosRes.message);
}
const saveComunicado = () => {
var data = {
post: document.getElementById('txt_comunicado').value,
user_id: cookies.id,
community_id: cookies.community_id
};
fetch('http://localhost:4000/post/createPost', {
cache: 'no-cache',
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(
function (response) {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else
return response.json();
}
)
.then(
function (response) {
}
)
.catch(
err => console.log('Ocurrió un error con el fetch', err)
);
}
const header = (
<React.Fragment>
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
<h5 className="m-0">Comunicados de la comunidad</h5>
<span className="block mt-2 md:mt-0 p-input-icon-left">
<i className="pi pi-search" />
<InputText type="search" onInput={(e) => setGlobalFilter(e.target.value)} placeholder="Buscar..." />
</span>
</div>
</React.Fragment>
);
const headerPost = (
<>
<p>
{' '}
<FontAwesomeIcon icon={faCommentAlt} style={{ color: "#D7A86E" }} />{' '}
Descripción comunicado</p>
</>
)
const leftToolbarTemplate = () => {
return (
<React.Fragment>
<div className="my-2">
<Button label="Eliminar" icon="pi pi-trash" className="p-button-danger" />
</div>
</React.Fragment>
)
}
const rightToolbarTemplate = () => {
return (
<React.Fragment>
<Button label="Exportar" icon="pi pi-upload" className="p-button-help" />
</React.Fragment>
)
}
return (
<div className="grid">
<div className="col-12">
<Toast ref={toast} />
<div className="card">
<Toolbar className="mb-4" left={leftToolbarTemplate} right={rightToolbarTemplate}></Toolbar>
<DataTable ref={dt} value={comunicados} dataKey="_id" paginator rows={5}
scrollable scrollHeight="400px" scrollDirection="both" header={header}
rowsPerPageOptions={[5, 10, 25]} className="datatable-responsive mt-3"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
currentPageReportTemplate="Mostrando {first} a {last} de {totalRecords} administradores de comunidades de viviendas"
globalFilter={globalFilter} emptyMessage="No hay administradores de comunidades registrados.">
<Column selectionMode="multiple" headerStyle={{ width: '3rem' }}></Column>
<Column field="post" sortable header={headerPost} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column>
</DataTable>
</div>
</div>
<div className="col-12">
<div className="card">
<h5>Registro de un comunicado para la comunidad</h5>
<div className="p-fluid formgrid grid">
<div className="field col-12 md:col-12">
<label htmlFor="name">Contenido del comunicado</label>
<div className="p-0 col-12 md:col-12">
<div className="p-inputgroup">
<span className="p-inputgroup-addon p-button p-icon-input-khaki">
<i className="pi pi-pencil"></i>
</span>
<InputTextarea id="txt_comunicado" rows="4"/>
</div>
</div>
</div>
<Button label="Registrar" onClick={saveComunicado} />
</div>
</div>
</div>
</div>
);
};
export default React.memo(RegistroComunicado);

View File

@ -0,0 +1,97 @@
import React from 'react'
import { Dialog } from 'primereact/dialog'
import { Button } from 'primereact/button'
class InfoDialog extends React.Component {
constructor(props) {
super(props)
this.state = {
openInfoDialog: false,
footer: (
<>
<Button label='Cerrar' icon='pi pi-times' onClick={this.onClose} />
</>
),
}
}
onClose = () => this.setState({ openInfoDialog: false })
render() {
return (
<div>
<Dialog
visible={this.state.openInfoDialog}
style={{ width: '650px' }}
modal
className='p-fluid'
header={this.props.header}
footer={this.state.footer}
>
<div className='container text-center'>
<div className='row my-4'>
<div className='col-4 md:col-4'>
<p>Nombre</p>
<div
className='p-0 col-2 md:col-2'
style={{ margin: '0 auto' }}
>
<div className='p-inputgroup align-items-center justify-content-evenly'>
<i className='pi pi-user icon-khaki' />
<p>{this.props.info.name}</p>
</div>
</div>
<div className='col-4 md:col-4'>
<p>Apellido(s)</p>
<div
className='p-0 col-2 md:col-2'
style={{ margin: '0 auto' }}
>
<div className='p-inputgroup align-items-center justify-content-evenly'>
<i className='pi pi-user icon-khaki' />
<p>{this.props.info.last_name}</p>
</div>
</div>
</div>
<div className='col-4 md:col-4'>
<p>Identificación</p>
<div
className='p-0 col-2 md:col-2'
style={{ margin: '0 auto' }}
>
<div className='p-inputgroup align-items-center justify-content-evenly'>
<i className='pi pi-user icon-khaki' />
<p>{this.props.info.dni}</p>
</div>
</div>
</div>
</div>
<div className='row my-5 justify-content-center'>
<div className=' col-4 md:col-4'>
<p>Teléfono</p>
<div className='p-0 col-10 md:col-10'>
<div className='p-inputgroup align-items-center justify-content-evenly'>
<i className='pi pi-phone icon-khaki'></i>
<p>{this.props.info.phone}</p>
</div>
</div>
</div>
<div className=' col-6 md:col-6'>
<p>Correo Electrónico</p>
<div
className='p-0 col-10 md:col-10'
style={{ margin: '0 auto' }}
>
<div className='p-inputgroup align-items-center justify-content-evenly'>
<i className='pi pi-envelope icon-khaki'></i>
<p>{this.props.info.email}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</Dialog>
</div>
)
}
}
export default InfoDialog

View File

@ -7,6 +7,8 @@ import { HashRouter } from 'react-router-dom';
import ScrollToTop from './ScrollToTop'; import ScrollToTop from './ScrollToTop';
import { CookiesProvider } from "react-cookie"; import { CookiesProvider } from "react-cookie";
ReactDOM.render( ReactDOM.render(
<HashRouter> <HashRouter>
<ScrollToTop> <ScrollToTop>