Sign Up
parent
10ac84df72
commit
8b7f244812
|
@ -311,3 +311,9 @@ def isNewArchitectureEnabled() {
|
||||||
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
||||||
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
project.ext.vectoricons = [
|
||||||
|
iconFontNames: [ 'MaterialIcons.ttf', 'MaterialCommunityIcons.ttf', 'FontAwesome.ttf', 'Ionicons.ttf' ] // Name of the font files you want to copy
|
||||||
|
]
|
||||||
|
|
||||||
|
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
|
|
@ -3,13 +3,87 @@ import {AppRegistry} from 'react-native';
|
||||||
|
|
||||||
import App from './src/App';
|
import App from './src/App';
|
||||||
|
|
||||||
//AppRegistry.registerComponent("App", () => App)
|
// @ts-ignore
|
||||||
|
import outfitFont from './web/public/fonts/Outfit.ttf';
|
||||||
|
// @ts-ignore
|
||||||
|
import FontAwesome from 'react-native-vector-icons/Fonts/FontAwesome.ttf';
|
||||||
|
// @ts-ignore
|
||||||
|
import MaterialIcons from 'react-native-vector-icons/Fonts/MaterialIcons.ttf';
|
||||||
|
// @ts-ignore
|
||||||
|
import Ionicons from 'react-native-vector-icons/Fonts/Ionicons.ttf';
|
||||||
|
// @ts-ignore
|
||||||
|
import MaterialCommunityIcons from 'react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf';
|
||||||
|
|
||||||
/*
|
const iconFontStyles = `@font-face {
|
||||||
AppRegistry.runApplication("App", {
|
src: url(${MaterialCommunityIcons});
|
||||||
initialProps: {},
|
font-family: MaterialCommunityIcons;
|
||||||
rootTag: document.getElementById("root"),
|
}
|
||||||
})*/
|
@font-face {
|
||||||
|
src: url(${FontAwesome});
|
||||||
|
font-family: FontAwesome;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
src: url(${MaterialIcons});
|
||||||
|
font-family: MaterialIcons;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
src: url(${Ionicons});
|
||||||
|
font-family: Ionicons;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-Thin';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-ExtraLight';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-Light';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-Regular';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-Medium';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-SemiBold';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-Bold';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-ExtraBold';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Outfit-Black';
|
||||||
|
src: url(${outfitFont});
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.type = 'text/css';
|
||||||
|
|
||||||
|
style.appendChild(document.createTextNode(iconFontStyles));
|
||||||
|
|
||||||
|
document.head.appendChild(style);
|
||||||
|
|
||||||
const root = createRoot(document.getElementById('root') as HTMLElement);
|
const root = createRoot(document.getElementById('root') as HTMLElement);
|
||||||
root.render(<App />);
|
root.render(<App />);
|
||||||
|
|
|
@ -8,12 +8,14 @@
|
||||||
"name": "ClickAndJoinApp",
|
"name": "ClickAndJoinApp",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-native-masked-view/masked-view": "^0.2.8",
|
||||||
"@react-navigation/bottom-tabs": "^6.5.2",
|
"@react-navigation/bottom-tabs": "^6.5.2",
|
||||||
"@react-navigation/native": "^6.1.1",
|
"@react-navigation/native": "^6.1.1",
|
||||||
"@react-navigation/native-stack": "^6.9.7",
|
"@react-navigation/native-stack": "^6.9.7",
|
||||||
"@react-spring/native": "^9.6.1",
|
"@react-spring/native": "^9.6.1",
|
||||||
"@react-spring/web": "^9.6.1",
|
"@react-spring/web": "^9.6.1",
|
||||||
"@reduxjs/toolkit": "^1.9.1",
|
"@reduxjs/toolkit": "^1.9.1",
|
||||||
|
"@types/react-native-vector-icons": "^6.4.12",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-esnext": "^1.1.3",
|
"babel-preset-esnext": "^1.1.3",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
|
@ -26,8 +28,12 @@
|
||||||
"react-native-reanimated": "^2.13.0",
|
"react-native-reanimated": "^2.13.0",
|
||||||
"react-native-safe-area-context": "^4.4.1",
|
"react-native-safe-area-context": "^4.4.1",
|
||||||
"react-native-screens": "^3.18.2",
|
"react-native-screens": "^3.18.2",
|
||||||
|
"react-native-svg": "^13.6.0",
|
||||||
|
"react-native-user-agent": "^2.3.1",
|
||||||
|
"react-native-vector-icons": "^9.2.0",
|
||||||
"react-native-web": "^0.18.10",
|
"react-native-web": "^0.18.10",
|
||||||
"react-redux": "^8.0.5"
|
"react-redux": "^8.0.5",
|
||||||
|
"react-string-replace": "^1.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.9",
|
"@babel/core": "^7.12.9",
|
||||||
|
@ -4964,6 +4970,15 @@
|
||||||
"integrity": "sha512-+zDZ20NUnSWghj7Ku5aFphMzuM9JulqCW+aPXT6IfIXFbb8tzYTTOSeRFOtuekJ99ibW2fUCSsjuKNlwDIbHFg==",
|
"integrity": "sha512-+zDZ20NUnSWghj7Ku5aFphMzuM9JulqCW+aPXT6IfIXFbb8tzYTTOSeRFOtuekJ99ibW2fUCSsjuKNlwDIbHFg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native-masked-view/masked-view": {
|
||||||
|
"version": "0.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.2.8.tgz",
|
||||||
|
"integrity": "sha512-+1holBPDF1yi/y0uc1WB6lA5tSNHhM7PpTMapT3ypvSnKQ9+C6sy/zfjxNxRA/llBQ1Ci6f94EaK56UCKs5lTA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16",
|
||||||
|
"react-native": ">=0.57"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-native/assets": {
|
"node_modules/@react-native/assets": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz",
|
||||||
|
@ -5906,11 +5921,19 @@
|
||||||
"version": "0.70.7",
|
"version": "0.70.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.70.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.70.7.tgz",
|
||||||
"integrity": "sha512-hBzeUWwk8sfj3vDfwEXb4hbjWjl0jb5CvWlu2gLrOUJyFHVzJ+x6Y9ilO2eVtJW7l5QmmNLILE1PkVfKRkqYuQ==",
|
"integrity": "sha512-hBzeUWwk8sfj3vDfwEXb4hbjWjl0jb5CvWlu2gLrOUJyFHVzJ+x6Y9ilO2eVtJW7l5QmmNLILE1PkVfKRkqYuQ==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-native-vector-icons": {
|
||||||
|
"version": "6.4.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.12.tgz",
|
||||||
|
"integrity": "sha512-gSXtv3NMOsRwSXJ/gvGebm7CNjHbkeFKCse9h/Pvi+x2yjCLOkJR1FBfec06DhaFJpsK7Y8WRQpwOS0eLqx5Rg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/retry": {
|
"node_modules/@types/retry": {
|
||||||
"version": "0.12.0",
|
"version": "0.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
||||||
|
@ -8154,8 +8177,7 @@
|
||||||
"node_modules/boolbase": {
|
"node_modules/boolbase": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"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=="
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
|
@ -8955,7 +8977,6 @@
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
||||||
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
|
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"boolbase": "^1.0.0",
|
"boolbase": "^1.0.0",
|
||||||
"css-what": "^6.1.0",
|
"css-what": "^6.1.0",
|
||||||
|
@ -8971,7 +8992,6 @@
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
|
||||||
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
|
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mdn-data": "2.0.14",
|
"mdn-data": "2.0.14",
|
||||||
"source-map": "^0.6.1"
|
"source-map": "^0.6.1"
|
||||||
|
@ -8984,7 +9004,6 @@
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
|
||||||
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
|
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
},
|
},
|
||||||
|
@ -9304,7 +9323,6 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||||
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"domelementtype": "^2.3.0",
|
"domelementtype": "^2.3.0",
|
||||||
"domhandler": "^5.0.2",
|
"domhandler": "^5.0.2",
|
||||||
|
@ -9329,8 +9347,7 @@
|
||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/fb55"
|
"url": "https://github.com/sponsors/fb55"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/domexception": {
|
"node_modules/domexception": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
@ -9357,7 +9374,6 @@
|
||||||
"version": "5.0.3",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"domelementtype": "^2.3.0"
|
"domelementtype": "^2.3.0"
|
||||||
},
|
},
|
||||||
|
@ -9372,7 +9388,6 @@
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
|
||||||
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
|
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dom-serializer": "^2.0.0",
|
"dom-serializer": "^2.0.0",
|
||||||
"domelementtype": "^2.3.0",
|
"domelementtype": "^2.3.0",
|
||||||
|
@ -9463,7 +9478,6 @@
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
|
||||||
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
|
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
},
|
},
|
||||||
|
@ -14123,9 +14137,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/json5": {
|
"node_modules/json5": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
|
||||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
"integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"json5": "lib/cli.js"
|
"json5": "lib/cli.js"
|
||||||
},
|
},
|
||||||
|
@ -14481,8 +14495,7 @@
|
||||||
"node_modules/mdn-data": {
|
"node_modules/mdn-data": {
|
||||||
"version": "2.0.14",
|
"version": "2.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
|
||||||
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
|
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/media-typer": {
|
"node_modules/media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
|
@ -15730,7 +15743,6 @@
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||||
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
|
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"boolbase": "^1.0.0"
|
"boolbase": "^1.0.0"
|
||||||
},
|
},
|
||||||
|
@ -16849,7 +16861,6 @@
|
||||||
"version": "13.6.0",
|
"version": "13.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.6.0.tgz",
|
||||||
"integrity": "sha512-1wjHCMJ8siyZbDZ0MX5wM+Jr7YOkb6GADn4/Z+/u1UwJX8WfjarypxDF3UO1ugMHa+7qor39oY+URMcrgPpiww==",
|
"integrity": "sha512-1wjHCMJ8siyZbDZ0MX5wM+Jr7YOkb6GADn4/Z+/u1UwJX8WfjarypxDF3UO1ugMHa+7qor39oY+URMcrgPpiww==",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"css-select": "^5.1.0",
|
"css-select": "^5.1.0",
|
||||||
"css-tree": "^1.1.3"
|
"css-tree": "^1.1.3"
|
||||||
|
@ -16859,6 +16870,116 @@
|
||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-native-user-agent": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-user-agent/-/react-native-user-agent-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-AIFr1VgJHwgWmMwCOmIGxuBeAaADlouXKc10UyR4fzWneUbt5uIJIoRu2oExlfCtiT8IyCp106khDD5vx7RUjw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz",
|
||||||
|
"integrity": "sha512-wKYLaFuQST/chH3AJRjmOLoLy3JEs1JR6zMNgTaemFpNoXs0ztRnTxcxFD9xhX7cJe1/zoN5BpQYe7kL0m5yyA==",
|
||||||
|
"dependencies": {
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"yargs": "^16.1.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"fa5-upgrade": "bin/fa5-upgrade.sh",
|
||||||
|
"generate-icon": "bin/generate-icon.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons/node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons/node_modules/cliui": {
|
||||||
|
"version": "7.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||||
|
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"string-width": "^4.2.0",
|
||||||
|
"strip-ansi": "^6.0.0",
|
||||||
|
"wrap-ansi": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons/node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons/node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons/node_modules/wrap-ansi": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.0.0",
|
||||||
|
"string-width": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons/node_modules/y18n": {
|
||||||
|
"version": "5.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons/node_modules/yargs": {
|
||||||
|
"version": "16.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||||
|
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||||
|
"dependencies": {
|
||||||
|
"cliui": "^7.0.2",
|
||||||
|
"escalade": "^3.1.1",
|
||||||
|
"get-caller-file": "^2.0.5",
|
||||||
|
"require-directory": "^2.1.1",
|
||||||
|
"string-width": "^4.2.0",
|
||||||
|
"y18n": "^5.0.5",
|
||||||
|
"yargs-parser": "^20.2.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-vector-icons/node_modules/yargs-parser": {
|
||||||
|
"version": "20.2.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||||
|
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-native-web": {
|
"node_modules/react-native-web": {
|
||||||
"version": "0.18.10",
|
"version": "0.18.10",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.18.10.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.18.10.tgz",
|
||||||
|
@ -16958,6 +17079,14 @@
|
||||||
"react": "^16.0.0 || ^17.0.0 || ^18.0.0"
|
"react": "^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-string-replace": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-string-replace/-/react-string-replace-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-N6RalSDFGbOHs0IJi1H611WbZsvk3ZT47Jl2JEXFbiS3kTwsdCYij70Keo/tWtLy7sfhDsYm7CwNM/WmjXIaMw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-test-renderer": {
|
"node_modules/react-test-renderer": {
|
||||||
"version": "18.1.0",
|
"version": "18.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.1.0.tgz",
|
||||||
|
@ -24109,6 +24238,12 @@
|
||||||
"integrity": "sha512-+zDZ20NUnSWghj7Ku5aFphMzuM9JulqCW+aPXT6IfIXFbb8tzYTTOSeRFOtuekJ99ibW2fUCSsjuKNlwDIbHFg==",
|
"integrity": "sha512-+zDZ20NUnSWghj7Ku5aFphMzuM9JulqCW+aPXT6IfIXFbb8tzYTTOSeRFOtuekJ99ibW2fUCSsjuKNlwDIbHFg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@react-native-masked-view/masked-view": {
|
||||||
|
"version": "0.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.2.8.tgz",
|
||||||
|
"integrity": "sha512-+1holBPDF1yi/y0uc1WB6lA5tSNHhM7PpTMapT3ypvSnKQ9+C6sy/zfjxNxRA/llBQ1Ci6f94EaK56UCKs5lTA==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"@react-native/assets": {
|
"@react-native/assets": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz",
|
||||||
|
@ -24892,11 +25027,19 @@
|
||||||
"version": "0.70.7",
|
"version": "0.70.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.70.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.70.7.tgz",
|
||||||
"integrity": "sha512-hBzeUWwk8sfj3vDfwEXb4hbjWjl0jb5CvWlu2gLrOUJyFHVzJ+x6Y9ilO2eVtJW7l5QmmNLILE1PkVfKRkqYuQ==",
|
"integrity": "sha512-hBzeUWwk8sfj3vDfwEXb4hbjWjl0jb5CvWlu2gLrOUJyFHVzJ+x6Y9ilO2eVtJW7l5QmmNLILE1PkVfKRkqYuQ==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-native-vector-icons": {
|
||||||
|
"version": "6.4.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.12.tgz",
|
||||||
|
"integrity": "sha512-gSXtv3NMOsRwSXJ/gvGebm7CNjHbkeFKCse9h/Pvi+x2yjCLOkJR1FBfec06DhaFJpsK7Y8WRQpwOS0eLqx5Rg==",
|
||||||
|
"requires": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/retry": {
|
"@types/retry": {
|
||||||
"version": "0.12.0",
|
"version": "0.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
||||||
|
@ -26820,8 +26963,7 @@
|
||||||
"boolbase": {
|
"boolbase": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"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=="
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
|
@ -27432,7 +27574,6 @@
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
||||||
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
|
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"boolbase": "^1.0.0",
|
"boolbase": "^1.0.0",
|
||||||
"css-what": "^6.1.0",
|
"css-what": "^6.1.0",
|
||||||
|
@ -27445,7 +27586,6 @@
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
|
||||||
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
|
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"mdn-data": "2.0.14",
|
"mdn-data": "2.0.14",
|
||||||
"source-map": "^0.6.1"
|
"source-map": "^0.6.1"
|
||||||
|
@ -27454,8 +27594,7 @@
|
||||||
"css-what": {
|
"css-what": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
|
||||||
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
|
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"cssom": {
|
"cssom": {
|
||||||
"version": "0.4.4",
|
"version": "0.4.4",
|
||||||
|
@ -27692,7 +27831,6 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||||
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"domelementtype": "^2.3.0",
|
"domelementtype": "^2.3.0",
|
||||||
"domhandler": "^5.0.2",
|
"domhandler": "^5.0.2",
|
||||||
|
@ -27708,8 +27846,7 @@
|
||||||
"domelementtype": {
|
"domelementtype": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"domexception": {
|
"domexception": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
@ -27732,7 +27869,6 @@
|
||||||
"version": "5.0.3",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"domelementtype": "^2.3.0"
|
"domelementtype": "^2.3.0"
|
||||||
}
|
}
|
||||||
|
@ -27741,7 +27877,6 @@
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
|
||||||
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
|
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"dom-serializer": "^2.0.0",
|
"dom-serializer": "^2.0.0",
|
||||||
"domelementtype": "^2.3.0",
|
"domelementtype": "^2.3.0",
|
||||||
|
@ -27810,8 +27945,7 @@
|
||||||
"entities": {
|
"entities": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
|
||||||
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
|
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"envinfo": {
|
"envinfo": {
|
||||||
"version": "7.8.1",
|
"version": "7.8.1",
|
||||||
|
@ -31309,9 +31443,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"json5": {
|
"json5": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
|
||||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
|
"integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ=="
|
||||||
},
|
},
|
||||||
"jsonfile": {
|
"jsonfile": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
@ -31591,8 +31725,7 @@
|
||||||
"mdn-data": {
|
"mdn-data": {
|
||||||
"version": "2.0.14",
|
"version": "2.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
|
||||||
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
|
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
|
@ -32625,7 +32758,6 @@
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||||
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
|
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"boolbase": "^1.0.0"
|
"boolbase": "^1.0.0"
|
||||||
}
|
}
|
||||||
|
@ -33473,12 +33605,93 @@
|
||||||
"version": "13.6.0",
|
"version": "13.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.6.0.tgz",
|
||||||
"integrity": "sha512-1wjHCMJ8siyZbDZ0MX5wM+Jr7YOkb6GADn4/Z+/u1UwJX8WfjarypxDF3UO1ugMHa+7qor39oY+URMcrgPpiww==",
|
"integrity": "sha512-1wjHCMJ8siyZbDZ0MX5wM+Jr7YOkb6GADn4/Z+/u1UwJX8WfjarypxDF3UO1ugMHa+7qor39oY+URMcrgPpiww==",
|
||||||
"peer": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"css-select": "^5.1.0",
|
"css-select": "^5.1.0",
|
||||||
"css-tree": "^1.1.3"
|
"css-tree": "^1.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-native-user-agent": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-user-agent/-/react-native-user-agent-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-AIFr1VgJHwgWmMwCOmIGxuBeAaADlouXKc10UyR4fzWneUbt5uIJIoRu2oExlfCtiT8IyCp106khDD5vx7RUjw==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
|
"react-native-vector-icons": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz",
|
||||||
|
"integrity": "sha512-wKYLaFuQST/chH3AJRjmOLoLy3JEs1JR6zMNgTaemFpNoXs0ztRnTxcxFD9xhX7cJe1/zoN5BpQYe7kL0m5yyA==",
|
||||||
|
"requires": {
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"yargs": "^16.1.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cliui": {
|
||||||
|
"version": "7.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||||
|
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||||
|
"requires": {
|
||||||
|
"string-width": "^4.2.0",
|
||||||
|
"strip-ansi": "^6.0.0",
|
||||||
|
"wrap-ansi": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"requires": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
|
},
|
||||||
|
"wrap-ansi": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "^4.0.0",
|
||||||
|
"string-width": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"y18n": {
|
||||||
|
"version": "5.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
|
||||||
|
},
|
||||||
|
"yargs": {
|
||||||
|
"version": "16.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||||
|
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||||
|
"requires": {
|
||||||
|
"cliui": "^7.0.2",
|
||||||
|
"escalade": "^3.1.1",
|
||||||
|
"get-caller-file": "^2.0.5",
|
||||||
|
"require-directory": "^2.1.1",
|
||||||
|
"string-width": "^4.2.0",
|
||||||
|
"y18n": "^5.0.5",
|
||||||
|
"yargs-parser": "^20.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yargs-parser": {
|
||||||
|
"version": "20.2.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||||
|
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-native-web": {
|
"react-native-web": {
|
||||||
"version": "0.18.10",
|
"version": "0.18.10",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.18.10.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.18.10.tgz",
|
||||||
|
@ -33537,6 +33750,11 @@
|
||||||
"react-is": "^16.12.0 || ^17.0.0 || ^18.0.0"
|
"react-is": "^16.12.0 || ^17.0.0 || ^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-string-replace": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-string-replace/-/react-string-replace-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-N6RalSDFGbOHs0IJi1H611WbZsvk3ZT47Jl2JEXFbiS3kTwsdCYij70Keo/tWtLy7sfhDsYm7CwNM/WmjXIaMw=="
|
||||||
|
},
|
||||||
"react-test-renderer": {
|
"react-test-renderer": {
|
||||||
"version": "18.1.0",
|
"version": "18.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.1.0.tgz",
|
||||||
|
|
10
package.json
10
package.json
|
@ -12,12 +12,14 @@
|
||||||
"lint": "eslint ."
|
"lint": "eslint ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-native-masked-view/masked-view": "^0.2.8",
|
||||||
"@react-navigation/bottom-tabs": "^6.5.2",
|
"@react-navigation/bottom-tabs": "^6.5.2",
|
||||||
"@react-navigation/native": "^6.1.1",
|
"@react-navigation/native": "^6.1.1",
|
||||||
"@react-navigation/native-stack": "^6.9.7",
|
"@react-navigation/native-stack": "^6.9.7",
|
||||||
"@react-spring/native": "^9.6.1",
|
"@react-spring/native": "^9.6.1",
|
||||||
"@react-spring/web": "^9.6.1",
|
"@react-spring/web": "^9.6.1",
|
||||||
"@reduxjs/toolkit": "^1.9.1",
|
"@reduxjs/toolkit": "^1.9.1",
|
||||||
|
"@types/react-native-vector-icons": "^6.4.12",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-esnext": "^1.1.3",
|
"babel-preset-esnext": "^1.1.3",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
|
@ -30,8 +32,12 @@
|
||||||
"react-native-reanimated": "^2.13.0",
|
"react-native-reanimated": "^2.13.0",
|
||||||
"react-native-safe-area-context": "^4.4.1",
|
"react-native-safe-area-context": "^4.4.1",
|
||||||
"react-native-screens": "^3.18.2",
|
"react-native-screens": "^3.18.2",
|
||||||
|
"react-native-svg": "^13.6.0",
|
||||||
|
"react-native-user-agent": "^2.3.1",
|
||||||
|
"react-native-vector-icons": "^9.2.0",
|
||||||
"react-native-web": "^0.18.10",
|
"react-native-web": "^0.18.10",
|
||||||
"react-redux": "^8.0.5"
|
"react-redux": "^8.0.5",
|
||||||
|
"react-string-replace": "^1.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.9",
|
"@babel/core": "^7.12.9",
|
||||||
|
@ -59,7 +65,7 @@
|
||||||
"webpack-dev-server": "^4.11.1"
|
"webpack-dev-server": "^4.11.1"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"preset": "react-native",
|
"preset": "react-native-web",
|
||||||
"transform": {
|
"transform": {
|
||||||
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
|
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
|
||||||
"\\.(ts|tsx)$": "ts-jest"
|
"\\.(ts|tsx)$": "ts-jest"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {NavigationContainer} from '@react-navigation/native';
|
||||||
import {getBackgroundColor, theme, ThemeSwitcher} from '@caj/configs/colors';
|
import {getBackgroundColor, theme, ThemeSwitcher} from '@caj/configs/colors';
|
||||||
|
|
||||||
import StatusBar from './StatusBar';
|
import StatusBar from './StatusBar';
|
||||||
import Navigation, {linking} from './Navigation';
|
import Navigation, {linking} from './caj/Navigation';
|
||||||
|
|
||||||
import {Provider, useSelector} from 'react-redux';
|
import {Provider, useSelector} from 'react-redux';
|
||||||
import {RootState, store} from '@caj/redux/store';
|
import {RootState, store} from '@caj/redux/store';
|
||||||
|
@ -44,8 +44,8 @@ const OtherProviders = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationContainer theme={navigationTheme} linking={linking}>
|
<NavigationContainer theme={navigationTheme} /*linking={linking}*/>
|
||||||
<NativeBaseProvider theme={theme}>
|
<NativeBaseProvider theme={theme(globalTheme)}>
|
||||||
<MainComponent />
|
<MainComponent />
|
||||||
</NativeBaseProvider>
|
</NativeBaseProvider>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
|
|
|
@ -23,7 +23,7 @@ function onAppStart() {
|
||||||
console.log('finish');
|
console.log('finish');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
store.dispatch(appNonSaveVarActions.setAppStatus(appStatus.APP_RUNNING));
|
store.dispatch(appNonSaveVarActions.setAppStatus(appStatus.APP_RUNNING));
|
||||||
}, 500);
|
}, 250);
|
||||||
//store.dispatch(actions.loadPreferences(appVar));
|
//store.dispatch(actions.loadPreferences(appVar));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,25 +34,24 @@ const styles = StyleSheet.create({
|
||||||
});
|
});
|
||||||
|
|
||||||
export const linking: LinkingOptions<{
|
export const linking: LinkingOptions<{
|
||||||
Auth: string;
|
Maps: string;
|
||||||
Home: string;
|
Home: string;
|
||||||
Table: string;
|
Chat: string;
|
||||||
Loading: string;
|
Settings: string;
|
||||||
}> = {
|
}> = {
|
||||||
prefixes: ['http://'],
|
prefixes: ['http://'],
|
||||||
config: {
|
config: {
|
||||||
initialRouteName: 'Loading',
|
|
||||||
screens: {
|
screens: {
|
||||||
Auth: 'auth',
|
Maps: 'mapss',
|
||||||
Home: 'home',
|
Home: 'account',
|
||||||
Table: 'table',
|
Chat: 'chats',
|
||||||
Loading: 'loading',
|
Settings: 'settingss',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HomeStackNavigatorParamList = {
|
export type HomeStackNavigatorParamList = {
|
||||||
Home: undefined;
|
Account: undefined;
|
||||||
Maps: undefined;
|
Maps: undefined;
|
||||||
Chat: undefined;
|
Chat: undefined;
|
||||||
Test: undefined;
|
Test: undefined;
|
||||||
|
@ -100,12 +99,21 @@ function HomeScreen() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SettingsStackNavigatorParamList = {
|
||||||
|
Chat: undefined;
|
||||||
|
Settings: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SettingsScreenNavigationProp =
|
||||||
|
NativeStackNavigationProp<SettingsStackNavigatorParamList>;
|
||||||
|
|
||||||
function SettingsScreen() {
|
function SettingsScreen() {
|
||||||
const navigation = useNavigation<HomeScreenNavigationProp>();
|
const navigation = useNavigation<SettingsScreenNavigationProp>();
|
||||||
|
const navigation2 = useNavigation<HomeScreenNavigationProp>();
|
||||||
return (
|
return (
|
||||||
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
|
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
|
||||||
<Text>Settings screen</Text>
|
<Text>Settings screen</Text>
|
||||||
<Button onPress={() => navigation.navigate('Chat')}>Go to Chat</Button>
|
<Button onPress={() => navigation2.navigate('Maps')}>Go to Chat</Button>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
import React, {useState, useEffect} from 'react';
|
||||||
|
|
||||||
|
import {StyleSheet, Appearance, Dimensions} from 'react-native';
|
||||||
|
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context';
|
||||||
|
|
||||||
|
import {useSelector, useDispatch} from 'react-redux';
|
||||||
|
import {RootState} from '@caj/redux/store';
|
||||||
|
import {appVarActions} from '@caj/configs/appVarReducer';
|
||||||
|
|
||||||
|
import imgSrc from '@caj/img/maimg.png';
|
||||||
|
import {placeholder} from '@caj/lang/default';
|
||||||
|
import {getBackgroundColor} from '@caj/configs/colors';
|
||||||
|
import {saveVarChanges} from '@caj/helper/appData';
|
||||||
|
|
||||||
|
import {Box, Input, VStack, Center, Avatar, Text, Button} from 'native-base';
|
||||||
|
import {View} from 'react-native';
|
||||||
|
|
||||||
|
import {
|
||||||
|
LinkingOptions,
|
||||||
|
NavigationContainer,
|
||||||
|
NavigatorScreenParams,
|
||||||
|
useNavigation,
|
||||||
|
} from '@react-navigation/native';
|
||||||
|
import {
|
||||||
|
createNativeStackNavigator,
|
||||||
|
NativeStackNavigationProp,
|
||||||
|
} from '@react-navigation/native-stack';
|
||||||
|
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
|
||||||
|
import AccountTab, {
|
||||||
|
AccountStackNavigatorParamList,
|
||||||
|
AccountTabName,
|
||||||
|
} from './tabs/main/AccountTab';
|
||||||
|
import CalendarTab, {
|
||||||
|
CalendarStackNavigatorParamList,
|
||||||
|
} from './tabs/main/CalendarTab';
|
||||||
|
import MapsTab, {MapsStackNavigatorParamList} from './tabs/main/MapsTab';
|
||||||
|
import ChatTab, {ChatStackNavigatorParamList} from './tabs/main/ChatTab';
|
||||||
|
import {
|
||||||
|
FadeInView,
|
||||||
|
SlideFromLeftView,
|
||||||
|
SlideFromRightView,
|
||||||
|
} from './helper/animations';
|
||||||
|
import {
|
||||||
|
LoginStackNavigatorParamList,
|
||||||
|
RegisterScreenAnim,
|
||||||
|
} from './components/NotLoggedIn';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
height: '100%',
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const linking: LinkingOptions<{}> = {
|
||||||
|
prefixes: ['http://'],
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RootStackNavigatorParamList = {
|
||||||
|
Home: NavigatorScreenParams<HomeStackNavigatorParamList>;
|
||||||
|
Register: NavigatorScreenParams<LoginStackNavigatorParamList>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RootScreenNavigationProp =
|
||||||
|
NativeStackNavigationProp<RootStackNavigatorParamList>;
|
||||||
|
|
||||||
|
export default function Navigation() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator screenOptions={{headerShown: false}}>
|
||||||
|
<Stack.Screen name="Home" component={HomeStack} />
|
||||||
|
<Stack.Screen name="Register" component={RegisterScreenAnim} />
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Stack = createNativeStackNavigator<RootStackNavigatorParamList>();
|
||||||
|
|
||||||
|
export type HomeStackNavigatorParamList = {
|
||||||
|
Account: NavigatorScreenParams<AccountStackNavigatorParamList>;
|
||||||
|
Calendar: NavigatorScreenParams<CalendarStackNavigatorParamList>;
|
||||||
|
Maps: NavigatorScreenParams<MapsStackNavigatorParamList>;
|
||||||
|
Chat: NavigatorScreenParams<ChatStackNavigatorParamList>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function AccountTabAnim(props: any) {
|
||||||
|
return (
|
||||||
|
<SlideFromLeftView>
|
||||||
|
<AccountTab {...props} />
|
||||||
|
</SlideFromLeftView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CalendarTabAnim(props: any) {
|
||||||
|
return (
|
||||||
|
<FadeInView>
|
||||||
|
<CalendarTab {...props} />
|
||||||
|
</FadeInView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function MapsTabAnim(props: any) {
|
||||||
|
return (
|
||||||
|
<FadeInView>
|
||||||
|
<MapsTab {...props} />
|
||||||
|
</FadeInView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function ChatTabAnim(props: any) {
|
||||||
|
return (
|
||||||
|
<SlideFromRightView>
|
||||||
|
<ChatTab {...props} />
|
||||||
|
</SlideFromRightView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function HomeStack() {
|
||||||
|
return (
|
||||||
|
<Tab.Navigator screenOptions={{headerShown: false, unmountOnBlur: false}}>
|
||||||
|
<Tab.Screen name="Account" component={AccountTabAnim} />
|
||||||
|
<Tab.Screen name="Calendar" component={CalendarTabAnim} />
|
||||||
|
<Tab.Screen name="Maps" component={MapsTabAnim} />
|
||||||
|
<Tab.Screen name="Chat" component={ChatTabAnim} />
|
||||||
|
</Tab.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Tab = createBottomTabNavigator<HomeStackNavigatorParamList>();
|
|
@ -0,0 +1,5 @@
|
||||||
|
import {Center} from 'native-base';
|
||||||
|
|
||||||
|
export default function AccountInfoBanner() {
|
||||||
|
return <Center>Account</Center>;
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
import {Box, Center, HStack, Input, Pressable, Text} from 'native-base';
|
||||||
|
import {useEffect, useRef, useState} from 'react';
|
||||||
|
import {
|
||||||
|
TextInput,
|
||||||
|
NativeSyntheticEvent,
|
||||||
|
TextInputChangeEventData,
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
|
function RenderCell(props: {
|
||||||
|
index: number;
|
||||||
|
text: string | number;
|
||||||
|
maxIndex: number;
|
||||||
|
isFocus: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
rest: any;
|
||||||
|
}) {
|
||||||
|
const display: string = props.text ? props.text.toString() : '';
|
||||||
|
|
||||||
|
const [toggle, setToggle] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (props.isFocus === false) return;
|
||||||
|
|
||||||
|
let timer = setInterval(() => {
|
||||||
|
setToggle(!toggle);
|
||||||
|
}, 500);
|
||||||
|
return () => {
|
||||||
|
clearInterval(timer);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Pressable
|
||||||
|
{...props.rest}
|
||||||
|
w={10}
|
||||||
|
h={10}
|
||||||
|
borderColor={props.isFocus ? 'primary.300' : 'black.100'}
|
||||||
|
backgroundColor={
|
||||||
|
props.disabled ? 'black.300' : props.isFocus ? '#ff9b7933' : null
|
||||||
|
}
|
||||||
|
borderWidth={1}
|
||||||
|
borderRadius={5}>
|
||||||
|
<Center w={'100%'} h={'100%'}>
|
||||||
|
<Text
|
||||||
|
fontSize={'2xl'}
|
||||||
|
color={props.disabled ? 'white.100' : 'white.900'}
|
||||||
|
{...props.rest}>
|
||||||
|
{props.isFocus ? (toggle ? '|' : '') : display}
|
||||||
|
</Text>
|
||||||
|
</Center>
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ConfirmationCodeField(props: {
|
||||||
|
cellCount: number;
|
||||||
|
charType: 'number' | 'letter';
|
||||||
|
onFinish?: Function;
|
||||||
|
onChange?: Function;
|
||||||
|
disabled?: boolean;
|
||||||
|
rest?: any;
|
||||||
|
}) {
|
||||||
|
const [values, setValues] = useState({input: ''});
|
||||||
|
const [isFocus, setFocus] = useState(false);
|
||||||
|
|
||||||
|
const inputRef = useRef<TextInput>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box {...props.rest}>
|
||||||
|
<TextInput
|
||||||
|
autoFocus
|
||||||
|
ref={inputRef}
|
||||||
|
value={values.input}
|
||||||
|
keyboardType={props.charType === 'number' ? 'numeric' : 'default'}
|
||||||
|
onFocus={() => setFocus(true)}
|
||||||
|
onBlur={() => setFocus(false)}
|
||||||
|
editable={!props.disabled}
|
||||||
|
onChange={(event: NativeSyntheticEvent<TextInputChangeEventData>) => {
|
||||||
|
let text = event.nativeEvent.text;
|
||||||
|
let vals = {...values};
|
||||||
|
|
||||||
|
if (props.charType === 'number')
|
||||||
|
vals.input = text.replace(/[^0-9]/g, '');
|
||||||
|
else if (props.charType === 'letter') vals.input = text;
|
||||||
|
|
||||||
|
vals.input = vals.input.slice(0, props.cellCount);
|
||||||
|
|
||||||
|
setValues(vals);
|
||||||
|
|
||||||
|
if (props.onChange) props.onChange(vals.input);
|
||||||
|
|
||||||
|
if (vals.input.length === props.cellCount) {
|
||||||
|
if (inputRef.current !== null) {
|
||||||
|
inputRef.current.blur();
|
||||||
|
if (props.onFinish) props.onFinish(vals.input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
opacity: 0,
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
|
||||||
|
padding: 0,
|
||||||
|
margin: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<HStack space={3} justifyContent="center">
|
||||||
|
{(() => {
|
||||||
|
let cells = [];
|
||||||
|
for (let i = 0; i < props.cellCount; i++) {
|
||||||
|
cells.push(
|
||||||
|
<RenderCell
|
||||||
|
key={'ConfirmationCodeFieldCell' + i}
|
||||||
|
index={i}
|
||||||
|
isFocus={isFocus === true ? values.input.length === i : false}
|
||||||
|
text={values.input[i]}
|
||||||
|
maxIndex={props.cellCount}
|
||||||
|
disabled={props.disabled || false}
|
||||||
|
rest={{
|
||||||
|
onPress: !props.disabled
|
||||||
|
? () => {
|
||||||
|
let vals = {...values};
|
||||||
|
vals.input = vals.input.slice(0, i);
|
||||||
|
setValues(vals);
|
||||||
|
|
||||||
|
if (props.onChange) props.onChange(vals.input);
|
||||||
|
|
||||||
|
if (inputRef.current !== null) {
|
||||||
|
inputRef.current.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return cells;
|
||||||
|
})()}
|
||||||
|
</HStack>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConfirmationCodeField;
|
|
@ -0,0 +1,30 @@
|
||||||
|
import {AccountName, Username} from '@caj/helper/types';
|
||||||
|
import {RootState} from '@caj/redux/store';
|
||||||
|
import {HStack, Text} from 'native-base';
|
||||||
|
import {useSelector} from 'react-redux';
|
||||||
|
|
||||||
|
export default function NameDisplay(props: {
|
||||||
|
UserName: Username;
|
||||||
|
AccountName: AccountName;
|
||||||
|
fontSize?: number;
|
||||||
|
}) {
|
||||||
|
const theme = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.theme,
|
||||||
|
);
|
||||||
|
const fontSize = props.fontSize || 15;
|
||||||
|
const lineHeight = fontSize * 1.25;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HStack space={fontSize / 30} alignItems={'flex-end'}>
|
||||||
|
<Text fontSize={fontSize} color="primary.400">
|
||||||
|
{props.UserName !== '' ? props.UserName : '----'}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
fontSize={fontSize / 1.5}
|
||||||
|
fontFamily={'Outfit-Light'}
|
||||||
|
color="light.400">
|
||||||
|
{props.AccountName !== '' ? props.AccountName : '----'}
|
||||||
|
</Text>
|
||||||
|
</HStack>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,960 @@
|
||||||
|
import {RegisterProcess, ThemeMode} from '@caj/configs/appVar';
|
||||||
|
import {appVarActions} from '@caj/configs/appVarReducer';
|
||||||
|
import {defaultHeaderStyle} from '@caj/configs/colors';
|
||||||
|
import {SlideFromLeftView} from '@caj/helper/animations';
|
||||||
|
import {saveVarChanges} from '@caj/helper/appData';
|
||||||
|
import {apiBackendRequest, makeRequest} from '@caj/helper/request';
|
||||||
|
import {
|
||||||
|
accountNameOptions,
|
||||||
|
EMail,
|
||||||
|
emailOptions,
|
||||||
|
passwordOptions,
|
||||||
|
userNameOptions,
|
||||||
|
XToken,
|
||||||
|
} from '@caj/helper/types';
|
||||||
|
import {RootScreenNavigationProp} from '@caj/Navigation';
|
||||||
|
import {RootState, store} from '@caj/redux/store';
|
||||||
|
import {useNavigation} from '@react-navigation/native';
|
||||||
|
import {
|
||||||
|
createNativeStackNavigator,
|
||||||
|
NativeStackNavigationProp,
|
||||||
|
} from '@react-navigation/native-stack';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Center,
|
||||||
|
Container,
|
||||||
|
FormControl,
|
||||||
|
Heading,
|
||||||
|
HStack,
|
||||||
|
Icon,
|
||||||
|
IconButton,
|
||||||
|
Input,
|
||||||
|
Pressable,
|
||||||
|
ScrollView,
|
||||||
|
Spinner,
|
||||||
|
Text,
|
||||||
|
useColorModeValue,
|
||||||
|
useTheme,
|
||||||
|
useToast,
|
||||||
|
VStack,
|
||||||
|
WarningOutlineIcon,
|
||||||
|
} from 'native-base';
|
||||||
|
|
||||||
|
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
||||||
|
|
||||||
|
import {baseFontSize} from 'native-base/lib/typescript/theme/tools';
|
||||||
|
import {useEffect, useRef, useState} from 'react';
|
||||||
|
import {useDispatch, useSelector} from 'react-redux';
|
||||||
|
import reactStringReplace from 'react-string-replace';
|
||||||
|
import ConfirmationCodeField from './ConfirmationCodeField';
|
||||||
|
import NameDisplay from './NameDisplay';
|
||||||
|
import showToast from './Toast';
|
||||||
|
import {NativeSyntheticEvent, TextInputFocusEventData} from 'react-native';
|
||||||
|
|
||||||
|
const validateEmail = (email: EMail) => {
|
||||||
|
return emailOptions.isAllowed(email);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function NotLoggedIn() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const theme = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.theme,
|
||||||
|
);
|
||||||
|
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box alignItems="center" mt={5}>
|
||||||
|
<Text color="primary.400">{lang.appName}</Text>
|
||||||
|
<Text color="white.100">{lang.appNameDesc}</Text>
|
||||||
|
<VStack mt={5} space={4} alignItems="center">
|
||||||
|
<Button
|
||||||
|
w="72"
|
||||||
|
colorScheme="primary"
|
||||||
|
rounded="xl"
|
||||||
|
_text={{fontSize: 'xl'}}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate('Register', {screen: 'RegStepOne'});
|
||||||
|
}}>
|
||||||
|
Sign up
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
w="72"
|
||||||
|
colorScheme="black"
|
||||||
|
variant={theme === ThemeMode.Darkest ? 'outline' : 'subtle'}
|
||||||
|
rounded="xl"
|
||||||
|
_text={{fontSize: 'xl', color: 'white.900'}}>
|
||||||
|
Log in
|
||||||
|
</Button>
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RegisterScreenAnim(props: any) {
|
||||||
|
return (
|
||||||
|
<SlideFromLeftView>
|
||||||
|
<RegisterScreen {...props} />
|
||||||
|
</SlideFromLeftView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LoginStackNavigatorParamList = {
|
||||||
|
RegStepOne: undefined;
|
||||||
|
RegStepTwo: undefined;
|
||||||
|
RegStepFinal: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const LoginStack = createNativeStackNavigator<LoginStackNavigatorParamList>();
|
||||||
|
|
||||||
|
export type LoginScreenNavigationProp =
|
||||||
|
NativeStackNavigationProp<LoginStackNavigatorParamList>;
|
||||||
|
|
||||||
|
function RegisterScreen() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const theme = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.theme,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LoginStack.Navigator>
|
||||||
|
<LoginStack.Screen
|
||||||
|
name="RegStepOne"
|
||||||
|
options={{
|
||||||
|
animation: 'slide_from_left',
|
||||||
|
title: lang.account.registration.registration,
|
||||||
|
headerShown: true,
|
||||||
|
...defaultHeaderStyle(theme, 'registration'),
|
||||||
|
}}
|
||||||
|
component={StepOne}
|
||||||
|
/>
|
||||||
|
<LoginStack.Screen
|
||||||
|
name="RegStepTwo"
|
||||||
|
options={{
|
||||||
|
animation: 'slide_from_right',
|
||||||
|
title: lang.account.registration.registration,
|
||||||
|
headerShown: true,
|
||||||
|
...defaultHeaderStyle(theme, 'registration'),
|
||||||
|
}}
|
||||||
|
component={StepTwo}
|
||||||
|
/>
|
||||||
|
<LoginStack.Screen
|
||||||
|
name="RegStepFinal"
|
||||||
|
options={{
|
||||||
|
animation: 'slide_from_right',
|
||||||
|
title: lang.account.registration.registration,
|
||||||
|
headerShown: true,
|
||||||
|
...defaultHeaderStyle(theme, 'registration'),
|
||||||
|
}}
|
||||||
|
component={StepFinal}
|
||||||
|
/>
|
||||||
|
</LoginStack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Agreement() {
|
||||||
|
const toast = useToast();
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
|
||||||
|
const textColor = useColorModeValue('blue.700', 'cyan.400');
|
||||||
|
|
||||||
|
let replacedText = reactStringReplace(
|
||||||
|
lang.account.registration.info,
|
||||||
|
'${TermsOfUse}',
|
||||||
|
(match, i) => (
|
||||||
|
<Text
|
||||||
|
key={match + i}
|
||||||
|
color={textColor}
|
||||||
|
bold
|
||||||
|
onPress={() => {
|
||||||
|
showToast(toast, {
|
||||||
|
title: lang.account.registration.termsOfUse,
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'info',
|
||||||
|
description: undefined,
|
||||||
|
isClosable: true,
|
||||||
|
rest: {colorScheme: 'primary'},
|
||||||
|
});
|
||||||
|
}}>
|
||||||
|
{lang.account.registration.termsOfUse}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
replacedText = reactStringReplace(
|
||||||
|
replacedText,
|
||||||
|
'${privacyPolicy}',
|
||||||
|
(match, i) => (
|
||||||
|
<Text
|
||||||
|
key={match + i}
|
||||||
|
color={textColor}
|
||||||
|
bold
|
||||||
|
onPress={() => {
|
||||||
|
showToast(toast, {
|
||||||
|
title: lang.account.registration.privacyPolicy,
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'info',
|
||||||
|
description: undefined,
|
||||||
|
isClosable: true,
|
||||||
|
rest: {colorScheme: 'primary'},
|
||||||
|
});
|
||||||
|
}}>
|
||||||
|
{lang.account.registration.privacyPolicy}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Text textAlign={'justify'} color={'white.900'}>
|
||||||
|
{replacedText}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resendMail(email: EMail, toast: any): Promise<XToken> {
|
||||||
|
return new Promise<XToken>((resolve, reject) => {
|
||||||
|
makeRequest({
|
||||||
|
path: apiBackendRequest.REGISTER_RESEND_MAIL,
|
||||||
|
|
||||||
|
requestHeader: {},
|
||||||
|
request: {
|
||||||
|
Email: email,
|
||||||
|
},
|
||||||
|
//response: {
|
||||||
|
// XToken: undefined,
|
||||||
|
//},
|
||||||
|
})
|
||||||
|
.then(resp => {
|
||||||
|
console.log(1);
|
||||||
|
let token =
|
||||||
|
store.getState().appVariables.preferences.RegisterProcess.XToken;
|
||||||
|
if (token !== undefined /*resp.response.XToken !== undefined*/) {
|
||||||
|
showToast(toast, {
|
||||||
|
title: store.getState().appVariables.lang.info,
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'info',
|
||||||
|
description:
|
||||||
|
store.getState().appVariables.lang.account.registration.stepTwo
|
||||||
|
.resend[2],
|
||||||
|
isClosable: true,
|
||||||
|
rest: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve(token);
|
||||||
|
} else {
|
||||||
|
reject(500);
|
||||||
|
showToast(toast, {
|
||||||
|
title: store.getState().appVariables.lang.error,
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'error',
|
||||||
|
description: 'XToken is undefined',
|
||||||
|
isClosable: true,
|
||||||
|
rest: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(resp => {
|
||||||
|
let text = 'unknown error ' + resp.status;
|
||||||
|
if (resp.status !== undefined) {
|
||||||
|
const _text =
|
||||||
|
store.getState().appVariables.lang.account.registration.stepTwo
|
||||||
|
.resendError[resp.status as number];
|
||||||
|
if (_text !== undefined) text = _text;
|
||||||
|
}
|
||||||
|
|
||||||
|
showToast(toast, {
|
||||||
|
title: store.getState().appVariables.lang.error,
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'error',
|
||||||
|
description: text,
|
||||||
|
isClosable: true,
|
||||||
|
rest: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
reject(resp.status);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function StepOne() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const regPro = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.RegisterProcess,
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||||
|
|
||||||
|
const initNoErrors = {
|
||||||
|
wrongFormat: false,
|
||||||
|
alreadyExists: false,
|
||||||
|
noEntered: false,
|
||||||
|
unknown: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
const [errors, setErrors] = useState(initNoErrors);
|
||||||
|
|
||||||
|
const isError =
|
||||||
|
errors.wrongFormat ||
|
||||||
|
errors.alreadyExists ||
|
||||||
|
errors.noEntered ||
|
||||||
|
errors.unknown !== undefined;
|
||||||
|
|
||||||
|
const errorText = () => {
|
||||||
|
if (errors.wrongFormat) {
|
||||||
|
return lang.account.registration.stepOne.addressInvalid;
|
||||||
|
}
|
||||||
|
if (errors.alreadyExists) {
|
||||||
|
return lang.account.registration.stepOne.addressExists;
|
||||||
|
}
|
||||||
|
if (errors.noEntered) {
|
||||||
|
return lang.account.registration.stepOne.noMailEntered;
|
||||||
|
}
|
||||||
|
if (errors.unknown !== undefined) {
|
||||||
|
return errors.unknown;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const [values, setValues] = useState({email: regPro.EMail});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (regPro.isRegistering === 'stepTwo') {
|
||||||
|
setLoading(true);
|
||||||
|
setErrors(initNoErrors);
|
||||||
|
|
||||||
|
setTimeout(nextStep, 500);
|
||||||
|
} else if (regPro.isRegistering === 'stepFinal') {
|
||||||
|
setLoading(true);
|
||||||
|
setErrors(initNoErrors);
|
||||||
|
|
||||||
|
setTimeout(nextStep, 500);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const nextStep = () => {
|
||||||
|
setLoading(true);
|
||||||
|
setErrors(initNoErrors);
|
||||||
|
|
||||||
|
makeRequest({
|
||||||
|
path: apiBackendRequest.REGISTER_STEP_1,
|
||||||
|
requestHeader: {},
|
||||||
|
request: {
|
||||||
|
Email: values.email,
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
XToken: undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(resp => {
|
||||||
|
let rp = {...regPro};
|
||||||
|
rp.isRegistering = 'stepTwo';
|
||||||
|
rp.EMail = values.email;
|
||||||
|
rp.XToken = resp.response.XToken;
|
||||||
|
|
||||||
|
dispatch(appVarActions.setRegisterProcess(rp));
|
||||||
|
saveVarChanges();
|
||||||
|
|
||||||
|
showToast(toast, {
|
||||||
|
title: lang.account.registration.stepOne.success,
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'success',
|
||||||
|
description: undefined,
|
||||||
|
isClosable: true,
|
||||||
|
rest: {colorScheme: 'primary'},
|
||||||
|
});
|
||||||
|
|
||||||
|
navigation.navigate('Register', {screen: 'RegStepTwo'});
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(resp => {
|
||||||
|
if (resp.status === 401 || resp.status === 204) {
|
||||||
|
if (regPro.XToken !== undefined) {
|
||||||
|
let rp = {...regPro};
|
||||||
|
|
||||||
|
if (resp.status === 401) {
|
||||||
|
rp.isRegistering = 'stepTwo';
|
||||||
|
rp.EMail = values.email;
|
||||||
|
|
||||||
|
dispatch(appVarActions.setRegisterProcess(rp));
|
||||||
|
saveVarChanges();
|
||||||
|
|
||||||
|
navigation.navigate('Register', {screen: 'RegStepTwo'});
|
||||||
|
} else if (resp.status === 204) {
|
||||||
|
rp.isRegistering = 'stepFinal';
|
||||||
|
rp.EMail = values.email;
|
||||||
|
|
||||||
|
dispatch(appVarActions.setRegisterProcess(rp));
|
||||||
|
saveVarChanges();
|
||||||
|
|
||||||
|
navigation.navigate('Register', {screen: 'RegStepFinal'});
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
} else {
|
||||||
|
resendMail(values.email, toast)
|
||||||
|
.then(() => {
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showToast(toast, {
|
||||||
|
title: 'Error',
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'error',
|
||||||
|
description: resp.status,
|
||||||
|
isClosable: true,
|
||||||
|
rest: {colorScheme: 'primary'},
|
||||||
|
});
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView keyboardShouldPersistTaps="handled">
|
||||||
|
<Box alignItems="center" mt={5}>
|
||||||
|
<FormControl
|
||||||
|
w="75%"
|
||||||
|
maxW="350px"
|
||||||
|
isRequired
|
||||||
|
isDisabled={isLoading}
|
||||||
|
isInvalid={isError}>
|
||||||
|
<FormControl.Label>
|
||||||
|
{lang.account.registration.stepOne.title}
|
||||||
|
</FormControl.Label>
|
||||||
|
<Input
|
||||||
|
autoFocus
|
||||||
|
placeholder={lang.account.registration.stepOne.title}
|
||||||
|
value={values.email}
|
||||||
|
autoCapitalize={'none'}
|
||||||
|
maxLength={emailOptions.maxLength}
|
||||||
|
keyboardType={'email-address'}
|
||||||
|
onChangeText={text => {
|
||||||
|
const mail = text.replaceAll(' ', '');
|
||||||
|
setValues({email: mail});
|
||||||
|
|
||||||
|
if (errors.noEntered && mail !== '') {
|
||||||
|
let err = errors;
|
||||||
|
err.noEntered = false;
|
||||||
|
setErrors({...err});
|
||||||
|
}
|
||||||
|
if (errors.wrongFormat && validateEmail(mail)) {
|
||||||
|
let err = errors;
|
||||||
|
err.wrongFormat = false;
|
||||||
|
setErrors({...err});
|
||||||
|
}
|
||||||
|
if (errors.alreadyExists) {
|
||||||
|
let err = errors;
|
||||||
|
err.alreadyExists = false;
|
||||||
|
setErrors({...err});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormControl.ErrorMessage leftIcon={<WarningOutlineIcon size="xs" />}>
|
||||||
|
{errorText()}
|
||||||
|
</FormControl.ErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
<Container marginY={5}>
|
||||||
|
<Agreement />
|
||||||
|
</Container>
|
||||||
|
<Button
|
||||||
|
w="75%"
|
||||||
|
maxW="350px"
|
||||||
|
colorScheme="primary"
|
||||||
|
rounded="xl"
|
||||||
|
_text={{fontSize: 'xl'}}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onPress={() => {
|
||||||
|
if (values.email === '') {
|
||||||
|
let err = errors;
|
||||||
|
err.noEntered = true;
|
||||||
|
setErrors({...err});
|
||||||
|
} else if (validateEmail(values.email)) {
|
||||||
|
nextStep();
|
||||||
|
} else {
|
||||||
|
let err = errors;
|
||||||
|
err.wrongFormat = true;
|
||||||
|
setErrors({...err});
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
{lang.account.registration.stepOne.button}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function StepTwo() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const regPro = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.RegisterProcess,
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const cellCount = 6;
|
||||||
|
const {colors} = useTheme();
|
||||||
|
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||||
|
|
||||||
|
const initNoErrors = {
|
||||||
|
noEntered: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const [errors, setErrors] = useState(initNoErrors);
|
||||||
|
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const [values, setValues] = useState({code: ''});
|
||||||
|
|
||||||
|
const headerText = () => {
|
||||||
|
return reactStringReplace(
|
||||||
|
lang.account.registration.stepTwo.title,
|
||||||
|
'${EMail}',
|
||||||
|
(match, i) => (
|
||||||
|
<Text key={match + i} color={'primary.400'}>
|
||||||
|
{regPro.EMail}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resendText = () => {
|
||||||
|
return reactStringReplace(
|
||||||
|
lang.account.registration.stepTwo.resend[0],
|
||||||
|
'${resend}',
|
||||||
|
(match, i) => (
|
||||||
|
<Text
|
||||||
|
key={match + i}
|
||||||
|
color={'primary.400'}
|
||||||
|
onPress={() => {
|
||||||
|
setLoading(true);
|
||||||
|
resendMail(
|
||||||
|
store.getState().appVariables.preferences.RegisterProcess.EMail,
|
||||||
|
toast,
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}}>
|
||||||
|
{lang.account.registration.stepTwo.resend[1]}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const validate = (text: string) => {
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
makeRequest({
|
||||||
|
path: apiBackendRequest.REGISTER_STEP_2,
|
||||||
|
|
||||||
|
requestHeader: {},
|
||||||
|
requestGET: {':verifyId': text, ':xToken': regPro.XToken || ''},
|
||||||
|
})
|
||||||
|
.then(resp => {
|
||||||
|
let rp = {...regPro};
|
||||||
|
rp.isRegistering = 'stepFinal';
|
||||||
|
|
||||||
|
dispatch(appVarActions.setRegisterProcess(rp));
|
||||||
|
saveVarChanges();
|
||||||
|
|
||||||
|
showToast(toast, {
|
||||||
|
title: lang.account.registration.stepTwo.success,
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'success',
|
||||||
|
description: undefined,
|
||||||
|
isClosable: true,
|
||||||
|
rest: {colorScheme: 'primary'},
|
||||||
|
});
|
||||||
|
|
||||||
|
navigation.navigate('Register', {screen: 'RegStepFinal'});
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(resp => {
|
||||||
|
let text = 'unknown error ' + resp.status;
|
||||||
|
if (resp.status !== undefined) {
|
||||||
|
const _text =
|
||||||
|
lang.account.registration.stepTwo.verificationError[
|
||||||
|
resp.status as number
|
||||||
|
];
|
||||||
|
if (_text !== undefined) text = _text;
|
||||||
|
}
|
||||||
|
|
||||||
|
showToast(toast, {
|
||||||
|
title: lang.error,
|
||||||
|
variant: 'solid',
|
||||||
|
status: 'error',
|
||||||
|
description: text,
|
||||||
|
isClosable: true,
|
||||||
|
rest: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
if (resp.status === 422) {
|
||||||
|
let rp = {...regPro};
|
||||||
|
rp.isRegistering = false;
|
||||||
|
|
||||||
|
dispatch(appVarActions.setRegisterProcess(rp));
|
||||||
|
saveVarChanges();
|
||||||
|
navigation.navigate('Register', {screen: 'RegStepOne'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView keyboardShouldPersistTaps="handled">
|
||||||
|
<Box alignItems="center" mt={5}>
|
||||||
|
<Center w="75%" maxW="1000px">
|
||||||
|
<Text>{headerText()}</Text>
|
||||||
|
<Box>
|
||||||
|
<FormControl isDisabled={isLoading} isInvalid={errors.noEntered}>
|
||||||
|
<ConfirmationCodeField
|
||||||
|
cellCount={cellCount}
|
||||||
|
charType="number"
|
||||||
|
disabled={isLoading}
|
||||||
|
rest={{mt: 5}}
|
||||||
|
onChange={(text: string) => {
|
||||||
|
setValues({code: text});
|
||||||
|
setErrors(initNoErrors);
|
||||||
|
}}
|
||||||
|
onFinish={(text: string) => validate(text)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormControl.ErrorMessage
|
||||||
|
leftIcon={<WarningOutlineIcon size="xs" />}>
|
||||||
|
{lang.account.registration.stepTwo.noCodeEntered}
|
||||||
|
</FormControl.ErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
</Box>
|
||||||
|
</Center>
|
||||||
|
<Container marginY={5}>
|
||||||
|
<Agreement />
|
||||||
|
</Container>
|
||||||
|
<Button
|
||||||
|
w="75%"
|
||||||
|
maxW="350px"
|
||||||
|
colorScheme="primary"
|
||||||
|
rounded="xl"
|
||||||
|
_text={{fontSize: 'xl'}}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onPress={() => {
|
||||||
|
if (values.code.length === cellCount) {
|
||||||
|
validate(values.code);
|
||||||
|
} else {
|
||||||
|
let err = {...errors};
|
||||||
|
err.noEntered = true;
|
||||||
|
setErrors(err);
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
{lang.account.registration.stepTwo.button}
|
||||||
|
</Button>
|
||||||
|
<Container marginY={5}>
|
||||||
|
<Text textAlign={'justify'} color={'white.900'}>
|
||||||
|
{resendText()}
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function StepFinal() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const regPro = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.RegisterProcess,
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const {colors} = useTheme();
|
||||||
|
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||||
|
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
|
interface inputElementType {
|
||||||
|
label: string;
|
||||||
|
input: string;
|
||||||
|
autoCapitalize: 'none' | 'words';
|
||||||
|
errorIndex: 'none' | string;
|
||||||
|
errorTextObject: any;
|
||||||
|
isPassword: boolean | 'passwordRepeat';
|
||||||
|
minLength: number;
|
||||||
|
maxLength: number;
|
||||||
|
onTextChange: any;
|
||||||
|
textChangeTimeout: number;
|
||||||
|
isAllowed: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const accountNameRef = useRef(setTimeout(() => {}));
|
||||||
|
const accountNameFetchRef = useRef(setTimeout(() => {}));
|
||||||
|
|
||||||
|
const accountName = {
|
||||||
|
label: lang.account.registration.stepFinal.accountName,
|
||||||
|
input: '',
|
||||||
|
errorIndex: 'none',
|
||||||
|
errorTextObject: lang.account.registration.stepFinal.accountNameError,
|
||||||
|
minLength: accountNameOptions.minLength,
|
||||||
|
maxLength: accountNameOptions.maxLength,
|
||||||
|
isAllowed: accountNameOptions.isAllowed,
|
||||||
|
isPassword: false,
|
||||||
|
onTextChange: (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
||||||
|
let text = e.nativeEvent.text;
|
||||||
|
let self = accountName;
|
||||||
|
|
||||||
|
clearTimeout(accountNameRef.current);
|
||||||
|
|
||||||
|
let obj = {...valuesAccountName};
|
||||||
|
accountNameRef.current = setTimeout(() => {
|
||||||
|
obj.input = text;
|
||||||
|
|
||||||
|
if (text.length < self.minLength) obj.errorIndex = 'tooShort';
|
||||||
|
else if (text.length > self.maxLength) obj.errorIndex = 'tooLong';
|
||||||
|
else if (self.isAllowed(text) === false) obj.errorIndex = 'invalid';
|
||||||
|
else obj.errorIndex = 'none';
|
||||||
|
|
||||||
|
setValuesAccountName(obj);
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
clearTimeout(accountNameFetchRef.current);
|
||||||
|
accountNameFetchRef.current = setTimeout(() => {
|
||||||
|
console.log(obj);
|
||||||
|
|
||||||
|
if (obj.errorIndex === 'none') {
|
||||||
|
makeRequest({
|
||||||
|
path: apiBackendRequest.REGISTER_STEP_FINAL_ACCOUNT_NAME_CHECK,
|
||||||
|
request: {AccountName: obj.input},
|
||||||
|
})
|
||||||
|
.then(resp => {
|
||||||
|
console.log('OK');
|
||||||
|
})
|
||||||
|
.catch(resp => {
|
||||||
|
if (resp.status !== undefined) {
|
||||||
|
obj.errorIndex = resp.status;
|
||||||
|
setValuesAccountName(obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 750);
|
||||||
|
},
|
||||||
|
} as inputElementType;
|
||||||
|
const [valuesAccountName, setValuesAccountName] = useState(accountName);
|
||||||
|
|
||||||
|
const userNameRef = useRef(setTimeout(() => {}));
|
||||||
|
|
||||||
|
const userName = {
|
||||||
|
label: lang.account.registration.stepFinal.userName,
|
||||||
|
input: '',
|
||||||
|
errorIndex: 'none',
|
||||||
|
errorTextObject: lang.account.registration.stepFinal.userNameError,
|
||||||
|
minLength: userNameOptions.minLength,
|
||||||
|
maxLength: userNameOptions.maxLength,
|
||||||
|
isAllowed: userNameOptions.isAllowed,
|
||||||
|
isPassword: false,
|
||||||
|
onTextChange: (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
||||||
|
let text = e.nativeEvent.text;
|
||||||
|
let self = userName;
|
||||||
|
|
||||||
|
clearTimeout(userNameRef.current);
|
||||||
|
|
||||||
|
userNameRef.current = setTimeout(() => {
|
||||||
|
let obj = {...valuesUserName};
|
||||||
|
obj.input = text;
|
||||||
|
|
||||||
|
if (text.length < self.minLength) obj.errorIndex = 'tooShort';
|
||||||
|
else if (text.length > self.maxLength) obj.errorIndex = 'tooLong';
|
||||||
|
else if (self.isAllowed(text) === false) obj.errorIndex = 'invalid';
|
||||||
|
else obj.errorIndex = 'none';
|
||||||
|
|
||||||
|
setValuesUserName(obj);
|
||||||
|
}, 50);
|
||||||
|
},
|
||||||
|
} as inputElementType;
|
||||||
|
const [valuesUserName, setValuesUserName] = useState(userName);
|
||||||
|
|
||||||
|
const passwordRef = useRef(setTimeout(() => {}));
|
||||||
|
|
||||||
|
const password = {
|
||||||
|
label: lang.account.registration.stepFinal.password,
|
||||||
|
input: '',
|
||||||
|
errorIndex: 'none',
|
||||||
|
errorTextObject: lang.account.registration.stepFinal.passwordError,
|
||||||
|
minLength: passwordOptions.minLength,
|
||||||
|
maxLength: passwordOptions.maxLength,
|
||||||
|
isAllowed: passwordOptions.isAllowed,
|
||||||
|
isPassword: true,
|
||||||
|
onTextChange: (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
||||||
|
let text = e.nativeEvent.text;
|
||||||
|
let self = password;
|
||||||
|
|
||||||
|
clearTimeout(passwordRef.current);
|
||||||
|
|
||||||
|
passwordRef.current = setTimeout(() => {
|
||||||
|
let obj = {...valuesPassword};
|
||||||
|
obj.input = text;
|
||||||
|
|
||||||
|
if (text.length < self.minLength) obj.errorIndex = 'tooShort';
|
||||||
|
else if (text.length > self.maxLength) obj.errorIndex = 'tooLong';
|
||||||
|
else if (self.isAllowed(text) === false) obj.errorIndex = 'invalid';
|
||||||
|
else obj.errorIndex = 'none';
|
||||||
|
|
||||||
|
setValuesPassword(obj);
|
||||||
|
|
||||||
|
let objRe = {...valuesPasswordRe};
|
||||||
|
if (text !== valuesPasswordRe.input) objRe.errorIndex = 'noMatch';
|
||||||
|
else objRe.errorIndex = 'none';
|
||||||
|
|
||||||
|
setValuesPasswordRe(objRe);
|
||||||
|
}, 50);
|
||||||
|
},
|
||||||
|
} as inputElementType;
|
||||||
|
const [valuesPassword, setValuesPassword] = useState(password);
|
||||||
|
|
||||||
|
const passwordReRef = useRef(setTimeout(() => {}));
|
||||||
|
|
||||||
|
const passwordRe = {
|
||||||
|
label: lang.account.registration.stepFinal.passwordRepeat,
|
||||||
|
input: '',
|
||||||
|
errorIndex: 'none',
|
||||||
|
errorTextObject: lang.account.registration.stepFinal.passwordError,
|
||||||
|
minLength: passwordOptions.minLength,
|
||||||
|
maxLength: passwordOptions.maxLength,
|
||||||
|
isAllowed: passwordOptions.isAllowed,
|
||||||
|
isPassword: 'passwordRepeat',
|
||||||
|
onTextChange: (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
||||||
|
let text = e.nativeEvent.text;
|
||||||
|
let self = passwordRe;
|
||||||
|
|
||||||
|
clearTimeout(passwordReRef.current);
|
||||||
|
|
||||||
|
passwordReRef.current = setTimeout(() => {
|
||||||
|
let obj = {...valuesPasswordRe};
|
||||||
|
obj.input = text;
|
||||||
|
console.log(text, valuesPassword.input);
|
||||||
|
|
||||||
|
if (text !== valuesPassword.input) obj.errorIndex = 'noMatch';
|
||||||
|
else obj.errorIndex = 'none';
|
||||||
|
|
||||||
|
setValuesPasswordRe(obj);
|
||||||
|
}, 50);
|
||||||
|
},
|
||||||
|
} as inputElementType;
|
||||||
|
const [valuesPasswordRe, setValuesPasswordRe] = useState(passwordRe);
|
||||||
|
|
||||||
|
const inputElement = (
|
||||||
|
val: inputElementType,
|
||||||
|
set: React.Dispatch<React.SetStateAction<inputElementType>>,
|
||||||
|
valConst: inputElementType,
|
||||||
|
autofocus?: boolean,
|
||||||
|
) => {
|
||||||
|
const isPassword =
|
||||||
|
val.isPassword === true || val.isPassword === 'passwordRepeat';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
w="75%"
|
||||||
|
maxW="350px"
|
||||||
|
isRequired
|
||||||
|
isDisabled={isLoading}
|
||||||
|
isInvalid={val.errorIndex !== 'none'}>
|
||||||
|
<FormControl.Label>{val.label}</FormControl.Label>
|
||||||
|
<Input
|
||||||
|
autoFocus={autofocus}
|
||||||
|
type={isPassword && showPassword === false ? 'password' : 'text'}
|
||||||
|
placeholder={''}
|
||||||
|
keyboardType={'default'}
|
||||||
|
onChange={valConst.onTextChange}
|
||||||
|
InputRightElement={
|
||||||
|
isPassword ? (
|
||||||
|
<IconButton
|
||||||
|
mr="2"
|
||||||
|
onPress={() => setShowPassword(!showPassword)}
|
||||||
|
icon={
|
||||||
|
<MaterialIcons
|
||||||
|
size={20}
|
||||||
|
name={showPassword ? 'visibility' : 'visibility-off'}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
borderRadius="full"
|
||||||
|
/>
|
||||||
|
) : undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormControl.ErrorMessage leftIcon={<WarningOutlineIcon size="xs" />}>
|
||||||
|
{val.errorTextObject[val.errorIndex] !== undefined
|
||||||
|
? val.errorTextObject[val.errorIndex]
|
||||||
|
.replaceAll('$(minLength)', val.minLength)
|
||||||
|
.replaceAll('$(maxLength)', val.maxLength)
|
||||||
|
: val.errorTextObject[val.errorIndex] !== 'none'
|
||||||
|
? lang.error
|
||||||
|
: null}
|
||||||
|
</FormControl.ErrorMessage>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView keyboardShouldPersistTaps="handled">
|
||||||
|
<VStack space={3} alignItems="center" mt={5}>
|
||||||
|
<Container maxWidth={'100%'} alignItems={'center'}>
|
||||||
|
<Center>
|
||||||
|
<Text>{lang.account.registration.stepFinal.displayName}</Text>
|
||||||
|
<NameDisplay
|
||||||
|
UserName={
|
||||||
|
valuesUserName.input !== ''
|
||||||
|
? valuesUserName.input
|
||||||
|
: lang.account.registration.stepFinal.userName
|
||||||
|
}
|
||||||
|
AccountName={
|
||||||
|
valuesAccountName.input !== ''
|
||||||
|
? valuesAccountName.input
|
||||||
|
: lang.account.registration.stepFinal.accountName
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
</Container>
|
||||||
|
{inputElement(valuesUserName, setValuesUserName, userName)}
|
||||||
|
{inputElement(valuesAccountName, setValuesAccountName, accountName)}
|
||||||
|
{inputElement(valuesPassword, setValuesPassword, password)}
|
||||||
|
{inputElement(valuesPasswordRe, setValuesPasswordRe, passwordRe)}
|
||||||
|
</VStack>
|
||||||
|
<Center>
|
||||||
|
<Container mt={5}>
|
||||||
|
<Agreement />
|
||||||
|
</Container>
|
||||||
|
<Button
|
||||||
|
marginY={5}
|
||||||
|
w="75%"
|
||||||
|
maxW="350px"
|
||||||
|
colorScheme="primary"
|
||||||
|
rounded="xl"
|
||||||
|
_text={{fontSize: 'xl'}}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onPress={() => {}}>
|
||||||
|
{lang.account.registration.stepFinal.button}
|
||||||
|
</Button>
|
||||||
|
</Center>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
import {
|
||||||
|
Alert,
|
||||||
|
Button,
|
||||||
|
Center,
|
||||||
|
CloseIcon,
|
||||||
|
HStack,
|
||||||
|
IconButton,
|
||||||
|
Text,
|
||||||
|
VStack,
|
||||||
|
} from 'native-base';
|
||||||
|
import {ResponsiveValue} from 'native-base/lib/typescript/components/types';
|
||||||
|
|
||||||
|
const {useToast} = require('native-base');
|
||||||
|
|
||||||
|
const Toast = () => {
|
||||||
|
const toast = useToast();
|
||||||
|
const ToastDetails = [
|
||||||
|
{
|
||||||
|
title: 'Account verified',
|
||||||
|
variant: 'solid',
|
||||||
|
description: 'Thanks for signing up with us.',
|
||||||
|
isClosable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Something went wrong',
|
||||||
|
variant: 'subtle',
|
||||||
|
description: 'Please create a support ticket from the support page',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Network connection restored',
|
||||||
|
variant: 'left-accent',
|
||||||
|
description:
|
||||||
|
'This is to inform you that your network connectivity is restored',
|
||||||
|
isClosable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Invalid email address',
|
||||||
|
variant: 'top-accent',
|
||||||
|
description: 'Please enter a valid email address',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Invalid email address',
|
||||||
|
variant: 'outline',
|
||||||
|
description: 'Please enter a valid email address',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
interface toastType {
|
||||||
|
id?: string;
|
||||||
|
status?: 'info' | (string & {}) | 'error' | 'success' | 'warning';
|
||||||
|
variant: ResponsiveValue<
|
||||||
|
| 'subtle'
|
||||||
|
| 'solid'
|
||||||
|
| 'left-accent'
|
||||||
|
| 'top-accent'
|
||||||
|
| 'outline'
|
||||||
|
| 'outline-light'
|
||||||
|
| (string & {})
|
||||||
|
>;
|
||||||
|
title: any;
|
||||||
|
description: any;
|
||||||
|
isClosable?: boolean;
|
||||||
|
rest: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface alertType extends toastType {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showToast(toast: any, item: toastType) {
|
||||||
|
const ToastAlert = ({
|
||||||
|
id,
|
||||||
|
status,
|
||||||
|
variant,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
isClosable,
|
||||||
|
rest,
|
||||||
|
}: alertType) => (
|
||||||
|
<Alert
|
||||||
|
maxWidth="95%"
|
||||||
|
alignSelf="center"
|
||||||
|
flexDirection="row"
|
||||||
|
status={status ? status : 'info'}
|
||||||
|
variant={variant}
|
||||||
|
{...rest}>
|
||||||
|
<VStack space={1} flexShrink={1} w="100%">
|
||||||
|
<HStack
|
||||||
|
flexShrink={1}
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="space-between">
|
||||||
|
<HStack space={2} flexShrink={1} alignItems="center">
|
||||||
|
<Alert.Icon />
|
||||||
|
<Text
|
||||||
|
fontSize="md"
|
||||||
|
fontWeight="medium"
|
||||||
|
flexShrink={1}
|
||||||
|
color={
|
||||||
|
variant === 'solid'
|
||||||
|
? 'lightText'
|
||||||
|
: variant !== 'outline'
|
||||||
|
? 'darkText'
|
||||||
|
: null
|
||||||
|
}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
</HStack>
|
||||||
|
{isClosable ? (
|
||||||
|
<IconButton
|
||||||
|
variant="unstyled"
|
||||||
|
icon={<CloseIcon size="3" />}
|
||||||
|
_icon={{
|
||||||
|
color: variant === 'solid' ? 'lightText' : 'darkText',
|
||||||
|
}}
|
||||||
|
onPress={() => toast.close(id)}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</HStack>
|
||||||
|
<Text
|
||||||
|
px="6"
|
||||||
|
color={
|
||||||
|
variant === 'solid'
|
||||||
|
? 'lightText'
|
||||||
|
: variant !== 'outline'
|
||||||
|
? 'darkText'
|
||||||
|
: null
|
||||||
|
}>
|
||||||
|
{description}
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
|
||||||
|
toast.show({
|
||||||
|
render: ({id}: {id: string}) => {
|
||||||
|
return <ToastAlert id={id} {...item} />;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default showToast;
|
|
@ -1,3 +1,4 @@
|
||||||
|
import {EMail, XToken} from '@caj/helper/types';
|
||||||
import {VersionType} from '@caj/helper/version';
|
import {VersionType} from '@caj/helper/version';
|
||||||
import {APP_VERSION} from './appNonSaveVar';
|
import {APP_VERSION} from './appNonSaveVar';
|
||||||
|
|
||||||
|
@ -43,13 +44,24 @@ export function applyUpdateChanges(appVar: any): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
//these variables may be changed by the user and will be saved in storage
|
//these variables may be changed by the user and will be saved in storage
|
||||||
|
export interface RegisterProcess {
|
||||||
|
isRegistering: false | 'stepTwo' | 'stepFinal';
|
||||||
|
XToken: XToken | undefined;
|
||||||
|
EMail: EMail;
|
||||||
|
}
|
||||||
|
|
||||||
export interface PREFERENCES_VARS {
|
export interface PREFERENCES_VARS {
|
||||||
version: VersionType;
|
version: VersionType;
|
||||||
theme: ThemeMode;
|
theme: ThemeMode;
|
||||||
|
RegisterProcess: RegisterProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const preferences_vars_default: PREFERENCES_VARS = {
|
export const preferences_vars_default: PREFERENCES_VARS = {
|
||||||
version: APP_VERSION, //version of datatypes in storage
|
version: APP_VERSION, //version of datatypes in storage
|
||||||
theme: ThemeMode.Dark,
|
theme: ThemeMode.Dark,
|
||||||
|
RegisterProcess: {
|
||||||
|
isRegistering: false,
|
||||||
|
XToken: undefined,
|
||||||
|
EMail: '',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import {createSlice} from '@reduxjs/toolkit';
|
import {createSlice} from '@reduxjs/toolkit';
|
||||||
import type {PayloadAction} from '@reduxjs/toolkit';
|
import type {PayloadAction} from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import {PREFERENCES_VARS, preferences_vars_default, ThemeMode} from './appVar';
|
import {
|
||||||
|
PREFERENCES_VARS,
|
||||||
|
preferences_vars_default,
|
||||||
|
RegisterProcess,
|
||||||
|
ThemeMode,
|
||||||
|
} from './appVar';
|
||||||
import {non_save_vars, NON_SAVE_VARS} from './appNonSaveVar';
|
import {non_save_vars, NON_SAVE_VARS} from './appNonSaveVar';
|
||||||
import LangFormat from '@caj/lang/default';
|
import LangFormat from '@caj/lang/default';
|
||||||
import {lang as defaultLang} from '@caj/lang/en';
|
import {lang as defaultLang} from '@caj/lang/en';
|
||||||
|
@ -29,6 +34,9 @@ export const appVariablesSlice = createSlice({
|
||||||
loadPreferences: (state, action: PayloadAction<PREFERENCES_VARS>) => {
|
loadPreferences: (state, action: PayloadAction<PREFERENCES_VARS>) => {
|
||||||
state.preferences = action.payload;
|
state.preferences = action.payload;
|
||||||
},
|
},
|
||||||
|
setRegisterProcess: (state, action: PayloadAction<RegisterProcess>) => {
|
||||||
|
state.preferences.RegisterProcess = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,83 +1,194 @@
|
||||||
import {Platform} from 'react-native';
|
import {Platform} from 'react-native';
|
||||||
import {extendTheme, useColorMode} from 'native-base';
|
import {extendTheme, Theme, useColorMode} from 'native-base';
|
||||||
import {ThemeMode} from './appVar';
|
import {ThemeMode} from './appVar';
|
||||||
|
|
||||||
import {useSelector} from 'react-redux';
|
import {useSelector} from 'react-redux';
|
||||||
import {RootState} from '@caj/redux/store';
|
import {RootState} from '@caj/redux/store';
|
||||||
import {useEffect} from 'react';
|
import {useEffect} from 'react';
|
||||||
|
|
||||||
export const theme = extendTheme({
|
export const theme = (_theme: ThemeMode) => {
|
||||||
config: {
|
return extendTheme({
|
||||||
// Changing initialColorMode to 'dark'
|
config: {
|
||||||
initialColorMode: 'dark',
|
// Changing initialColorMode to 'dark'
|
||||||
},
|
initialColorMode: 'dark',
|
||||||
fonts: {
|
|
||||||
header: 'Outfit-Regular',
|
|
||||||
medium: 'Outfit-Regular',
|
|
||||||
regular: 'Outfit-Regular',
|
|
||||||
semibold: 'Outfit-Regular',
|
|
||||||
},
|
|
||||||
colors: {
|
|
||||||
black: {
|
|
||||||
100: '#C4C4C4',
|
|
||||||
200: '#7C7C7C',
|
|
||||||
300: '#292929',
|
|
||||||
800: '#181725',
|
|
||||||
},
|
},
|
||||||
|
fonts: {
|
||||||
|
header: 'Outfit-Regular',
|
||||||
|
medium: 'Outfit-Regular',
|
||||||
|
regular: 'Outfit-Regular',
|
||||||
|
semibold: 'Outfit-Regular',
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
black: [
|
||||||
|
{
|
||||||
|
// darkest
|
||||||
|
100: '#414755',
|
||||||
|
200: '#313640',
|
||||||
|
300: '#293037',
|
||||||
|
400: '#282e35',
|
||||||
|
500: '#23272e',
|
||||||
|
600: '#1a1d22',
|
||||||
|
700: '#19191e',
|
||||||
|
800: '#101013',
|
||||||
|
900: '#060607',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
//dark
|
||||||
|
100: '#414755',
|
||||||
|
200: '#313640',
|
||||||
|
300: '#293037',
|
||||||
|
400: '#282e35',
|
||||||
|
500: '#23272e',
|
||||||
|
600: '#1a1d22',
|
||||||
|
700: '#19191e',
|
||||||
|
800: '#101013',
|
||||||
|
900: '#060607',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
//light
|
||||||
|
900: '#e9e8f0',
|
||||||
|
800: '#e4e3ec',
|
||||||
|
700: '#dfdde8',
|
||||||
|
600: '#dad8e4',
|
||||||
|
500: '#d7d5e1',
|
||||||
|
400: '#d4d2de',
|
||||||
|
300: '#d2d0db',
|
||||||
|
200: '#cfcdd8',
|
||||||
|
100: '#cdcbd5',
|
||||||
|
},
|
||||||
|
][_theme],
|
||||||
|
blackBG: [
|
||||||
|
{
|
||||||
|
// darkest
|
||||||
|
100: '#000',
|
||||||
|
200: '#000',
|
||||||
|
300: '#000',
|
||||||
|
400: '#000',
|
||||||
|
500: '#000',
|
||||||
|
600: '#000',
|
||||||
|
700: '#000',
|
||||||
|
800: '#000',
|
||||||
|
900: '#000',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
//dark
|
||||||
|
100: '#414755',
|
||||||
|
200: '#313640',
|
||||||
|
300: '#293037',
|
||||||
|
400: '#282e35',
|
||||||
|
500: '#23272e',
|
||||||
|
600: '#1a1d22',
|
||||||
|
700: '#19191e',
|
||||||
|
800: '#101013',
|
||||||
|
900: '#060607',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
//light
|
||||||
|
900: '#e9e8f0',
|
||||||
|
800: '#e4e3ec',
|
||||||
|
700: '#dfdde8',
|
||||||
|
600: '#dad8e4',
|
||||||
|
500: '#d7d5e1',
|
||||||
|
400: '#d4d2de',
|
||||||
|
300: '#d2d0db',
|
||||||
|
200: '#cfcdd8',
|
||||||
|
100: '#cdcbd5',
|
||||||
|
},
|
||||||
|
][_theme],
|
||||||
|
white: [
|
||||||
|
{
|
||||||
|
// darkest
|
||||||
|
100: '#ccc',
|
||||||
|
200: '#ccc',
|
||||||
|
300: '#ccc',
|
||||||
|
400: '#ccc',
|
||||||
|
500: '#ccc',
|
||||||
|
600: '#ccc',
|
||||||
|
700: '#ccc',
|
||||||
|
800: '#ccc',
|
||||||
|
900: '#ccc',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
//dark
|
||||||
|
|
||||||
primary: {
|
900: '#e9e8f0',
|
||||||
50: '#fff4f1',
|
800: '#e4e3ec',
|
||||||
100: '#ffd6c9',
|
700: '#dfdde8',
|
||||||
200: '#ffb9a1',
|
600: '#dad8e4',
|
||||||
300: '#ff9b79',
|
500: '#d7d5e1',
|
||||||
400: '#ff7d50',
|
400: '#d4d2de',
|
||||||
500: '#f96e40',
|
300: '#d2d0db',
|
||||||
600: '#f26030',
|
200: '#cfcdd8',
|
||||||
700: '#e95321',
|
100: '#cdcbd5',
|
||||||
800: '#d54b1d',
|
},
|
||||||
900: '#ba4721',
|
{
|
||||||
},
|
//light
|
||||||
},
|
100: '#414755',
|
||||||
components: {
|
200: '#313640',
|
||||||
Divider: {
|
300: '#293037',
|
||||||
baseStyle: ({colorMode}) => {
|
400: '#282e35',
|
||||||
return {
|
500: '#23272e',
|
||||||
backgroundColor: colorMode === 'dark' ? 'black.100' : 'black.200',
|
600: '#1a1d22',
|
||||||
};
|
700: '#19191e',
|
||||||
|
800: '#101013',
|
||||||
|
900: '#060607',
|
||||||
|
},
|
||||||
|
][_theme],
|
||||||
|
|
||||||
|
primary: {
|
||||||
|
50: '#fff4f1',
|
||||||
|
100: '#ffd6c9',
|
||||||
|
200: '#ffb9a1',
|
||||||
|
300: '#ff9b79',
|
||||||
|
400: '#ff7d4f',
|
||||||
|
500: '#f96e40',
|
||||||
|
600: '#f26030',
|
||||||
|
700: '#e95321',
|
||||||
|
800: '#d54b1d',
|
||||||
|
900: '#ba4721',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Text: {
|
components: {
|
||||||
defaultProps: {
|
Divider: {
|
||||||
size: 'md',
|
baseStyle: ({colorMode}) => {
|
||||||
fontFamily: 'Outfit-Regular',
|
return {
|
||||||
colorScheme: 'red',
|
backgroundColor: colorMode === 'dark' ? 'black.100' : 'black.200',
|
||||||
},
|
};
|
||||||
sizes: {
|
|
||||||
xl: {
|
|
||||||
fontSize: '64px',
|
|
||||||
},
|
|
||||||
lg: {
|
|
||||||
fontSize: '32px',
|
|
||||||
},
|
|
||||||
md: {
|
|
||||||
fontSize: '16px',
|
|
||||||
},
|
|
||||||
sm: {
|
|
||||||
fontSize: '12px',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Button: {
|
Text: {
|
||||||
// Can simply pass default props to change default behaviour of components.
|
|
||||||
baseStyle: {
|
|
||||||
rounded: 'md',
|
|
||||||
},
|
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
colorScheme: 'red',
|
size: 'md',
|
||||||
|
fontFamily: 'Outfit-Regular',
|
||||||
|
colorScheme: 'black',
|
||||||
|
},
|
||||||
|
sizes: {
|
||||||
|
xl: {
|
||||||
|
fontSize: '64px',
|
||||||
|
},
|
||||||
|
lg: {
|
||||||
|
fontSize: '32px',
|
||||||
|
},
|
||||||
|
md: {
|
||||||
|
fontSize: '16px',
|
||||||
|
},
|
||||||
|
sm: {
|
||||||
|
fontSize: '12px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Button: {
|
||||||
|
// Can simply pass default props to change default behaviour of components.
|
||||||
|
baseStyle: {
|
||||||
|
rounded: 'md',
|
||||||
|
},
|
||||||
|
defaultProps: {
|
||||||
|
colorScheme: 'primary',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
});
|
};
|
||||||
|
|
||||||
export function getBackgroundColor(tm: ThemeMode): string {
|
export function getBackgroundColor(tm: ThemeMode): string {
|
||||||
switch (tm) {
|
switch (tm) {
|
||||||
|
@ -86,7 +197,7 @@ export function getBackgroundColor(tm: ThemeMode): string {
|
||||||
case ThemeMode.Darkest:
|
case ThemeMode.Darkest:
|
||||||
return '#000';
|
return '#000';
|
||||||
default:
|
default:
|
||||||
return '#282f34';
|
return '#1b1c22';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,3 +228,26 @@ export function ThemeSwitcher() {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const defaultHeaderStyle = (cur: ThemeMode, place?: 'registration') => {
|
||||||
|
if (place === 'registration') {
|
||||||
|
return {
|
||||||
|
headerTintColor: '#fff',
|
||||||
|
headerStyle: {
|
||||||
|
backgroundColor: theme(cur).colors.primary[500],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
headerTintColor: theme(cur).colors.primary[400],
|
||||||
|
headerStyle: {
|
||||||
|
backgroundColor:
|
||||||
|
cur === ThemeMode.Light
|
||||||
|
? '#eee'
|
||||||
|
: cur === ThemeMode.Dark
|
||||||
|
? '#181d21'
|
||||||
|
: '#000',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
import {useFocusEffect} from '@react-navigation/native';
|
||||||
|
import {animated, useSpring} from '@react-spring/native';
|
||||||
|
import {useEffect} from 'react';
|
||||||
|
import {Dimensions, View} from 'react-native';
|
||||||
|
|
||||||
|
const AnimationView = animated(View);
|
||||||
|
|
||||||
|
export const FadeInView = (props: any) => {
|
||||||
|
const [motionProps, api] = useSpring(
|
||||||
|
() => ({
|
||||||
|
from: {
|
||||||
|
opacity: 0,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
useFocusEffect(() => {
|
||||||
|
api.start({
|
||||||
|
to: [
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
api.start({
|
||||||
|
to: [
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnimationView // Special animatable View
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
opacity: motionProps.opacity, // Bind opacity to animated value
|
||||||
|
}}>
|
||||||
|
{props.children}
|
||||||
|
</AnimationView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SlideFromLeftView = (props: any) => {
|
||||||
|
let SCREEN_WIDTH = Dimensions.get('window').width;
|
||||||
|
|
||||||
|
const [motionProps, api] = useSpring(
|
||||||
|
() => ({
|
||||||
|
from: {
|
||||||
|
translateX: -SCREEN_WIDTH,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
useFocusEffect(() => {
|
||||||
|
api.start({
|
||||||
|
to: [
|
||||||
|
{
|
||||||
|
translateX: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
SCREEN_WIDTH = Dimensions.get('window').width;
|
||||||
|
api.start({
|
||||||
|
to: [
|
||||||
|
{
|
||||||
|
translateX: -SCREEN_WIDTH,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnimationView // Special animatable View
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
transform: [{translateX: motionProps.translateX}],
|
||||||
|
}}>
|
||||||
|
{props.children}
|
||||||
|
</AnimationView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SlideFromRightView = (props: any) => {
|
||||||
|
let SCREEN_WIDTH = Dimensions.get('window').width;
|
||||||
|
|
||||||
|
const [motionProps, api] = useSpring(
|
||||||
|
() => ({
|
||||||
|
from: {
|
||||||
|
translateX: SCREEN_WIDTH,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
useFocusEffect(() => {
|
||||||
|
api.start({
|
||||||
|
to: [
|
||||||
|
{
|
||||||
|
translateX: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
SCREEN_WIDTH = Dimensions.get('window').width;
|
||||||
|
api.start({
|
||||||
|
to: [
|
||||||
|
{
|
||||||
|
translateX: SCREEN_WIDTH,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnimationView // Special animatable View
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
transform: [{translateX: motionProps.translateX}],
|
||||||
|
}}>
|
||||||
|
{props.children}
|
||||||
|
</AnimationView>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,168 @@
|
||||||
|
import {types} from '@babel/core';
|
||||||
|
import {store} from '@caj/redux/store';
|
||||||
|
import {Any} from '@react-spring/types';
|
||||||
|
import {type} from 'os';
|
||||||
|
import {Platform} from 'react-native';
|
||||||
|
|
||||||
|
import getUserAgent from './userAgent';
|
||||||
|
|
||||||
|
import {
|
||||||
|
AccountName,
|
||||||
|
EMail,
|
||||||
|
Password,
|
||||||
|
SessionId,
|
||||||
|
UserId,
|
||||||
|
Username,
|
||||||
|
verifyId,
|
||||||
|
WebSocketSessionId,
|
||||||
|
XToken,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
export const apiPath = {
|
||||||
|
backend: {
|
||||||
|
prefix: 'https://alpha-api.clickandjoin.umbach.dev/v1',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum apiBackendRequest {
|
||||||
|
REGISTER_STEP_1 = '/admin/users/email',
|
||||||
|
REGISTER_RESEND_MAIL = '/admin/users/email/resend',
|
||||||
|
REGISTER_STEP_2 = '/verify/email/:xToken/:verifyId',
|
||||||
|
REGISTER_STEP_FINAL = '/admin/users',
|
||||||
|
REGISTER_STEP_FINAL_ACCOUNT_NAME_CHECK = '/admin/users/validation/accountname',
|
||||||
|
}
|
||||||
|
|
||||||
|
type requestGET = {[key: string]: string};
|
||||||
|
|
||||||
|
export interface defaultRequest {
|
||||||
|
status?: 200 | 400 | 422 | 500;
|
||||||
|
error?: string;
|
||||||
|
requestGET?: requestGET;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface REGISTER_STEP_1 extends defaultRequest {
|
||||||
|
path: apiBackendRequest.REGISTER_STEP_1;
|
||||||
|
requestHeader: {};
|
||||||
|
request: {
|
||||||
|
Email: EMail;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
XToken: XToken | undefined;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
interface REGISTER_RESEND_MAIL extends defaultRequest {
|
||||||
|
path: apiBackendRequest.REGISTER_RESEND_MAIL;
|
||||||
|
requestHeader: {};
|
||||||
|
request: {
|
||||||
|
Email: EMail;
|
||||||
|
};
|
||||||
|
// response: {
|
||||||
|
// XToken: XToken | undefined;
|
||||||
|
//};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface REGISTER_STEP_2 extends defaultRequest {
|
||||||
|
path: apiBackendRequest.REGISTER_STEP_2;
|
||||||
|
requestHeader: {};
|
||||||
|
requestGET: {
|
||||||
|
':xToken': XToken;
|
||||||
|
':verifyId': verifyId;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface REGISTER_STEP_FINAL_ACCOUNT_NAME_CHECK extends defaultRequest {
|
||||||
|
path: apiBackendRequest.REGISTER_STEP_FINAL_ACCOUNT_NAME_CHECK;
|
||||||
|
|
||||||
|
request: {
|
||||||
|
AccountName: AccountName;
|
||||||
|
};
|
||||||
|
// response: {
|
||||||
|
// XToken: XToken | undefined;
|
||||||
|
//};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface REGISTER_STEP_FINAL extends defaultRequest {
|
||||||
|
path: apiBackendRequest.REGISTER_STEP_FINAL;
|
||||||
|
requestHeader: {
|
||||||
|
XToken: XToken;
|
||||||
|
};
|
||||||
|
request: {
|
||||||
|
AccountName: AccountName;
|
||||||
|
Username: Username;
|
||||||
|
Password: Password;
|
||||||
|
};
|
||||||
|
response?: {
|
||||||
|
SessionId: SessionId;
|
||||||
|
UserId: UserId;
|
||||||
|
WebSocketSessionId: WebSocketSessionId;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type FetchTypes =
|
||||||
|
| REGISTER_STEP_1
|
||||||
|
| REGISTER_RESEND_MAIL
|
||||||
|
| REGISTER_STEP_2
|
||||||
|
| REGISTER_STEP_FINAL
|
||||||
|
| REGISTER_STEP_FINAL_ACCOUNT_NAME_CHECK;
|
||||||
|
|
||||||
|
function isA(obj: any): obj is REGISTER_STEP_1 {
|
||||||
|
return obj.request !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeRequest<T1 extends FetchTypes>(type: T1): Promise<T1> {
|
||||||
|
let makeRequestObj: any = type;
|
||||||
|
|
||||||
|
let path = type.path.toString();
|
||||||
|
|
||||||
|
if (type.requestGET !== undefined) {
|
||||||
|
for (let key in type.requestGET) {
|
||||||
|
path = path.replaceAll(key, (type.requestGET as requestGET)[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple POST request with a JSON body using fetch
|
||||||
|
|
||||||
|
let headers: HeadersInit = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-App-Version': store
|
||||||
|
.getState()
|
||||||
|
.nonSaveVariables.currentAppVersion.toString(),
|
||||||
|
'X-Language': store.getState().appVariables.lang.details.langCode,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Platform.OS === 'android' || Platform.OS === 'ios')
|
||||||
|
headers['User-Agent'] = getUserAgent();
|
||||||
|
|
||||||
|
const requestOptions: RequestInit = {
|
||||||
|
method: makeRequestObj.request !== undefined ? 'POST' : 'GET',
|
||||||
|
|
||||||
|
headers,
|
||||||
|
body:
|
||||||
|
makeRequestObj.request !== undefined
|
||||||
|
? JSON.stringify(makeRequestObj.request)
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise<T1>((resolve, reject) => {
|
||||||
|
fetch(apiPath.backend.prefix + path, requestOptions)
|
||||||
|
.then(response => {
|
||||||
|
makeRequestObj.status = response.status;
|
||||||
|
|
||||||
|
if (makeRequestObj.response === undefined) return {};
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
makeRequestObj.response = data;
|
||||||
|
|
||||||
|
//console.log(makeRequestObj);
|
||||||
|
if (makeRequestObj.status !== 200) reject(makeRequestObj);
|
||||||
|
else resolve(makeRequestObj);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
//console.error(error, makeRequestObj);
|
||||||
|
makeRequestObj.error = error;
|
||||||
|
reject(makeRequestObj);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
export type EMail = string;
|
||||||
|
|
||||||
|
export type AccountName = string;
|
||||||
|
export type Username = string;
|
||||||
|
export type Password = string;
|
||||||
|
export type UserAgent = string;
|
||||||
|
export type XToken = string;
|
||||||
|
export type verifyId = string;
|
||||||
|
|
||||||
|
export type SessionId = string;
|
||||||
|
export type UserId = string;
|
||||||
|
export type WebSocketSessionId = string;
|
||||||
|
|
||||||
|
export const accountNameOptions = {
|
||||||
|
minLength: 4,
|
||||||
|
maxLength: 24,
|
||||||
|
isAllowed: (text: string): boolean => {
|
||||||
|
return text.match('^[a-zA-Z0-9_.]+$') !== null;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export const userNameOptions = {
|
||||||
|
minLength: 2,
|
||||||
|
maxLength: 24,
|
||||||
|
isAllowed: (text: string): boolean => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const passwordOptions = {
|
||||||
|
minLength: 6,
|
||||||
|
maxLength: 64,
|
||||||
|
isAllowed: (text: string): boolean => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const emailOptions = {
|
||||||
|
maxLength: 48,
|
||||||
|
isAllowed: (email: string) => {
|
||||||
|
return String(email).match(
|
||||||
|
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
import {getUserAgent} from 'react-native-user-agent';
|
||||||
|
|
||||||
|
export default getUserAgent;
|
|
@ -0,0 +1,2 @@
|
||||||
|
const getUserAgent = undefined;
|
||||||
|
export default getUserAgent;
|
|
@ -9,7 +9,56 @@ export default interface LangFormat {
|
||||||
details: LangDetails;
|
details: LangDetails;
|
||||||
curVersion: string;
|
curVersion: string;
|
||||||
appName: string;
|
appName: string;
|
||||||
|
appNameDesc: string;
|
||||||
startHelper1: string;
|
startHelper1: string;
|
||||||
|
navigation: {
|
||||||
|
home: {
|
||||||
|
account: string;
|
||||||
|
calendar: string;
|
||||||
|
chat: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
info: string;
|
||||||
|
error: string;
|
||||||
|
success: string;
|
||||||
|
account: {
|
||||||
|
registration: {
|
||||||
|
registration: string;
|
||||||
|
info: string;
|
||||||
|
privacyPolicy: string;
|
||||||
|
termsOfUse: string;
|
||||||
|
stepOne: {
|
||||||
|
title: string;
|
||||||
|
success: string;
|
||||||
|
addressExists: string;
|
||||||
|
addressInvalid: string;
|
||||||
|
noMailEntered: string;
|
||||||
|
button: string;
|
||||||
|
};
|
||||||
|
stepTwo: {
|
||||||
|
title: string;
|
||||||
|
verification: string;
|
||||||
|
resend: [string, string, string];
|
||||||
|
noCodeEntered: string;
|
||||||
|
resendError: {[key: number]: string};
|
||||||
|
verificationError: {[key: number]: string};
|
||||||
|
button: string;
|
||||||
|
success: string;
|
||||||
|
};
|
||||||
|
stepFinal: {
|
||||||
|
verification: string;
|
||||||
|
userName: string;
|
||||||
|
accountName: string;
|
||||||
|
password: string;
|
||||||
|
passwordRepeat: string;
|
||||||
|
displayName: string;
|
||||||
|
accountNameError: {[key: string]: string};
|
||||||
|
userNameError: {[key: string]: string};
|
||||||
|
passwordError: {[key: string]: string};
|
||||||
|
button: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LangPlaceholderKeys {
|
interface LangPlaceholderKeys {
|
||||||
|
|
|
@ -8,5 +8,85 @@ export const lang: LangFormat = {
|
||||||
},
|
},
|
||||||
curVersion: 'Your current version is v${version}.',
|
curVersion: 'Your current version is v${version}.',
|
||||||
appName: 'Click And Join',
|
appName: 'Click And Join',
|
||||||
|
appNameDesc: 'an app developed with love by Janex',
|
||||||
startHelper1: 'Your data will be loaded :)',
|
startHelper1: 'Your data will be loaded :)',
|
||||||
|
navigation: {
|
||||||
|
home: {
|
||||||
|
account: 'My account',
|
||||||
|
calendar: 'Calendar',
|
||||||
|
chat: 'Conversations',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
info: 'Info',
|
||||||
|
error: 'Error',
|
||||||
|
success: 'Success',
|
||||||
|
account: {
|
||||||
|
registration: {
|
||||||
|
registration: 'Registration',
|
||||||
|
info: 'By registering, you agree to our ${TermsOfUse}. You can find out how we collect and use your data in our ${privacyPolicy}.',
|
||||||
|
privacyPolicy: 'privacy policy',
|
||||||
|
termsOfUse: 'Terms of Use',
|
||||||
|
stepOne: {
|
||||||
|
title: 'Enter E-Mail',
|
||||||
|
success: 'A verification has sent to your E-Mail!',
|
||||||
|
addressExists: 'The E-Mail you entered is already in use.',
|
||||||
|
addressInvalid: 'The address you entered has an invalid format.',
|
||||||
|
noMailEntered: 'Please enter your E-Mail',
|
||||||
|
button: 'Next step',
|
||||||
|
},
|
||||||
|
stepTwo: {
|
||||||
|
title: 'Enter the 6-digit code that we sent you to ${EMail}.',
|
||||||
|
verification: 'X-X-X-X-X-X',
|
||||||
|
noCodeEntered: 'Please enter your code',
|
||||||
|
resend: [
|
||||||
|
'E-Mail not arrived? You can also resend the verification E-Mail by ${resend}.',
|
||||||
|
'clicking here',
|
||||||
|
'E-Mail verification has resent',
|
||||||
|
],
|
||||||
|
resendError: {
|
||||||
|
400: 'The E-Mail is already verified!',
|
||||||
|
401: 'Your device have changed. Please use another E-Mail address.',
|
||||||
|
429: 'Too many requests in a too small period of time in a row',
|
||||||
|
},
|
||||||
|
verificationError: {
|
||||||
|
400: 'Something went wrong please try again :( Restart App maybe required',
|
||||||
|
401: 'The code you entered does not match with the code we sent you',
|
||||||
|
422: 'The verification time is expired. Please please try again',
|
||||||
|
},
|
||||||
|
button: 'Verify',
|
||||||
|
success: 'Verification success!',
|
||||||
|
},
|
||||||
|
stepFinal: {
|
||||||
|
verification:
|
||||||
|
'Your Account has been verified. Now enter your user credentials.',
|
||||||
|
userName: 'Username',
|
||||||
|
accountName: 'AccountName',
|
||||||
|
password: 'Password',
|
||||||
|
passwordRepeat: 'Repeat password',
|
||||||
|
displayName: 'Other users see you like this:',
|
||||||
|
accountNameError: {
|
||||||
|
tooLong: 'Too long. Max length are $(maxLength) character.',
|
||||||
|
tooShort: 'Too short. Min length are $(minLength) character.',
|
||||||
|
required: 'This field is required',
|
||||||
|
invalid:
|
||||||
|
'Account names can only contain letters, numbers, underscores (_) and dots (.)',
|
||||||
|
exists: 'The account name you entered already exists.',
|
||||||
|
},
|
||||||
|
userNameError: {
|
||||||
|
tooLong: 'Too long. Max length are $(maxLength) character.',
|
||||||
|
tooShort: 'Too short. Min length are $(minLength) character.',
|
||||||
|
required: 'This field is required',
|
||||||
|
},
|
||||||
|
passwordError: {
|
||||||
|
noMatch: 'Passwords do not match',
|
||||||
|
tooLong: 'Too long. Max length are $(maxLength) character.',
|
||||||
|
tooShort: 'Too short. Min length are $(minLength) character.',
|
||||||
|
required: 'This field is required',
|
||||||
|
weak: 'Password is too weak',
|
||||||
|
},
|
||||||
|
|
||||||
|
button: 'Finish registration',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
import AccountInfoBanner from '@caj/components/AccountInfoBanner';
|
||||||
|
import NotLoggedIn from '@caj/components/NotLoggedIn';
|
||||||
|
import {ThemeMode} from '@caj/configs/appVar';
|
||||||
|
import {defaultHeaderStyle} from '@caj/configs/colors';
|
||||||
|
import {RootStackNavigatorParamList} from '@caj/Navigation';
|
||||||
|
import {RootState} from '@caj/redux/store';
|
||||||
|
import {
|
||||||
|
createNativeStackNavigator,
|
||||||
|
NativeStackNavigationProp,
|
||||||
|
} from '@react-navigation/native-stack';
|
||||||
|
import {Box, Center, Container, Text} from 'native-base';
|
||||||
|
import {useSelector} from 'react-redux';
|
||||||
|
|
||||||
|
export const AccountTabName = 'Account';
|
||||||
|
|
||||||
|
export type AccountStackNavigatorParamList = {
|
||||||
|
Overview: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AccountStack =
|
||||||
|
createNativeStackNavigator<AccountStackNavigatorParamList>();
|
||||||
|
|
||||||
|
export type AccountScreenNavigationProp =
|
||||||
|
NativeStackNavigationProp<AccountStackNavigatorParamList>;
|
||||||
|
|
||||||
|
function AccountTab() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const theme = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.theme,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AccountStack.Navigator>
|
||||||
|
<AccountStack.Screen
|
||||||
|
name="Overview"
|
||||||
|
options={{
|
||||||
|
animation: 'slide_from_left',
|
||||||
|
title: lang.navigation.home.account,
|
||||||
|
headerShown: true,
|
||||||
|
...defaultHeaderStyle(theme),
|
||||||
|
}}
|
||||||
|
component={AccountScreen}
|
||||||
|
/>
|
||||||
|
</AccountStack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AccountScreen() {
|
||||||
|
const theme = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.theme,
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
bg="blackBG.400"
|
||||||
|
{...(theme === ThemeMode.Darkest
|
||||||
|
? {borderBottomWidth: 1, borderColor: 'white.900'}
|
||||||
|
: {})}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
paddingVertical: 20,
|
||||||
|
borderBottomLeftRadius: 20,
|
||||||
|
}}>
|
||||||
|
<AccountInfoBanner />
|
||||||
|
</Box>
|
||||||
|
<NotLoggedIn />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AccountTab;
|
|
@ -0,0 +1,53 @@
|
||||||
|
import NotLoggedIn from '@caj/components/NotLoggedIn';
|
||||||
|
import {defaultHeaderStyle} from '@caj/configs/colors';
|
||||||
|
import {RootStackNavigatorParamList} from '@caj/Navigation';
|
||||||
|
import {RootState} from '@caj/redux/store';
|
||||||
|
import {
|
||||||
|
createNativeStackNavigator,
|
||||||
|
NativeStackNavigationProp,
|
||||||
|
} from '@react-navigation/native-stack';
|
||||||
|
import {Center, Text} from 'native-base';
|
||||||
|
import {useSelector} from 'react-redux';
|
||||||
|
|
||||||
|
export const CalendarTabName = 'Calendar';
|
||||||
|
|
||||||
|
export type CalendarStackNavigatorParamList = {
|
||||||
|
Overview: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CalendarStack =
|
||||||
|
createNativeStackNavigator<CalendarStackNavigatorParamList>();
|
||||||
|
|
||||||
|
export type CalendarScreenNavigationProp =
|
||||||
|
NativeStackNavigationProp<CalendarStackNavigatorParamList>;
|
||||||
|
|
||||||
|
function CalendarTab() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const theme = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.theme,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CalendarStack.Navigator>
|
||||||
|
<CalendarStack.Screen
|
||||||
|
name="Overview"
|
||||||
|
options={{
|
||||||
|
title: lang.navigation.home.calendar,
|
||||||
|
headerShown: true,
|
||||||
|
...defaultHeaderStyle(theme),
|
||||||
|
}}
|
||||||
|
component={CalendarScreen}
|
||||||
|
/>
|
||||||
|
</CalendarStack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CalendarScreen() {
|
||||||
|
return (
|
||||||
|
<Center>
|
||||||
|
<NotLoggedIn />
|
||||||
|
</Center>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CalendarTab;
|
|
@ -0,0 +1,52 @@
|
||||||
|
import NotLoggedIn from '@caj/components/NotLoggedIn';
|
||||||
|
import {defaultHeaderStyle} from '@caj/configs/colors';
|
||||||
|
import {RootStackNavigatorParamList} from '@caj/Navigation';
|
||||||
|
import {RootState} from '@caj/redux/store';
|
||||||
|
import {
|
||||||
|
createNativeStackNavigator,
|
||||||
|
NativeStackNavigationProp,
|
||||||
|
} from '@react-navigation/native-stack';
|
||||||
|
import {Center, Text} from 'native-base';
|
||||||
|
import {useSelector} from 'react-redux';
|
||||||
|
|
||||||
|
export const ChatTabName = 'Chat';
|
||||||
|
|
||||||
|
export type ChatStackNavigatorParamList = {
|
||||||
|
Overview: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ChatStack = createNativeStackNavigator<ChatStackNavigatorParamList>();
|
||||||
|
|
||||||
|
export type ChatScreenNavigationProp =
|
||||||
|
NativeStackNavigationProp<ChatStackNavigatorParamList>;
|
||||||
|
|
||||||
|
function ChatTab() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const theme = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.theme,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ChatStack.Navigator>
|
||||||
|
<ChatStack.Screen
|
||||||
|
name="Overview"
|
||||||
|
options={{
|
||||||
|
title: lang.navigation.home.chat,
|
||||||
|
headerShown: true,
|
||||||
|
...defaultHeaderStyle(theme),
|
||||||
|
}}
|
||||||
|
component={ChatScreen}
|
||||||
|
/>
|
||||||
|
</ChatStack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ChatScreen() {
|
||||||
|
return (
|
||||||
|
<Center>
|
||||||
|
<NotLoggedIn />
|
||||||
|
</Center>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ChatTab;
|
|
@ -0,0 +1,47 @@
|
||||||
|
import {defaultHeaderStyle} from '@caj/configs/colors';
|
||||||
|
import {RootStackNavigatorParamList} from '@caj/Navigation';
|
||||||
|
import {RootState} from '@caj/redux/store';
|
||||||
|
import {
|
||||||
|
createNativeStackNavigator,
|
||||||
|
NativeStackNavigationProp,
|
||||||
|
} from '@react-navigation/native-stack';
|
||||||
|
import {Center, Text} from 'native-base';
|
||||||
|
import {useSelector} from 'react-redux';
|
||||||
|
|
||||||
|
export const MapsTabName = 'Maps';
|
||||||
|
|
||||||
|
export type MapsStackNavigatorParamList = {
|
||||||
|
Overview: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MapsStack = createNativeStackNavigator<MapsStackNavigatorParamList>();
|
||||||
|
|
||||||
|
export type MapsScreenNavigationProp =
|
||||||
|
NativeStackNavigationProp<MapsStackNavigatorParamList>;
|
||||||
|
|
||||||
|
function MapsTab() {
|
||||||
|
const lang = useSelector((state: RootState) => state.appVariables.lang);
|
||||||
|
const theme = useSelector(
|
||||||
|
(state: RootState) => state.appVariables.preferences.theme,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MapsStack.Navigator>
|
||||||
|
<MapsStack.Screen
|
||||||
|
name="Overview"
|
||||||
|
options={{
|
||||||
|
title: 'Maps',
|
||||||
|
headerShown: true,
|
||||||
|
...defaultHeaderStyle(theme),
|
||||||
|
}}
|
||||||
|
component={MapsScreen}
|
||||||
|
/>
|
||||||
|
</MapsStack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function MapsScreen() {
|
||||||
|
return <Center>MapsScreen</Center>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MapsTab;
|
|
@ -12,52 +12,6 @@
|
||||||
--doc--height: 100%;
|
--doc--height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-Thin';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-ExtraLight';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 200;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-Light';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-Regular';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-Medium';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-SemiBold';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-Bold';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-ExtraBold';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Outfit-Black';
|
|
||||||
src: url('/fonts/Outfit.ttf');
|
|
||||||
font-weight: 900;
|
|
||||||
}
|
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
@ -11,13 +11,14 @@ const appDirectory = path.resolve(__dirname, '../');
|
||||||
// errors. To fix this webpack can be configured to compile to the necessary
|
// errors. To fix this webpack can be configured to compile to the necessary
|
||||||
// `node_module`.
|
// `node_module`.
|
||||||
const babelLoaderConfiguration = {
|
const babelLoaderConfiguration = {
|
||||||
test: /\.(ts|tsx|js)?$/,
|
test: /\.(ts|tsx|js|jsx)?$/,
|
||||||
// Add every directory that needs to be compiled by Babel during the build.
|
// Add every directory that needs to be compiled by Babel during the build.
|
||||||
include: [
|
include: [
|
||||||
path.resolve(appDirectory, 'index.web.tsx'),
|
path.resolve(appDirectory, 'index.web.tsx'),
|
||||||
path.resolve(appDirectory, 'src'),
|
path.resolve(appDirectory, 'src'),
|
||||||
|
/node_modules\/react-native-/,
|
||||||
],
|
],
|
||||||
exclude: [path.resolve(appDirectory, 'node_modules')],
|
// exclude: [path.resolve(appDirectory, 'node_modules')],
|
||||||
use: {
|
use: {
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
options: {
|
options: {
|
||||||
|
@ -25,14 +26,20 @@ const babelLoaderConfiguration = {
|
||||||
// The 'react-native' preset is recommended to match React Native's packager
|
// The 'react-native' preset is recommended to match React Native's packager
|
||||||
// presets: ['module:metro-react-native-babel-preset'],
|
// presets: ['module:metro-react-native-babel-preset'],
|
||||||
// presets: ['react-native'],
|
// presets: ['react-native'],
|
||||||
presets: [require.resolve('babel-preset-react-native')],
|
|
||||||
// Re-write paths to import only the modules needed by the app
|
|
||||||
plugins: ['react-native-web'],
|
|
||||||
presets: ['react-native'],
|
|
||||||
presets: ['module:metro-react-native-babel-preset'],
|
presets: ['module:metro-react-native-babel-preset'],
|
||||||
plugins: [
|
plugins: [
|
||||||
// needed to support async/await
|
// needed to support async/await
|
||||||
'@babel/plugin-transform-runtime',
|
// '@babel/plugin-transform-runtime',
|
||||||
|
'react-native-web',
|
||||||
|
[
|
||||||
|
'module-resolver',
|
||||||
|
{
|
||||||
|
alias: {
|
||||||
|
'^react-native$': 'react-native-web',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -49,9 +56,26 @@ const imageLoaderConfiguration = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ttfLoaderConfiguration = {
|
||||||
|
test: /\.ttf$/,
|
||||||
|
loader: 'url-loader', // or directly file-loader
|
||||||
|
include: [
|
||||||
|
path.resolve(appDirectory, 'node_modules/react-native-vector-icons'),
|
||||||
|
path.resolve(appDirectory, 'web/public/fonts'),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
target: 'web',
|
target: 'web',
|
||||||
|
devServer: {
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
||||||
|
'Access-Control-Allow-Headers':
|
||||||
|
'X-Requested-With, content-type, Authorization',
|
||||||
|
},
|
||||||
|
},
|
||||||
entry: [
|
entry: [
|
||||||
// load any web API polyfills
|
// load any web API polyfills
|
||||||
// path.resolve(appDirectory, 'polyfills-web.js'),
|
// path.resolve(appDirectory, 'polyfills-web.js'),
|
||||||
|
@ -68,7 +92,11 @@ module.exports = {
|
||||||
// ...the rest of your config
|
// ...the rest of your config
|
||||||
|
|
||||||
module: {
|
module: {
|
||||||
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
|
rules: [
|
||||||
|
babelLoaderConfiguration,
|
||||||
|
imageLoaderConfiguration,
|
||||||
|
ttfLoaderConfiguration,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
|
@ -80,6 +108,15 @@ module.exports = {
|
||||||
// If you're working on a multi-platform React Native app, web-specific
|
// If you're working on a multi-platform React Native app, web-specific
|
||||||
// module implementations should be written in files using the extension
|
// module implementations should be written in files using the extension
|
||||||
// `.web.js`.
|
// `.web.js`.
|
||||||
extensions: ['.web.js', '.js', '.web.ts', '.ts', '.web.tsx', '.tsx'],
|
extensions: [
|
||||||
|
'.web.js',
|
||||||
|
'.web.jsx',
|
||||||
|
'.js',
|
||||||
|
'.jsx',
|
||||||
|
'.web.ts',
|
||||||
|
'.ts',
|
||||||
|
'.web.tsx',
|
||||||
|
'.tsx',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue