diff --git a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/banner.png b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/banner.png
index 040e8470df..a25baf863a 100644
Binary files a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/banner.png and b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/banner.png differ
diff --git a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/boat-trip.jpg b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/boat-trip.jpg
index e8b25c8391..7a9b89732a 100644
Binary files a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/boat-trip.jpg and b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/boat-trip.jpg differ
diff --git a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/collage-moscow.jpg b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/collage-moscow.jpg
index 1acfee01a3..69652780b7 100644
Binary files a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/collage-moscow.jpg and b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/collage-moscow.jpg differ
diff --git a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/general-collage.jpg b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/general-collage.jpg
index 9310e1312f..459f151e25 100644
Binary files a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/general-collage.jpg and b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/general-collage.jpg differ
diff --git a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/halil-talk.jpg b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/halil-talk.jpg
index 9f0e62bf77..8d2a116524 100644
Binary files a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/halil-talk.jpg and b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/halil-talk.jpg differ
diff --git a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk-2.png b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk-2.png
index b2a0ae3581..34acae63da 100644
Binary files a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk-2.png and b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk-2.png differ
diff --git a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk-pro-pictures.jpg b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk-pro-pictures.jpg
index 20f411243b..8cd11d2d11 100644
Binary files a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk-pro-pictures.jpg and b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk-pro-pictures.jpg differ
diff --git a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk.png b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk.png
index 1206f5144c..caa9194c3f 100644
Binary files a/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk.png and b/docs/en/Blog-Posts/2024-09-17-My-Impressions-at-DotNext-2024-Conference/my-talk.png differ
diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md
index ba3e6aabf8..3fd8eee2f4 100644
--- a/docs/en/cli/index.md
+++ b/docs/en/cli/index.md
@@ -152,7 +152,7 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `--tiered`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side. (*Available for* ***Team*** *or higher licenses*)
* `--mobile` or `-m`: Specifies the mobile application framework. Default value is `none`. Available frameworks:
* `none`: Without any mobile application.
- * `react-native`: React Native.
+ * `react-native`: React Native. This mobile option is only available for active **license owners**.
* `maui`: MAUI. This mobile option is only available for ABP. (*Available for* ***Team*** *or higher licenses*)
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
diff --git a/docs/en/cli/new-command-samples.md b/docs/en/cli/new-command-samples.md
index 06099a3e29..6b168b538c 100644
--- a/docs/en/cli/new-command-samples.md
+++ b/docs/en/cli/new-command-samples.md
@@ -1,6 +1,6 @@
# ABP CLI - New Solution Sample Commands
-The `abp new` command creates an ABP solution or other artifacts based on an ABP template. [ABP CLI](../cli/index.md) has several parameters to create a new ABP solution. In this document we will show you some sample commands to create a new solution. All the project names are `Acme.BookStore`. Currently, the available mobile projects are `React Native` and `MAUI` mobile app. Available database providers are `Entity Framework Core` and `MongoDB`. All the commands starts with `abp new`.
+The `abp new` command creates an ABP solution or other artifacts based on an ABP template. [ABP CLI](../cli/index.md) has several parameters to create a new ABP solution. In this document we will show you some sample commands to create a new solution. All the project names are `Acme.BookStore`. Currently, the available mobile projects are `React Native` and `MAUI` mobile app (they are *available for* ***Team*** *or higher licenses*). Available database providers are `Entity Framework Core` and `MongoDB`. All the commands starts with `abp new`.
## Angular
diff --git a/docs/en/framework/ui/angular/images/fullscreen-true.png b/docs/en/framework/ui/angular/images/fullscreen-true.png
index 841946176a..d14bc774d6 100644
Binary files a/docs/en/framework/ui/angular/images/fullscreen-true.png and b/docs/en/framework/ui/angular/images/fullscreen-true.png differ
diff --git a/docs/en/framework/ui/react-native/index.md b/docs/en/framework/ui/react-native/index.md
index f79d5bb3d1..3dd60b6348 100644
--- a/docs/en/framework/ui/react-native/index.md
+++ b/docs/en/framework/ui/react-native/index.md
@@ -7,6 +7,8 @@
# Getting Started with the React Native
+> React Native mobile option is *available for* ***Team*** *or higher licenses*
+
ABP platform provide basic [React Native](https://reactnative.dev/) startup template to develop mobile applications **integrated to your ABP based backends**.

diff --git a/docs/en/solution-templates/layered-web-application/index.md b/docs/en/solution-templates/layered-web-application/index.md
index fa0b565888..d6d78864e8 100644
--- a/docs/en/solution-templates/layered-web-application/index.md
+++ b/docs/en/solution-templates/layered-web-application/index.md
@@ -60,7 +60,7 @@ abp new Acme.BookStore -d mongodb
This template supports the following mobile application frameworks:
-- `react-native`: React Native
+- `react-native`: React Native (*Available for* ***Team*** *or higher licenses*)
Use the `-m` (or `--mobile`) option to specify the mobile application framework:
diff --git a/docs/en/tutorials/mobile/react-native/index.md b/docs/en/tutorials/mobile/react-native/index.md
index 3178574627..359cdc510d 100644
--- a/docs/en/tutorials/mobile/react-native/index.md
+++ b/docs/en/tutorials/mobile/react-native/index.md
@@ -1,5 +1,7 @@
# Mobile Application Development Tutorial - React Native
+React Native mobile option is *available for* ***Team*** *or higher licenses*. Therefore, if you don't have a commercial license, it's suggested to follow the article by downloading the source code of the sample application as described in the next chapter.
+
## About This Tutorial
- This tutorial assumes that you have completed the [Web Application Development tutorial](../../book-store/part-01.md) and built an ABP based application named `Acme.BookStore` with [React Native](../../../framework/ui/react-native) as the mobile option.. Therefore, if you haven't completed the [Web Application Development tutorial](../../book-store/part-01.md), you either need to complete it or download the source code from down below and follow this tutorial.
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
index 5d228cc176..c014f52d0e 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
@@ -220,6 +220,7 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien
sb.AppendLine(" abp new Acme.BookStore -u angular -d mongodb");
sb.AppendLine(" abp new Acme.BookStore -m none");
sb.AppendLine(" abp new Acme.BookStore -m react-native");
+ sb.AppendLine(" abp new Acme.BookStore -m maui");
sb.AppendLine(" abp new Acme.BookStore -d mongodb");
sb.AppendLine(" abp new Acme.BookStore -d mongodb -o d:\\my-project");
sb.AppendLine(" abp new Acme.BookStore -t module");
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs
index d1e54868c4..6b607d4454 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs
@@ -137,7 +137,7 @@ public abstract class ProjectCreationCommandBase
Logger.LogInformation("Public Web Site: yes");
}
- var mobileApp = GetMobilePreference(commandLineArgs);
+ var mobileApp = GetMobilePreference(commandLineArgs, template);
if (mobileApp != MobileApp.None)
{
Logger.LogInformation("Mobile App: " + mobileApp);
@@ -635,7 +635,7 @@ public abstract class ProjectCreationCommandBase
}
}
- protected virtual MobileApp GetMobilePreference(CommandLineArgs commandLineArgs)
+ protected virtual MobileApp GetMobilePreference(CommandLineArgs commandLineArgs, string template)
{
var optionValue = commandLineArgs.Options.GetOrNull(Options.Mobile.Short, Options.Mobile.Long);
@@ -644,9 +644,9 @@ public abstract class ProjectCreationCommandBase
case null:
case "none":
return MobileApp.None;
- case "react-native":
+ case "react-native" when template is AppProTemplate.TemplateName or MicroserviceProTemplate.TemplateName:
return MobileApp.ReactNative;
- case "maui":
+ case "maui" when template is AppProTemplate.TemplateName or MicroserviceProTemplate.TemplateName:
return MobileApp.Maui;
default:
throw new CliUsageException(ExceptionMessageHelper.GetInvalidOptionExceptionMessage("Mobile App"));
diff --git a/templates/app/react-native/.eslintrc.json b/templates/app/react-native/.eslintrc.json
deleted file mode 100644
index 6702dcefd6..0000000000
--- a/templates/app/react-native/.eslintrc.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "extends": ["airbnb", "prettier", "prettier/react"],
- "parser": "babel-eslint",
- "env": {
- "jest": true
- },
- "rules": {
- "no-use-before-define": 0,
- "react/jsx-filename-extension": 0,
- "react/prop-types": ["error", { "ignore": ["navigation", "children"] }],
- "react/require-default-props": 0,
- "react/jsx-props-no-spreading": 0,
- "react/forbid-prop-types": 0,
- "import/prefer-default-export": 0,
- "comma-dangle": 0,
- "no-underscore-dangle": 1,
- "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
- "no-param-reassign": 0,
- "operator-linebreak": 0,
- "global-require": 0
- },
- "globals": {
- "fetch": false
- }
-}
diff --git a/templates/app/react-native/.expo-shared/assets.json b/templates/app/react-native/.expo-shared/assets.json
deleted file mode 100644
index 1e6decfbb5..0000000000
--- a/templates/app/react-native/.expo-shared/assets.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
- "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
-}
diff --git a/templates/app/react-native/.gitignore b/templates/app/react-native/.gitignore
deleted file mode 100644
index ec8a36a257..0000000000
--- a/templates/app/react-native/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-node_modules/
-.expo/
-dist/
-npm-debug.*
-*.jks
-*.p8
-*.p12
-*.key
-*.mobileprovision
-*.orig.*
-web-build/
-
-# macOS
-.DS_Store
diff --git a/templates/app/react-native/.prettierrc b/templates/app/react-native/.prettierrc
deleted file mode 100644
index 471fac2824..0000000000
--- a/templates/app/react-native/.prettierrc
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "trailingComma": "all",
- "singleQuote": true,
- "jsxSingleQuote": false,
- "printWidth": 80,
- "semi": true,
- "jsxBracketSameLine": true,
- "arrowParens": "avoid"
-}
diff --git a/templates/app/react-native/.vscode/extensions.json b/templates/app/react-native/.vscode/extensions.json
deleted file mode 100644
index d7df89c9cd..0000000000
--- a/templates/app/react-native/.vscode/extensions.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
-}
diff --git a/templates/app/react-native/App.js b/templates/app/react-native/App.js
deleted file mode 100644
index 6505569f2b..0000000000
--- a/templates/app/react-native/App.js
+++ /dev/null
@@ -1,101 +0,0 @@
-import { NavigationContainer } from '@react-navigation/native';
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import i18n from 'i18n-js';
-import { NativeBaseProvider } from 'native-base';
-import React, { useEffect, useMemo, useState } from 'react';
-import { enableScreens } from 'react-native-screens';
-import { Provider } from 'react-redux';
-import { PersistGate } from 'redux-persist/integration/react';
-import { getEnvVars } from './Environment';
-import Loading from './src/components/Loading/Loading';
-import { LocalizationContext } from './src/contexts/LocalizationContext';
-import { initAPIInterceptor } from './src/interceptors/APIInterceptor';
-import AuthNavigator from './src/navigators/AuthNavigator';
-import DrawerNavigator from './src/navigators/DrawerNavigator';
-import { persistor, store } from './src/store';
-import AppActions from './src/store/actions/AppActions';
-import PersistentStorageActions from './src/store/actions/PersistentStorageActions';
-import { createLanguageSelector } from './src/store/selectors/AppSelectors';
-import { createTokenSelector } from './src/store/selectors/PersistentStorageSelectors';
-import { connectToRedux } from './src/utils/ReduxConnect';
-import { isTokenValid } from './src/utils/TokenUtils';
-
-const Stack = createNativeStackNavigator();
-
-const { localization } = getEnvVars();
-
-i18n.defaultSeparator = '::';
-
-const cloneT = i18n.t;
-i18n.t = (key, ...args) => {
- if (key.slice(0, 2) === '::') {
- key = localization.defaultResourceName + key;
- }
- return cloneT(key, ...args);
-};
-
-enableScreens();
-initAPIInterceptor(store);
-
-export default function App() {
- const language = createLanguageSelector()(store.getState());
- const [isReady, setIsReady] = useState(false);
-
- const localizationContextValue = useMemo(
- () => ({
- t: i18n.t,
- locale: (language || {}).cultureName,
- }),
- [language]
- );
-
- useEffect(() => {
- store.dispatch(
- AppActions.fetchAppConfigAsync({
- callback: () => setIsReady(true),
- showLoading: true,
- })
- );
- }, []);
-
- return (
-
-
-
-
- {isReady ? (
-
-
-
- ) : null}
-
-
-
-
-
- );
-}
-
-function AppContainer({token, setToken}) {
- const isValid = useMemo(() => isTokenValid(token), [token]);
-
- useEffect(() => {
- if (!isValid && token && token.access_token) {
- setToken({})
- }
- }, [isValid]);
-
-
- return isValid ? :
-}
-
-
-const ConnectedAppContainer = connectToRedux({
- component: AppContainer,
- stateProps: (state) => ({
- token: createTokenSelector()(state),
- }),
- dispatchProps: {
- setToken: PersistentStorageActions.setToken,
- },
-});
diff --git a/templates/app/react-native/Environment.js b/templates/app/react-native/Environment.js
deleted file mode 100644
index a4a23995f7..0000000000
--- a/templates/app/react-native/Environment.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const yourIP = 'localhost'; // See the docs https://docs.abp.io/en/abp/latest/Getting-Started-React-Native?Tiered=No
-const port = 44305;
-const apiUrl = `http://${yourIP}:${port}`;
-const ENV = {
- dev: {
- apiUrl: apiUrl,
- oAuthConfig: {
- issuer: apiUrl,
- clientId: 'MyProjectName_App',
- scope: 'offline_access MyProjectName',
- },
- localization: {
- defaultResourceName: 'MyProjectName',
- },
- },
- prod: {
- apiUrl: 'http://localhost:44305',
- oAuthConfig: {
- issuer: 'http://localhost:44305',
- clientId: 'MyProjectName_App',
- scope: 'offline_access MyProjectName',
- },
- localization: {
- defaultResourceName: 'MyProjectName',
- },
- },
-};
-
-export const getEnvVars = () => {
- // eslint-disable-next-line no-undef
- return __DEV__ ? ENV.dev : ENV.prod;
-};
diff --git a/templates/app/react-native/app.json b/templates/app/react-native/app.json
deleted file mode 100644
index 5b78afa519..0000000000
--- a/templates/app/react-native/app.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "expo": {
- "name": "MyProjectName",
- "slug": "MyProjectName",
- "version": "1.0.0",
- "orientation": "portrait",
- "icon": "./assets/icon.png",
- "splash": {
- "image": "./assets/splash.png",
- "resizeMode": "cover",
- "backgroundColor": "#38003c"
- },
- "updates": {
- "fallbackToCacheTimeout": 0
- },
- "assetBundlePatterns": ["**/*"],
- "ios": {
- "supportsTablet": true,
- "bundleIdentifier": "com.MyCompanyName.MyProjectName",
- "buildNumber": "1.0.0"
- },
- "android": {
- "package": "com.MyCompanyName.MyProjectName",
- "versionCode": 1,
- "adaptiveIcon": {
- "foregroundImage": "./assets/adaptive-icon.png",
- "backgroundColor": "#FFFFFF"
- }
- },
- "web": {
- "favicon": "./assets/icon.png"
- }
- }
-}
diff --git a/templates/app/react-native/assets/adaptive-icon.png b/templates/app/react-native/assets/adaptive-icon.png
deleted file mode 100644
index 03d6f6b6c6..0000000000
Binary files a/templates/app/react-native/assets/adaptive-icon.png and /dev/null differ
diff --git a/templates/app/react-native/assets/avatar.png b/templates/app/react-native/assets/avatar.png
deleted file mode 100644
index 8a1daa0121..0000000000
Binary files a/templates/app/react-native/assets/avatar.png and /dev/null differ
diff --git a/templates/app/react-native/assets/icon.png b/templates/app/react-native/assets/icon.png
deleted file mode 100644
index 528c8711d7..0000000000
Binary files a/templates/app/react-native/assets/icon.png and /dev/null differ
diff --git a/templates/app/react-native/assets/logo.png b/templates/app/react-native/assets/logo.png
deleted file mode 100644
index b9b1e36c50..0000000000
Binary files a/templates/app/react-native/assets/logo.png and /dev/null differ
diff --git a/templates/app/react-native/assets/splash.png b/templates/app/react-native/assets/splash.png
deleted file mode 100644
index 0d5f0ec026..0000000000
Binary files a/templates/app/react-native/assets/splash.png and /dev/null differ
diff --git a/templates/app/react-native/babel.config.js b/templates/app/react-native/babel.config.js
deleted file mode 100644
index d715221e05..0000000000
--- a/templates/app/react-native/babel.config.js
+++ /dev/null
@@ -1,7 +0,0 @@
-module.exports = function(api) {
- api.cache(true);
- return {
- presets: ['babel-preset-expo'],
- plugins: ['react-native-reanimated/plugin'],
- };
-};
\ No newline at end of file
diff --git a/templates/app/react-native/package.json b/templates/app/react-native/package.json
deleted file mode 100644
index 9fbe23ea4b..0000000000
--- a/templates/app/react-native/package.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "name": "myprojectname",
- "version": "1.0.0",
- "main": "node_modules/expo/AppEntry.js",
- "scripts": {
- "start": "expo start --port 19000",
- "android": "expo start --android",
- "ios": "expo start --ios",
- "web": "expo start --web",
- "eject": "expo eject"
- },
- "dependencies": {
- "@react-native-async-storage/async-storage": "1.18.2",
- "@react-navigation/drawer": "^6.5.4",
- "@react-navigation/native": "^6.1.0",
- "@react-navigation/native-stack": "^6.9.5",
- "@reduxjs/toolkit": "^1.7.1",
- "axios": "~1.2.1",
- "expo": "^49.0.0",
- "expo-status-bar": "~1.6.0",
- "formik": "^2.2.9",
- "i18n-js": "^3.8.0",
- "native-base": "^3.4.25",
- "prop-types": "^15.8.1",
- "react": "18.2.0",
- "react-dom": "18.2.0",
- "react-native": "0.72.10",
- "react-native-chart-kit": "^6.11.0",
- "react-native-gesture-handler": "~2.12.0",
- "react-native-reanimated": "~3.3.0",
- "react-native-safe-area-context": "4.6.3",
- "react-native-screens": "~3.22.0",
- "react-native-svg": "13.9.0",
- "react-native-web": "~0.19.6",
- "react-redux": "^8.0.5",
- "redux-persist": "^6.0.0",
- "redux-saga": "^1.2.1",
- "yup": "^0.32.11"
- },
- "devDependencies": {
- "@babel/core": "^7.19.3"
- },
- "private": true
-}
diff --git a/templates/app/react-native/src/api/API.js b/templates/app/react-native/src/api/API.js
deleted file mode 100644
index dc604f62e9..0000000000
--- a/templates/app/react-native/src/api/API.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import axios from 'axios';
-import { getEnvVars } from '../../Environment';
-
-const { apiUrl } = getEnvVars();
-
-const axiosInstance = axios.create({
- baseURL: apiUrl,
- withCredentials: false
-});
-
-export default axiosInstance;
diff --git a/templates/app/react-native/src/api/AccountAPI.js b/templates/app/react-native/src/api/AccountAPI.js
deleted file mode 100644
index ddf49579d3..0000000000
--- a/templates/app/react-native/src/api/AccountAPI.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import api from './API';
-import { getEnvVars } from '../../Environment';
-
-const { oAuthConfig } = getEnvVars();
-
-getLoginData = (username, password) => {
- const formData = {
- grant_type: 'password',
- scope: oAuthConfig.scope,
- username: username,
- password: password,
- client_id: oAuthConfig.clientId,
- };
-
- if (oAuthConfig.clientSecret)
- formData['client_secret'] = oAuthConfig.clientSecret;
-
- return Object.entries(formData)
- .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
- .join('&');
-};
-
-export const login = ({ username, password }) =>
- api({
- method: 'POST',
- url: '/connect/token',
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
- data: getLoginData(username, password),
- baseURL: oAuthConfig.issuer,
- }).then(({ data }) => data);
-
-export const Logout = (
- input = { client_id: '', token: '', token_type_hint: '' },
-) => {
- if (!input.token_type_hint) {
- input.token_type_hint = 'access_token';
- }
-
- const _data = Object.entries(input)
- .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
- .join('&');
-
- return api({
- method: 'POST',
- url: '/connect/revocat',
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
- data: _data,
- baseURL: oAuthConfig.issuer,
- }).then(({ data }) => data);
-};
-
-export const getTenant = tenantName =>
- api({
- method: 'GET',
- url: `/api/abp/multi-tenancy/tenants/by-name/${tenantName}`,
- }).then(({ data }) => data);
-
-export const getTenantById = tenantId =>
- api({
- method: 'GET',
- url: `/api/abp/multi-tenancy/tenants/by-id/${tenantId}`,
- }).then(({ data }) => data);
diff --git a/templates/app/react-native/src/api/ApplicationConfigurationAPI.js b/templates/app/react-native/src/api/ApplicationConfigurationAPI.js
deleted file mode 100644
index 96fcbea5cd..0000000000
--- a/templates/app/react-native/src/api/ApplicationConfigurationAPI.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import i18n from 'i18n-js';
-import api from './API';
-
-export const getApplicationConfiguration = () =>
- api
- .get('/api/abp/application-configuration')
- .then(({ data }) => data)
- .then(async config => {
- const { cultureName } = config.localization.currentCulture;
- i18n.locale = cultureName;
-
- Object.keys(config.localization.values).forEach(key => {
- const resource = config.localization.values[key];
-
- if (typeof resource !== 'object') return;
-
- Object.keys(resource).forEach(key2 => {
- if (/'{|{/g.test(resource[key2])) {
- resource[key2] = resource[key2].replace(/'{|{/g, '{{').replace(/}'|}/g, '}}');
- }
- });
- });
-
- i18n.translations[cultureName] = {
- ...config.localization.values,
- ...(i18n.translations[cultureName] || {}),
- };
-
- return config;
- });
diff --git a/templates/app/react-native/src/api/IdentityAPI.js b/templates/app/react-native/src/api/IdentityAPI.js
deleted file mode 100644
index 9ae81ad2b5..0000000000
--- a/templates/app/react-native/src/api/IdentityAPI.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import api from './API';
-
-
-export const getAllRoles = () => api.get('/api/identity/roles/all').then(({ data }) => data.items);
-
-export const getUserRoles = id =>
- api.get(`/api/identity/users/${id}/roles`).then(({ data }) => data.items);
-
-export const getUsers = (params = { maxResultCount: 10, skipCount: 0 }) =>
- api.get('/api/identity/users', { params }).then(({ data }) => data);
-
-export const getUserById = id => api.get(`/api/identity/users/${id}`).then(({ data }) => data);
-
-export const createUser = body => api.post('/api/identity/users', body).then(({ data }) => data);
-
-export const updateUser = (body, id) =>
- api.put(`/api/identity/users/${id}`, body).then(({ data }) => data);
-
-export const removeUser = id => api.delete(`/api/identity/users/${id}`);
-
-export const getProfileDetail = () => api.get('/api/account/my-profile').then(({ data }) => data);
-
-export const updateProfileDetail = body =>
- api.put('/api/account/my-profile', body).then(({ data }) => data);
-
-export const changePassword = body =>
- api.post('/api/account/my-profile/change-password', body).then(({ data }) => data);
diff --git a/templates/app/react-native/src/api/TenantManagementAPI.js b/templates/app/react-native/src/api/TenantManagementAPI.js
deleted file mode 100644
index f60ed96450..0000000000
--- a/templates/app/react-native/src/api/TenantManagementAPI.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import api from './API';
-
-export function getTenants(params = {}) {
- return api.get('/api/multi-tenancy/tenants', { params }).then(({ data }) => data);
-}
-
-export function createTenant(body) {
- return api.post('/api/multi-tenancy/tenants', body).then(({ data }) => data);
-}
-
-export function getTenantById(id) {
- return api.get(`/api/multi-tenancy/tenants/${id}`).then(({ data }) => data);
-}
-
-export function updateTenant(body, id) {
- return api.put(`/api/multi-tenancy/tenants/${id}`, body).then(({ data }) => data);
-}
-
-export function removeTenant(id) {
- return api.delete(`/api/multi-tenancy/tenants/${id}`).then(({ data }) => data);
-}
diff --git a/templates/app/react-native/src/components/AddIcon/AddIcon.js b/templates/app/react-native/src/components/AddIcon/AddIcon.js
deleted file mode 100644
index b4cc26f36f..0000000000
--- a/templates/app/react-native/src/components/AddIcon/AddIcon.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Ionicons } from '@expo/vector-icons';
-import { Icon } from 'native-base';
-import React from 'react';
-
-export default function AddIcon({ onPress, ...iconProps }) {
- return (
-
- );
-}
diff --git a/templates/app/react-native/src/components/DataList/DataList.js b/templates/app/react-native/src/components/DataList/DataList.js
deleted file mode 100644
index 9dce6d9562..0000000000
--- a/templates/app/react-native/src/components/DataList/DataList.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import { Ionicons } from '@expo/vector-icons';
-import { useFocusEffect } from '@react-navigation/native';
-import i18n from 'i18n-js';
-import { Box, Center, FlatList, Icon, Input, Spinner, Text } from 'native-base';
-import PropTypes from 'prop-types';
-import React, { forwardRef, useCallback, useEffect, useState } from 'react';
-import { StyleSheet, View } from 'react-native';
-import LoadingActions from '../../store/actions/LoadingActions';
-import { debounce } from '../../utils/Debounce';
-import { connectToRedux } from '../../utils/ReduxConnect';
-import LoadingButton from '../LoadingButton/LoadingButton';
-
-function DataList({
- navigation,
- fetchFn,
- render,
- maxResultCount = 15,
- debounceTime = 350,
- ...props
-}) {
- const [records, setRecords] = useState([]);
- const [totalCount, setTotalCount] = useState(0);
- const [loading, setLoading] = useState(false);
- const [searchLoading, setSearchLoading] = useState(false);
- const [buttonLoading, setButtonLoading] = useState(false);
- const [skipCount, setSkipCount] = useState(0);
- const [filter, setFilter] = useState('');
-
- const fetch = (skip = 0, isRefreshingActive = true) => {
- if (isRefreshingActive) setLoading(true);
- return fetchFn({ filter, maxResultCount, skipCount: skip })
- .then(({ items, totalCount: total }) => {
- setTotalCount(total);
- setRecords(skip ? [...records, ...items] : items);
- setSkipCount(skip);
- })
- .finally(() => {
- if (isRefreshingActive) setLoading(false);
- });
- };
-
- const fetchPartial = () => {
- if (loading || records.length === totalCount) return;
-
- setButtonLoading(true);
- fetch(skipCount + maxResultCount, false).finally(() =>
- setButtonLoading(false)
- );
- };
-
- useFocusEffect(
- useCallback(() => {
- setSkipCount(0);
- fetch(0, false);
- }, [])
- );
-
- useEffect(() => {
- function searchFetch() {
- setSearchLoading(true);
- return fetch(0, false).finally(() =>
- setTimeout(() => setSearchLoading(false), 150)
- );
- }
- debounce(searchFetch, debounceTime)();
- }, [filter]);
-
- return (
-
-
-
- ) : (
-
- )
- }
- />
- (
- <>
- {render(...args)}
- {args.index + 1 === skipCount + maxResultCount &&
- totalCount > records.length ? (
-
- fetchPartial()}
- >
- {i18n.t('AbpUi::LoadMore')}
-
-
- ) : null}
- >
- )}
- {...props}
- />
-
-
- );
-}
-
-DataList.propTypes = {
- ...FlatList.propTypes,
- fetchFn: PropTypes.func.isRequired,
- render: PropTypes.func.isRequired,
- maxResultCount: PropTypes.number,
- debounceTime: PropTypes.number,
-};
-
-const styles = StyleSheet.create({
- container: { flex: 1 },
- list: {},
-});
-
-const Forwarded = forwardRef((props, ref) => (
-
-));
-
-export default connectToRedux({
- component: Forwarded,
- dispatchProps: {
- startLoading: LoadingActions.start,
- stopLoading: LoadingActions.stop,
- },
-});
diff --git a/templates/app/react-native/src/components/DrawerContent/DrawerContent.js b/templates/app/react-native/src/components/DrawerContent/DrawerContent.js
deleted file mode 100644
index 4f7792fab5..0000000000
--- a/templates/app/react-native/src/components/DrawerContent/DrawerContent.js
+++ /dev/null
@@ -1,104 +0,0 @@
-import { Ionicons } from '@expo/vector-icons';
-import Constants from 'expo-constants';
-import i18n from 'i18n-js';
-import { List, Text, View } from 'native-base';
-import PropTypes from 'prop-types';
-import React from 'react';
-import { Image, StyleSheet } from 'react-native';
-import { SafeAreaView } from 'react-native-safe-area-context';
-import { withPermission } from '../../hocs/PermissionHOC';
-
-const screens = {
- HomeStack: { label: '::Menu:Home', iconName: 'home' },
- UsersStack: {
- label: 'AbpIdentity::Users',
- iconName: 'people',
- requiredPolicy: 'AbpIdentity.Users',
- },
- TenantsStack: {
- label: 'AbpTenantManagement::Tenants',
- iconName: 'book-outline',
- requiredPolicy: 'AbpTenantManagement.Tenants',
- },
- SettingsStack: { label: 'AbpSettingManagement::Settings', iconName: 'cog' },
-};
-
-const ListItemWithPermission = withPermission(List.Item);
-
-function DrawerContent({
- navigation,
- state: { routeNames, index: currentScreenIndex },
-}) {
- const navigate = (screen) => {
- navigation.navigate(screen);
- navigation.closeDrawer();
- };
-
- return (
-
-
-
-
-
-
- {routeNames.map((name) => (
- navigate(name)}
- my="0"
- >
-
- {i18n.t(screens[name].label)}
-
- ))}
-
-
-
-
- © MyProjectName
-
-
- v{Constants.expoConfig.version}
-
-
-
- );
-}
-
-const styles = StyleSheet.create({
- container: {
- flexGrow: 1,
- },
- logo: {
- marginTop: 20,
- marginBottom: 15,
- },
- headerView: {
- alignItems: 'center',
- },
- footer: {
- backgroundColor: '#eee',
- flexDirection: 'row',
- justifyContent: 'space-between',
- },
- copyRight: {
- margin: 15,
- },
- version: {
- margin: 15,
- },
-});
-
-DrawerContent.propTypes = {
- state: PropTypes.object.isRequired,
-};
-
-export default DrawerContent;
diff --git a/templates/app/react-native/src/components/FormButtons/FormButtons.js b/templates/app/react-native/src/components/FormButtons/FormButtons.js
deleted file mode 100644
index d844f7747a..0000000000
--- a/templates/app/react-native/src/components/FormButtons/FormButtons.js
+++ /dev/null
@@ -1,78 +0,0 @@
-import i18n from 'i18n-js';
-import { Button, Text } from 'native-base';
-import PropTypes from 'prop-types';
-import React, { forwardRef } from 'react';
-import { Alert, StyleSheet, View } from 'react-native';
-
-function FormButtons({
- submit,
- remove,
- removeMessage,
- isRemoveDisabled,
- isSubmitDisabled,
- isShowRemove = false,
- isShowSubmit = true,
-}) {
- const confirmation = () => {
- Alert.alert(
- i18n.t('AbpUi::AreYouSure'),
- removeMessage,
- [
- {
- text: i18n.t('AbpUi::Cancel'),
- style: 'cancel',
- },
- { text: i18n.t('AbpUi::Yes'), onPress: () => remove() },
- ],
- { cancelable: true },
- );
- };
-
- return (
-
- {isShowRemove ? (
-
- ) : null}
- {isShowSubmit ? (
-
- ) : null}
-
- );
-}
-
-FormButtons.propTypes = {
- submit: PropTypes.func.isRequired,
- remove: PropTypes.func,
- removeMessage: PropTypes.string,
- style: PropTypes.any,
- isRemoveDisabled: PropTypes.bool,
- isSubmitDisabled: PropTypes.bool,
- isShowRemove: PropTypes.bool,
- isShowSubmit: PropTypes.bool,
-};
-
-const styles = StyleSheet.create({
- container: {
- width: '100%',
- justifyContent: 'center',
- alignItems: 'center',
- position: 'absolute',
- bottom: 0,
- flexDirection: 'row',
- },
-});
-
-const Forwarded = forwardRef((props, ref) => );
-
-export default Forwarded;
diff --git a/templates/app/react-native/src/components/FormButtons/index.js b/templates/app/react-native/src/components/FormButtons/index.js
deleted file mode 100644
index bf8864e7e0..0000000000
--- a/templates/app/react-native/src/components/FormButtons/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default as FormButtons } from './FormButtons';
diff --git a/templates/app/react-native/src/components/HamburgerIcon/HamburgerIcon.js b/templates/app/react-native/src/components/HamburgerIcon/HamburgerIcon.js
deleted file mode 100644
index 2d165f8249..0000000000
--- a/templates/app/react-native/src/components/HamburgerIcon/HamburgerIcon.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Ionicons } from '@expo/vector-icons';
-import { Icon } from 'native-base';
-import React from 'react';
-import { Platform } from 'react-native';
-
-export default function HamburgerIcon({ navigation, ...iconProps }) {
- return (
- navigation.openDrawer()}
- as={Ionicons}
- name={Platform.OS ? 'ios-menu' : 'md-menu'}
- size="8"
- marginLeft={2}
- {...iconProps}
- />
- );
-}
diff --git a/templates/app/react-native/src/components/Loading/Loading.js b/templates/app/react-native/src/components/Loading/Loading.js
deleted file mode 100644
index bd8f5ff180..0000000000
--- a/templates/app/react-native/src/components/Loading/Loading.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { Spinner, View } from 'native-base';
-import PropTypes from 'prop-types';
-import React, { forwardRef } from 'react';
-import { StyleSheet } from 'react-native';
-import {
- createLoadingSelector,
- createOpacitySelector
-} from '../../store/selectors/LoadingSelectors';
-import { connectToRedux } from '../../utils/ReduxConnect';
-
-function Loading({ loading, opacity }) {
- return loading ? (
-
-
-
-
- ) : null;
-}
-const Forwarded = forwardRef((props, ref) => );
-
-const backdropStyle = {
- position: 'absolute',
- top: 0,
- left: 0,
- width: '100%',
- height: '100%',
- backgroundColor: '#fff',
-};
-
-export const styles = StyleSheet.create({
- container: {
- ...backdropStyle,
- backgroundColor: 'transparent',
- // zIndex: activeTheme.zIndex.indicator, // TODO
- alignItems: 'center',
- justifyContent: 'center',
- },
- backdrop: backdropStyle,
- spinner: {
- // color: activeTheme.brandPrimary, // TODO
- fontSize: 100,
- },
-});
-
-Loading.propTypes = {
- style: PropTypes.objectOf(PropTypes.any),
- loading: PropTypes.bool,
- opacity: PropTypes.number,
-};
-
-export default connectToRedux({
- component: Forwarded,
- stateProps: state => ({
- loading: createLoadingSelector()(state),
- opacity: createOpacitySelector()(state),
- }),
-});
diff --git a/templates/app/react-native/src/components/LoadingButton/LoadingButton.js b/templates/app/react-native/src/components/LoadingButton/LoadingButton.js
deleted file mode 100644
index d36c7fc68c..0000000000
--- a/templates/app/react-native/src/components/LoadingButton/LoadingButton.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Button, Spinner } from 'native-base';
-import PropTypes from 'prop-types';
-import React from 'react';
-import { StyleSheet } from 'react-native';
-
-export default function LoadingButton({ loading = false, style, children, ...props }) {
- return (
-
- );
-}
-
-LoadingButton.propTypes = {
- ...Button.propTypes,
- loading: PropTypes.bool.isRequired,
-};
-
-const styles = StyleSheet.create({
- button: { marginTop: 20, marginBottom: 30, height: 30 },
-});
\ No newline at end of file
diff --git a/templates/app/react-native/src/components/TenantBox/TenantBox.js b/templates/app/react-native/src/components/TenantBox/TenantBox.js
deleted file mode 100644
index 939efb3c88..0000000000
--- a/templates/app/react-native/src/components/TenantBox/TenantBox.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import i18n from 'i18n-js';
-import { Box, Button, FormControl, Input, Text } from 'native-base';
-import PropTypes from 'prop-types';
-import React, { forwardRef, useState } from 'react';
-import { Alert, StyleSheet, View } from 'react-native';
-import { getTenant } from '../../api/AccountAPI';
-import PersistentStorageActions from '../../store/actions/PersistentStorageActions';
-import { createTenantSelector } from '../../store/selectors/PersistentStorageSelectors';
-import { connectToRedux } from '../../utils/ReduxConnect';
-
-function TenantBox({
- tenant = {},
- setTenant,
- showTenantSelection,
- toggleTenantSelection,
-}) {
- const [tenantName, setTenantName] = useState(tenant.name);
-
- const findTenant = () => {
- if (!tenantName) {
- setTenant({});
- toggleTenantSelection();
- return;
- }
-
- getTenant(tenantName).then(({ success, ...data }) => {
- if (!success) {
- Alert.alert(
- i18n.t('AbpUi::Error'),
- i18n.t('AbpUiMultiTenancy::GivenTenantIsNotAvailable', {
- 0: tenantName,
- }),
- [{ text: i18n.t('AbpUi::Ok') }]
- );
- return;
- }
- setTenant(data);
- toggleTenantSelection();
- });
- };
-
- return (
- <>
-
-
-
- {i18n.t('AbpUiMultiTenancy::Tenant')}
-
-
- {tenant.name
- ? tenant.name
- : i18n.t('AbpUiMultiTenancy::NotSelected')}
-
-
-
-
- {showTenantSelection ? (
-
-
-
- {i18n.t('AbpUiMultiTenancy::Name')}
-
-
-
-
- {i18n.t('AbpUiMultiTenancy::SwitchTenantHint')}
-
-
-
-
-
-
- ) : null}
- >
- );
-}
-
-TenantBox.propTypes = {
- setTenant: PropTypes.func.isRequired,
- showTenantSelection: PropTypes.bool.isRequired,
- toggleTenantSelection: PropTypes.func.isRequired,
- tenant: PropTypes.object.isRequired,
-};
-
-const styles = StyleSheet.create({
- button: { marginTop: 20, width: '49%' },
-
- tenant: { color: '#777' },
- title: {
- marginRight: 10,
- fontSize: 13,
- fontWeight: '600',
- textTransform: 'uppercase',
- },
- hint: { color: '#bbb', textAlign: 'left' },
-});
-
-const Forwarded = forwardRef((props, ref) => (
-
-));
-
-export default connectToRedux({
- component: Forwarded,
- dispatchProps: {
- setTenant: PersistentStorageActions.setTenant,
- },
- stateProps: (state) => ({
- tenant: createTenantSelector()(state),
- }),
-});
\ No newline at end of file
diff --git a/templates/app/react-native/src/components/ValidationMessage/ValidationMessage.js b/templates/app/react-native/src/components/ValidationMessage/ValidationMessage.js
deleted file mode 100644
index c2a398f379..0000000000
--- a/templates/app/react-native/src/components/ValidationMessage/ValidationMessage.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import i18n from 'i18n-js';
-import React, { forwardRef } from 'react';
-import { Text } from 'react-native';
-
-const ValidationMessage = ({ children, ...props }) =>
- children ? {i18n.t(children)} : null;
-
-const styles = {
- fontSize: 12,
- marginTop: 3,
- color: '#ed2f2f',
-};
-
-const Forwarded = forwardRef((props, ref) => );
-
-export default Forwarded
diff --git a/templates/app/react-native/src/contexts/LocalizationContext.js b/templates/app/react-native/src/contexts/LocalizationContext.js
deleted file mode 100644
index 83c68ba2bc..0000000000
--- a/templates/app/react-native/src/contexts/LocalizationContext.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import React from 'react';
-
-export const LocalizationContext = React.createContext();
diff --git a/templates/app/react-native/src/hocs/PermissionHOC.js b/templates/app/react-native/src/hocs/PermissionHOC.js
deleted file mode 100644
index 6cf8025428..0000000000
--- a/templates/app/react-native/src/hocs/PermissionHOC.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React, { forwardRef } from 'react';
-import PropTypes from 'prop-types';
-import { usePermission } from '../hooks/UsePermission';
-
-export function withPermission(Component, policyKey) {
- const Forwarded = forwardRef((props, ref) => {
- const isGranted =
- policyKey || props.policyKey ? usePermission(policyKey || props.policyKey) : true;
- return isGranted ? : null;
- });
-
- Forwarded.propTypes = {
- policyKey: PropTypes.string,
- };
-
- return Forwarded;
-}
diff --git a/templates/app/react-native/src/hooks/UsePermission.js b/templates/app/react-native/src/hooks/UsePermission.js
deleted file mode 100644
index a50d8f7fa1..0000000000
--- a/templates/app/react-native/src/hooks/UsePermission.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { useEffect, useState } from 'react';
-import { store } from '../store';
-import { createGrantedPolicySelector } from '../store/selectors/AppSelectors';
-
-export function usePermission(key) {
- const [permission, setPermission] = useState(false);
-
- const state = store.getState();
- const policy = createGrantedPolicySelector(key)(state);
-
- useEffect(() => {
- setPermission(policy);
- }, [policy]);
-
- return permission;
-}
diff --git a/templates/app/react-native/src/interceptors/APIInterceptor.js b/templates/app/react-native/src/interceptors/APIInterceptor.js
deleted file mode 100644
index b5ffc56a3c..0000000000
--- a/templates/app/react-native/src/interceptors/APIInterceptor.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import i18n from 'i18n-js';
-import { Toast } from 'native-base';
-import api from '../api/API';
-import LoadingActions from '../store/actions/LoadingActions';
-import PersistentStorageActions from '../store/actions/PersistentStorageActions';
-
-export function initAPIInterceptor(store) {
- api.interceptors.request.use(
- async request => {
- const {
- persistentStorage: { token, language, tenant },
- } = store.getState();
-
- if (!request.headers.Authorization && token && token.access_token) {
- request.headers.Authorization = `${token.token_type} ${token.access_token}`;
- }
-
- if (!request.headers['Content-Type']) {
- request.headers['Content-Type'] = 'application/json';
- }
-
- if (!request.headers['Accept-Language'] && language) {
- request.headers['Accept-Language'] = language;
- }
-
- if (!request.headers.__tenant && tenant && tenant.tenantId) {
- request.headers.__tenant = tenant.tenantId;
- }
-
- return request;
- },
- error => console.error(error),
- );
-
- api.interceptors.response.use(
- response => response,
- error => {
- store.dispatch(LoadingActions.clear());
- const errorRes = error.response;
- if (errorRes) {
- if (errorRes.headers._abperrorformat && errorRes.status === 401) {
- store.dispatch(PersistentStorageActions.setToken({}));
- }
-
- showError({ error: errorRes.data.error || {}, status: errorRes.status });
- } else {
- Toast.show({
- title: 'An unexpected error has occurred',
- isClosable: true,
- duration: 10000,
- backgroundColor: 'danger.500',
- });
- }
-
- return Promise.reject(error);
- },
- );
-}
-
-function showError({ error = {}, status }) {
- let message = '';
- let title = i18n.t('AbpAccount::DefaultErrorMessage');
-
- if (typeof error === 'string') {
- message = error;
- } else if (error.details) {
- message = error.details;
- title = error.message;
- } else if (error.message) {
- message = error.message;
- } else {
- switch (status) {
- case 401:
- title = i18n.t('AbpAccount::DefaultErrorMessage401');
- message = i18n.t('AbpAccount::DefaultErrorMessage401Detail');
- break;
- case 403:
- title = i18n.t('AbpAccount::DefaultErrorMessage403');
- message = i18n.t('AbpAccount::DefaultErrorMessage403Detail');
- break;
- case 404:
- title = i18n.t('AbpAccount::DefaultErrorMessage404');
- message = i18n.t('AbpAccount::DefaultErrorMessage404Detail');
- break;
- case 500:
- title = i18n.t('AbpAccount::500Message');
- message = i18n.t('AbpAccount::InternalServerErrorMessage');
- break;
- default:
- break;
- }
- }
-
- Toast.show({
- title: `${title}\n${message}`,
- isClosable: true,
- duration: 10000,
- backgroundColor: 'danger.500',
- });
-}
diff --git a/templates/app/react-native/src/navigators/AuthNavigator.js b/templates/app/react-native/src/navigators/AuthNavigator.js
deleted file mode 100644
index 0311556deb..0000000000
--- a/templates/app/react-native/src/navigators/AuthNavigator.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import React, { useContext } from 'react';
-import { LocalizationContext } from '../contexts/LocalizationContext';
-import LoginScreen from '../screens/Login/LoginScreen';
-
-const Stack = createNativeStackNavigator();
-
-export default function AuthNavigator() {
- const {t} = useContext(LocalizationContext);
-
- return (
-
- ({
- title: t('AbpAccount::Login'),
- })}
- />
-
- );
-}
diff --git a/templates/app/react-native/src/navigators/DrawerNavigator.js b/templates/app/react-native/src/navigators/DrawerNavigator.js
deleted file mode 100644
index 3cd83c8a13..0000000000
--- a/templates/app/react-native/src/navigators/DrawerNavigator.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import { createDrawerNavigator } from '@react-navigation/drawer';
-import React from 'react';
-import DrawerContent from '../components/DrawerContent/DrawerContent';
-import HamburgerIcon from '../components/HamburgerIcon/HamburgerIcon';
-import { LocalizationContext } from '../contexts/LocalizationContext';
-import HomeStackNavigator from './HomeNavigator';
-import SettingsStackNavigator from './SettingsNavigator';
-import TenantsStackNavigator from './TenantsNavigator';
-import UsersStackNavigator from './UsersNavigator';
-
-const Drawer = createDrawerNavigator();
-
-export default function DrawerNavigator() {
- const { t } = React.useContext(LocalizationContext);
-
- return (
-
- ({
- title: t('::Menu:Home'),
- headerLeft: () => ,
- })}
- />
- null }}
- />
- null }}
- />
- null }}
- />
-
- );
-}
diff --git a/templates/app/react-native/src/navigators/HomeNavigator.js b/templates/app/react-native/src/navigators/HomeNavigator.js
deleted file mode 100644
index 8f9e588edd..0000000000
--- a/templates/app/react-native/src/navigators/HomeNavigator.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import React from 'react';
-import HomeScreen from '../screens/Home/HomeScreen';
-
-const Stack = createNativeStackNavigator();
-
-export default function HomeStackNavigator() {
- return (
-
- null}}
- />
-
- );
-}
diff --git a/templates/app/react-native/src/navigators/SettingsNavigator.js b/templates/app/react-native/src/navigators/SettingsNavigator.js
deleted file mode 100644
index 370da97b93..0000000000
--- a/templates/app/react-native/src/navigators/SettingsNavigator.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import i18n from 'i18n-js';
-import React from 'react';
-import HamburgerIcon from '../components/HamburgerIcon/HamburgerIcon';
-import { LocalizationContext } from '../contexts/LocalizationContext';
-import ChangePasswordScreen from '../screens/ChangePassword/ChangePasswordScreen';
-import ManageProfileScreen from '../screens/ManageProfile/ManageProfileScreen';
-import SettingsScreen from '../screens/Settings/SettingsScreen';
-
-const Stack = createNativeStackNavigator();
-
-export default function SettingsStackNavigator() {
- const { t } = React.useContext(LocalizationContext);
-
- return (
-
- ({
- headerLeft: () => ,
- title: t('AbpSettingManagement::Settings'),
- })}
- />
-
-
-
- );
-}
diff --git a/templates/app/react-native/src/navigators/TenantsNavigator.js b/templates/app/react-native/src/navigators/TenantsNavigator.js
deleted file mode 100644
index 94ae711d42..0000000000
--- a/templates/app/react-native/src/navigators/TenantsNavigator.js
+++ /dev/null
@@ -1,35 +0,0 @@
-
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import React from 'react';
-import AddIcon from '../components/AddIcon/AddIcon';
-import HamburgerIcon from '../components/HamburgerIcon/HamburgerIcon';
-import { LocalizationContext } from '../contexts/LocalizationContext';
-import CreateUpdateTenantScreen from '../screens/CreateUpdateTenant/CreateUpdateTenantScreen';
-import TenantsScreen from '../screens/Tenants/TenantsScreen';
-
-const Stack = createNativeStackNavigator();
-
-export default function TenantsStackNavigator() {
- const { t } = React.useContext(LocalizationContext);
-
- return (
-
- ({
- title: t('AbpTenantManagement::Tenants'),
- headerLeft: () => ,
- headerRight: () => navigation.navigate('CreateUpdateTenant')}/>,
- })}
- />
- ({
- title: t(route.params?.tenantId ? 'AbpTenantManagement::Edit' : 'AbpTenantManagement::NewTenant'),
- })}
- />
-
- );
-}
diff --git a/templates/app/react-native/src/navigators/UsersNavigator.js b/templates/app/react-native/src/navigators/UsersNavigator.js
deleted file mode 100644
index 537129be14..0000000000
--- a/templates/app/react-native/src/navigators/UsersNavigator.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import React from 'react';
-import AddIcon from '../components/AddIcon/AddIcon';
-import HamburgerIcon from '../components/HamburgerIcon/HamburgerIcon';
-import { LocalizationContext } from '../contexts/LocalizationContext';
-import CreateUpdateUserScreen from '../screens/CreateUpdateUser/CreateUpdateUserScreen';
-import UsersScreen from '../screens/Users/UsersScreen';
-
-const Stack = createNativeStackNavigator();
-
-export default function UsersStackNavigator() {
- const { t } = React.useContext(LocalizationContext);
-
- return (
-
- ({
- title: t('AbpIdentity::Users'),
- headerLeft: () => ,
- headerRight: () => navigation.navigate('CreateUpdateUser')}/>,
- })}
- />
- ({
- title: t(route.params?.userId ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser'),
- })}
- />
-
- );
-}
diff --git a/templates/app/react-native/src/screens/ChangePassword/ChangePasswordForm.js b/templates/app/react-native/src/screens/ChangePassword/ChangePasswordForm.js
deleted file mode 100644
index 8621d00a99..0000000000
--- a/templates/app/react-native/src/screens/ChangePassword/ChangePasswordForm.js
+++ /dev/null
@@ -1,121 +0,0 @@
-import { useFormik } from 'formik';
-import i18n from 'i18n-js';
-import {
- Box,
- FormControl,
- Input,
- KeyboardAvoidingView,
- Stack,
- Icon
-} from 'native-base';
-import PropTypes from 'prop-types';
-import React, { useRef, useState } from 'react';
-import * as Yup from 'yup';
-import { FormButtons } from '../../components/FormButtons';
-import ValidationMessage from '../../components/ValidationMessage/ValidationMessage';
-import { Ionicons } from '@expo/vector-icons';
-
-const ValidationSchema = Yup.object().shape({
- currentPassword: Yup.string().required('AbpAccount::ThisFieldIsRequired.'),
- newPassword: Yup.string().required('AbpAccount::ThisFieldIsRequired.'),
-});
-
-function ChangePasswordForm({ submit, cancel }) {
- const [showCurrentPassword, setShowCurrentPassword] = useState(false);
- const [showNewPassword, setShowNewPassword] = useState(false);
-
- const currentPasswordRef = useRef();
- const newPasswordRef = useRef();
-
- const onSubmit = (values) => {
- submit({
- ...values,
- newPasswordConfirm: values.newPassword,
- });
- };
-
- const formik = useFormik({
- enableReinitialize: true,
- validationSchema: ValidationSchema,
- initialValues: {
- currentPassword: '',
- newPassword: '',
- },
- onSubmit,
- });
-
- return (
- <>
-
-
-
-
- {i18n.t('AbpIdentity::DisplayName:CurrentPassword')}
-
- newPasswordRef?.current?.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('currentPassword')}
- onBlur={formik.handleBlur('currentPassword')}
- value={formik.values.currentPassword}
- textContentType="password"
- secureTextEntry={!showCurrentPassword}
- InputRightElement={
- setShowCurrentPassword(!showCurrentPassword)}
- />
- }
- />
-
- {formik.errors.currentPassword}
-
-
-
-
-
-
-
- {i18n.t('AbpIdentity::DisplayName:NewPassword')}
-
- setShowNewPassword(!showNewPassword)}
- />
- }
- />
- {formik.errors.newPassword}
-
-
-
-
- >
- );
-}
-
-ChangePasswordForm.propTypes = {
- submit: PropTypes.func.isRequired,
- cancel: PropTypes.func.isRequired,
-};
-
-export default ChangePasswordForm;
diff --git a/templates/app/react-native/src/screens/ChangePassword/ChangePasswordScreen.js b/templates/app/react-native/src/screens/ChangePassword/ChangePasswordScreen.js
deleted file mode 100644
index 196c762a38..0000000000
--- a/templates/app/react-native/src/screens/ChangePassword/ChangePasswordScreen.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { changePassword } from '../../api/IdentityAPI';
-import LoadingActions from '../../store/actions/LoadingActions';
-import { connectToRedux } from '../../utils/ReduxConnect';
-import ChangePasswordForm from './ChangePasswordForm';
-
-function ChangePasswordScreen({ navigation, startLoading, stopLoading }) {
- const submit = data => {
- startLoading({ key: 'changePassword' });
-
- changePassword(data)
- .then(() => {
- navigation.goBack();
- })
- .finally(() => stopLoading({ key: 'changePassword' }));
- };
-
- return navigation.goBack()} />;
-}
-
-ChangePasswordScreen.propTypes = {
- startLoading: PropTypes.func.isRequired,
- stopLoading: PropTypes.func.isRequired,
-};
-
-export default connectToRedux({
- component: ChangePasswordScreen,
- dispatchProps: {
- startLoading: LoadingActions.start,
- stopLoading: LoadingActions.stop,
- },
-});
diff --git a/templates/app/react-native/src/screens/CreateUpdateTenant/CreateUpdateTenantForm.js b/templates/app/react-native/src/screens/CreateUpdateTenant/CreateUpdateTenantForm.js
deleted file mode 100644
index b76f356062..0000000000
--- a/templates/app/react-native/src/screens/CreateUpdateTenant/CreateUpdateTenantForm.js
+++ /dev/null
@@ -1,144 +0,0 @@
-import { Ionicons } from '@expo/vector-icons';
-import { useFormik } from 'formik';
-import i18n from 'i18n-js';
-import { Box, FormControl, Icon, Input, Stack } from 'native-base';
-import PropTypes from 'prop-types';
-import React, { useRef, useState } from 'react';
-import * as Yup from 'yup';
-import { FormButtons } from '../../components/FormButtons';
-import ValidationMessage from '../../components/ValidationMessage/ValidationMessage';
-import { usePermission } from '../../hooks/UsePermission';
-
-const validations = {
- name: Yup.string().required('AbpAccount::ThisFieldIsRequired.'),
-};
-
-function CreateUpdateTenantForm({ editingTenant = {}, submit, remove }) {
- const tenantNameRef = useRef();
- const adminEmailRef = useRef();
- const adminPasswordRef = useRef();
-
- const [showAdminPassword, setShowAdminPassword] = useState(false);
- const hasRemovePermission = usePermission('AbpTenantManagement.Tenants.Delete');
-
- const adminEmailAddressValidation = Yup.lazy(() =>
- Yup.string()
- .required('AbpAccount::ThisFieldIsRequired.')
- .email('AbpAccount::ThisFieldIsNotAValidEmailAddress.'),
- );
-
- const adminPasswordValidation = Yup.lazy(() =>
- Yup.string().required('AbpAccount::ThisFieldIsRequired.'),
- );
-
- const onSubmit = values => {
- submit({
- ...editingTenant,
- ...values,
- });
- };
-
- const formik = useFormik({
- enableReinitialize: true,
- validationSchema: Yup.object().shape({
- ...validations,
- ...(!editingTenant.id && {
- adminEmailAddress: adminEmailAddressValidation,
- adminPassword: adminPasswordValidation,
- }),
- }),
- initialValues: {
- lockoutEnabled: false,
- twoFactorEnabled: false,
- ...editingTenant,
- },
- onSubmit,
- });
-
- return (
- <>
-
-
-
- {i18n.t('AbpTenantManagement::TenantName')}
-
- {formik.errors.name}
-
-
-
- {!editingTenant.id ? (
- <>
-
-
-
- {i18n.t('AbpTenantManagement::DisplayName:AdminEmailAddress')}
-
- adminPasswordRef?.current?.focus()}
- returnKeyType="next"
- />
- {formik.errors.adminEmailAddress}
-
-
-
-
-
-
- {i18n.t('AbpTenantManagement::DisplayName:AdminPassword')}
-
- setShowAdminPassword(!showAdminPassword)}
- />
- }
- />
- {formik.errors.adminPassword}
-
-
- >
- ) : null}
-
-
- >
- );
-}
-
-CreateUpdateTenantForm.propTypes = {
- editingTenant: PropTypes.object,
- submit: PropTypes.func.isRequired,
- remove: PropTypes.func.isRequired,
-};
-
-export default CreateUpdateTenantForm;
diff --git a/templates/app/react-native/src/screens/CreateUpdateTenant/CreateUpdateTenantScreen.js b/templates/app/react-native/src/screens/CreateUpdateTenant/CreateUpdateTenantScreen.js
deleted file mode 100644
index a3f59a8cf7..0000000000
--- a/templates/app/react-native/src/screens/CreateUpdateTenant/CreateUpdateTenantScreen.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import { useFocusEffect } from '@react-navigation/native';
-import PropTypes from 'prop-types';
-import React, { useCallback, useState } from 'react';
-import {
- createTenant,
- getTenantById,
- removeTenant,
- updateTenant
-} from '../../api/TenantManagementAPI';
-import LoadingActions from '../../store/actions/LoadingActions';
-import { createLoadingSelector } from '../../store/selectors/LoadingSelectors';
-import { connectToRedux } from '../../utils/ReduxConnect';
-import CreateUpdateTenantForm from './CreateUpdateTenantForm';
-
-function CreateUpdateTenantScreen({ navigation, route, startLoading, stopLoading }) {
- const [tenant, setTenant] = useState();
- const tenantId = route.params?.tenantId;
-
- const remove = () => {
- startLoading({ key: 'removeTenant' });
- removeTenant(tenantId)
- .then(() => navigation.goBack())
- .finally(() => stopLoading({ key: 'removeTenant' }));
- };
-
- useFocusEffect(
- useCallback(() => {
- if (tenantId) {
- getTenantById(tenantId).then((data = {}) => setTenant(data));
- }
- }, []),
- );
-
- const submit = data => {
- startLoading({ key: 'saveTenant' });
- let request;
- if (data.id) {
- request = updateTenant(data, tenantId);
- } else {
- request = createTenant(data);
- }
-
- request
- .then(() => {
- navigation.goBack();
- })
- .finally(() => stopLoading({ key: 'saveTenant' }));
- };
-
- const renderForm = () => (
-
- );
-
- if (tenantId && tenant) {
- return renderForm();
- }
-
- if (!tenantId) {
- return renderForm();
- }
-
- return null;
-}
-
-CreateUpdateTenantScreen.propTypes = {
- startLoading: PropTypes.func.isRequired,
- stopLoading: PropTypes.func.isRequired,
-};
-
-export default connectToRedux({
- component: CreateUpdateTenantScreen,
- stateProps: state => ({ loading: createLoadingSelector()(state) }),
- dispatchProps: {
- startLoading: LoadingActions.start,
- stopLoading: LoadingActions.stop,
- },
-});
diff --git a/templates/app/react-native/src/screens/CreateUpdateUser/CreateUpdateUserForm.js b/templates/app/react-native/src/screens/CreateUpdateUser/CreateUpdateUserForm.js
deleted file mode 100644
index bb394232ba..0000000000
--- a/templates/app/react-native/src/screens/CreateUpdateUser/CreateUpdateUserForm.js
+++ /dev/null
@@ -1,272 +0,0 @@
-import { Ionicons } from '@expo/vector-icons';
-import { useFormik } from 'formik';
-import i18n from 'i18n-js';
-import {
- Box,
- Button,
- Checkbox,
- FormControl,
- Icon,
- Input,
- KeyboardAvoidingView,
- Stack
-} from 'native-base';
-import PropTypes from 'prop-types';
-import React, { useRef, useState } from 'react';
-import { Platform } from 'react-native';
-import * as Yup from 'yup';
-import { FormButtons } from '../../components/FormButtons';
-import ValidationMessage from '../../components/ValidationMessage/ValidationMessage';
-import { usePermission } from '../../hooks/UsePermission';
-import UserRoles from './UserRoles';
-
-const validations = {
- userName: Yup.string().required('AbpAccount::ThisFieldIsRequired.'),
- email: Yup.string()
- .email('AbpAccount::ThisFieldIsNotAValidEmailAddress.')
- .required('AbpAccount::ThisFieldIsRequired.'),
-};
-
-let roleNames = [];
-
-function onChangeRoles(roles) {
- roleNames = roles;
-}
-
-function CreateUpdateUserForm({ editingUser = {}, submit, remove }) {
- const [selectedTab, setSelectedTab] = useState(0);
- const [showPassword, setShowPassword] = useState(false);
-
- const usernameRef = useRef();
- const nameRef = useRef();
- const surnameRef = useRef();
- const emailRef = useRef();
- const phoneNumberRef = useRef();
- const passwordRef = useRef();
-
- const hasRemovePermission = usePermission('AbpIdentity.Users.Delete');
-
- const onSubmit = (values) => {
- submit({
- ...editingUser,
- ...values,
- roleNames,
- });
- };
-
- const passwordValidation = Yup.lazy(() => {
- if (editingUser.id) {
- return Yup.string();
- }
- return Yup.string().required('AbpAccount::ThisFieldIsRequired.');
- });
-
- const formik = useFormik({
- enableReinitialize: true,
- validationSchema: Yup.object().shape({
- ...validations,
- password: passwordValidation,
- }),
- initialValues: {
- lockoutEnabled: false,
- ...editingUser,
- },
- onSubmit,
- });
-
- return (
- <>
-
-
-
-
-
-
-
- {selectedTab === 0 ? (
- <>
-
-
-
- {i18n.t('AbpIdentity::UserName')}
-
- nameRef.current.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('userName')}
- onBlur={formik.handleBlur('userName')}
- value={formik.values.userName}
- autoCapitalize="none"
- />
-
- {formik.errors.userName}
-
-
-
-
-
-
-
- {i18n.t('AbpIdentity::DisplayName:Name')}
-
- surnameRef.current.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('name')}
- onBlur={formik.handleBlur('name')}
- value={formik.values.name}
- />
-
-
-
-
-
-
- {i18n.t('AbpIdentity::DisplayName:Surname')}
-
- emailRef.current.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('surname')}
- onBlur={formik.handleBlur('surname')}
- value={formik.values.surname}
- />
-
-
-
-
-
-
- {i18n.t('AbpIdentity::EmailAddress')}
-
- phoneNumberRef.current.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('email')}
- onBlur={formik.handleBlur('email')}
- value={formik.values.email}
- autoCapitalize="none"
- />
- {formik.errors.email}
-
-
-
-
-
-
- {i18n.t('AbpIdentity::PhoneNumber')}
-
- passwordRef?.current?.focus()}
- returnKeyType={!editingUser.id ? 'next' : 'default'}
- onChangeText={formik.handleChange('phoneNumber')}
- onBlur={formik.handleBlur('phoneNumber')}
- value={formik.values.phoneNumber}
- />
-
-
-
- {!editingUser.id ? (
-
-
-
- {i18n.t('AbpIdentity::Password')}
-
- setShowPassword(!showPassword)}
- />
- }
- />
-
- {formik.errors.password}
-
-
-
- ) : null}
-
-
-
-
- formik.setFieldValue(
- 'lockoutEnabled',
- !formik.values.lockoutEnabled
- )
- }
- >
- {i18n.t('AbpIdentity::DisplayName:LockoutEnabled')}
-
-
-
- >
- ) : (
-
- )}
-
-
-
- >
- );
-}
-
-CreateUpdateUserForm.propTypes = {
- editingUser: PropTypes.object,
- submit: PropTypes.func.isRequired,
- remove: PropTypes.func.isRequired,
-};
-
-export default CreateUpdateUserForm;
diff --git a/templates/app/react-native/src/screens/CreateUpdateUser/CreateUpdateUserScreen.js b/templates/app/react-native/src/screens/CreateUpdateUser/CreateUpdateUserScreen.js
deleted file mode 100644
index e900fde8fc..0000000000
--- a/templates/app/react-native/src/screens/CreateUpdateUser/CreateUpdateUserScreen.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { useEffect, useState } from 'react';
-import { createUser, getUserById, removeUser, updateUser } from '../../api/IdentityAPI';
-import LoadingActions from '../../store/actions/LoadingActions';
-import { createLoadingSelector } from '../../store/selectors/LoadingSelectors';
-import { connectToRedux } from '../../utils/ReduxConnect';
-import CreateUpdateUserForm from './CreateUpdateUserForm';
-
-function CreateUpdateUserScreen({ navigation, route, startLoading, stopLoading }) {
- const [user, setUser] = useState();
- const userId = route.params?.userId;
-
- const remove = () => {
- startLoading({ key: 'remove user' });
- removeUser(userId)
- .then(() => navigation.goBack())
- .finally(() => stopLoading({ key: 'remove user' }));
- };
-
- useEffect(() => {
- if (userId) {
- getUserById(userId).then((data = {}) => setUser(data));
- }
- }, []);
-
- const submit = data => {
- startLoading({ key: 'saveUser' });
- let request;
- if (data.id) {
- request = updateUser(data, userId);
- } else {
- request = createUser(data);
- }
-
- request
- .then(() => {
- navigation.goBack();
- })
- .finally(() => stopLoading({ key: 'saveUser' }));
- };
-
- const renderForm = () => (
-
- );
-
- if (userId && user) {
- return renderForm();
- }
-
- if (!userId) {
- return renderForm();
- }
-
- return null;
-}
-
-CreateUpdateUserScreen.propTypes = {
- startLoading: PropTypes.func.isRequired,
- stopLoading: PropTypes.func.isRequired,
-};
-
-export default connectToRedux({
- component: CreateUpdateUserScreen,
- stateProps: state => ({ loading: createLoadingSelector()(state) }),
- dispatchProps: {
- startLoading: LoadingActions.start,
- stopLoading: LoadingActions.stop,
- },
-});
diff --git a/templates/app/react-native/src/screens/CreateUpdateUser/UserRoles.js b/templates/app/react-native/src/screens/CreateUpdateUser/UserRoles.js
deleted file mode 100644
index 25db76afee..0000000000
--- a/templates/app/react-native/src/screens/CreateUpdateUser/UserRoles.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import { Box, Checkbox, List } from 'native-base';
-import PropTypes from 'prop-types';
-import React, { useEffect, useState } from 'react';
-import { getAllRoles, getUserRoles } from '../../api/IdentityAPI';
-
-function UserRoles({ editingUser = {}, onChangeRoles }) {
- const [roles, setRoles] = useState([]);
-
- const onPress = index => {
- setRoles(
- roles.map((role, i) => ({
- ...role,
- isSelected: index === i ? !role.isSelected : role.isSelected,
- })),
- );
- };
-
- useEffect(() => {
- const requests = [getAllRoles()];
- if (editingUser.id) requests.push(getUserRoles(editingUser.id));
-
- Promise.all(requests).then(([allRoles = [], userRoles = []]) => {
- setRoles(
- allRoles.map(role => ({
- ...role,
- isSelected: editingUser.id
- ? !!userRoles?.find(userRole => userRole?.id === role?.id)
- : role.isDefault,
- })),
- );
- });
- }, []);
-
- useEffect(() => {
- onChangeRoles(roles.filter(role => role.isSelected).map(role => role.name));
- }, [roles]);
-
- return (
-
-
- {roles.map((role, index) => (
-
- onPress(index)} >
- {role.name}
-
-
- ))}
-
-
- );
-}
-
-UserRoles.propTypes = {
- editingUser: PropTypes.objectOf(PropTypes.any).isRequired,
- onChangeRoles: PropTypes.func.isRequired,
-};
-
-export default UserRoles;
diff --git a/templates/app/react-native/src/screens/Home/HomeScreen.js b/templates/app/react-native/src/screens/Home/HomeScreen.js
deleted file mode 100644
index 82ca221e2d..0000000000
--- a/templates/app/react-native/src/screens/Home/HomeScreen.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import i18n from 'i18n-js';
-import { Box, Center, Heading, Text } from 'native-base';
-import React from 'react';
-import { StyleSheet } from 'react-native';
-
-function HomeScreen() {
- return (
-
-
- {i18n.t('::Welcome')}
-
- {i18n.t('::LongWelcomeMessage')}
-
-
-
- );
-}
-
-const styles = StyleSheet.create({
- centeredText: {
- textAlign: 'center',
- marginBottom: 5
- },
-});
-
-export default HomeScreen;
diff --git a/templates/app/react-native/src/screens/Login/LoginScreen.js b/templates/app/react-native/src/screens/Login/LoginScreen.js
deleted file mode 100644
index acb72076fa..0000000000
--- a/templates/app/react-native/src/screens/Login/LoginScreen.js
+++ /dev/null
@@ -1,154 +0,0 @@
-import { useFormik } from 'formik';
-import i18n from 'i18n-js';
-import {
- Box,
- Button,
- Center,
- FormControl, Image, Input,
- Stack,
- WarningOutlineIcon
-} from 'native-base';
-import PropTypes from 'prop-types';
-import React, { useRef, useState } from 'react';
-import { View } from 'react-native';
-import { object, string } from 'yup';
-import { login } from '../../api/AccountAPI';
-import TenantBox from '../../components/TenantBox/TenantBox';
-import ValidationMessage from '../../components/ValidationMessage/ValidationMessage';
-import AppActions from '../../store/actions/AppActions';
-import LoadingActions from '../../store/actions/LoadingActions';
-import PersistentStorageActions from '../../store/actions/PersistentStorageActions';
-import { connectToRedux } from '../../utils/ReduxConnect';
-
-const ValidationSchema = object().shape({
- username: string().required('AbpAccount::ThisFieldIsRequired.'),
- password: string().required('AbpAccount::ThisFieldIsRequired.'),
-});
-
-function LoginScreen({ startLoading, stopLoading, setToken, fetchAppConfig }) {
- const [showTenantSelection, setShowTenantSelection] = useState(false);
- const passwordRef = useRef(null);
-
- const toggleTenantSelection = () => {
- setShowTenantSelection(!showTenantSelection);
- };
-
- const submit = ({ username, password }) => {
- startLoading({ key: 'login' });
- login({ username, password })
- .then((data) =>
- setToken({
- ...data,
- expire_time: new Date().valueOf() + data.expires_in,
- scope: undefined,
- })
- )
- .then(
- () =>
- new Promise((resolve) =>
- fetchAppConfig({
- showLoading: false,
- callback: () => resolve(true),
- })
- )
- )
- .finally(() => stopLoading({ key: 'login' }));
- };
-
- const formik = useFormik({
- validationSchema: ValidationSchema,
- initialValues: { username: '', password: '' },
- onSubmit: submit,
- });
-
- return (
-
-
-
-
-
-
-
-
-
-
- {i18n.t('AbpAccount::UserNameOrEmailAddress')}
-
- passwordRef?.current?.focus()}
- size="lg"
- />
- {formik.errors.username}
-
-
-
-
-
-
- {i18n.t('AbpAccount::Password')}
-
-
- }
- >
- {formik.errors.password}
-
-
-
-
-
-
-
-
-
- );
-}
-
-LoginScreen.propTypes = {
- startLoading: PropTypes.func.isRequired,
- stopLoading: PropTypes.func.isRequired,
- setToken: PropTypes.func.isRequired,
- fetchAppConfig: PropTypes.func.isRequired,
-};
-
-export default connectToRedux({
- component: LoginScreen,
- dispatchProps: {
- startLoading: LoadingActions.start,
- stopLoading: LoadingActions.stop,
- fetchAppConfig: AppActions.fetchAppConfigAsync,
- setToken: PersistentStorageActions.setToken,
- },
-});
diff --git a/templates/app/react-native/src/screens/ManageProfile/ManageProfileForm.js b/templates/app/react-native/src/screens/ManageProfile/ManageProfileForm.js
deleted file mode 100644
index 2dffd3624b..0000000000
--- a/templates/app/react-native/src/screens/ManageProfile/ManageProfileForm.js
+++ /dev/null
@@ -1,153 +0,0 @@
-import { useFormik } from 'formik';
-import i18n from 'i18n-js';
-import {
- Box,
- FormControl,
- Input,
- KeyboardAvoidingView,
- Stack,
-} from 'native-base';
-import PropTypes from 'prop-types';
-import React, { useRef } from 'react';
-import * as Yup from 'yup';
-import FormButtons from '../../components/FormButtons/FormButtons';
-import ValidationMessage from '../../components/ValidationMessage/ValidationMessage';
-
-const ValidationSchema = Yup.object().shape({
- userName: Yup.string().required('AbpAccount::ThisFieldIsRequired.'),
- email: Yup.string()
- .required('AbpAccount::ThisFieldIsRequired.')
- .email('AbpAccount::ThisFieldIsNotAValidEmailAddress.'),
-});
-
-function ManageProfileForm({ editingUser = {}, submit, cancel }) {
- const usernameRef = useRef();
- const nameRef = useRef();
- const surnameRef = useRef();
- const emailRef = useRef();
- const phoneNumberRef = useRef();
-
- const onSubmit = (values) => {
- submit({
- ...editingUser,
- ...values,
- });
- };
-
- const formik = useFormik({
- enableReinitialize: true,
- validationSchema: ValidationSchema,
- initialValues: {
- ...editingUser,
- },
- onSubmit,
- });
-
- return (
- <>
-
-
-
-
-
- {i18n.t('AbpIdentity::UserName')}
-
- nameRef?.current?.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('userName')}
- onBlur={formik.handleBlur('userName')}
- value={formik.values.userName}
- />
- {formik.errors.userName}
-
-
-
-
-
-
- {i18n.t('AbpIdentity::DisplayName:Name')}
-
- surnameRef?.current?.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('name')}
- onBlur={formik.handleBlur('name')}
- value={formik.values.name}
- />
-
-
-
-
-
-
- {i18n.t('AbpIdentity::DisplayName:Surname')}
-
- phoneNumberRef?.current?.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('surname')}
- onBlur={formik.handleBlur('surname')}
- value={formik.values.surname}
- />
-
-
-
-
-
-
- {i18n.t('AbpIdentity::PhoneNumber')}
-
- emailRef?.current?.focus()}
- returnKeyType="next"
- onChangeText={formik.handleChange('phoneNumber')}
- onBlur={formik.handleBlur('phoneNumber')}
- value={formik.values.phoneNumber}
- />
-
-
-
-
-
-
- {i18n.t('AbpIdentity::EmailAddress')}
-
-
- {formik.errors.email}
-
-
-
-
-
- >
- );
-}
-
-ManageProfileForm.propTypes = {
- editingUser: PropTypes.object.isRequired,
- submit: PropTypes.func.isRequired,
- cancel: PropTypes.func.isRequired,
-};
-
-export default ManageProfileForm;
diff --git a/templates/app/react-native/src/screens/ManageProfile/ManageProfileScreen.js b/templates/app/react-native/src/screens/ManageProfile/ManageProfileScreen.js
deleted file mode 100644
index 1f2e577a37..0000000000
--- a/templates/app/react-native/src/screens/ManageProfile/ManageProfileScreen.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import { updateProfileDetail, getProfileDetail } from '../../api/IdentityAPI';
-import ManageProfileForm from './ManageProfileForm';
-import LoadingActions from '../../store/actions/LoadingActions';
-import { connectToRedux } from '../../utils/ReduxConnect';
-
-function ManageProfileScreen({ navigation, startLoading, stopLoading }) {
- const [user, setUser] = useState();
-
- useEffect(() => {
- if (!user) {
- startLoading({ key: 'manageProfile' });
- getProfileDetail()
- .then((data = {}) => setUser(data))
- .finally(() => stopLoading({ key: 'manageProfile' }));
- }
- });
-
- const submit = data => {
- startLoading({ key: 'manageProfile' });
-
- updateProfileDetail(data)
- .then(() => {
- navigation.goBack();
- })
- .finally(() => stopLoading({ key: 'manageProfile' }));
- };
-
- return (
- <>
- {user ? (
- navigation.goBack()} />
- ) : null}
- >
- );
-}
-
-ManageProfileScreen.propTypes = {
- startLoading: PropTypes.func.isRequired,
- stopLoading: PropTypes.func.isRequired,
-};
-
-export default connectToRedux({
- component: ManageProfileScreen,
- dispatchProps: {
- startLoading: LoadingActions.start,
- stopLoading: LoadingActions.stop,
- },
-});
diff --git a/templates/app/react-native/src/screens/Settings/SettingsScreen.js b/templates/app/react-native/src/screens/Settings/SettingsScreen.js
deleted file mode 100644
index 58ede9cbb5..0000000000
--- a/templates/app/react-native/src/screens/Settings/SettingsScreen.js
+++ /dev/null
@@ -1,157 +0,0 @@
-import { Ionicons } from '@expo/vector-icons';
-import { useFocusEffect } from '@react-navigation/native';
-import i18n from 'i18n-js';
-import {
- Avatar,
- Button,
- Divider,
- FormControl,
- List,
- Select,
- Stack,
- Text,
- View,
-} from 'native-base';
-import PropTypes from 'prop-types';
-import React, { useCallback, useState } from 'react';
-import { getProfileDetail } from '../../api/IdentityAPI';
-import AppActions from '../../store/actions/AppActions';
-import {
- createLanguageSelector,
- createLanguagesSelector,
-} from '../../store/selectors/AppSelectors';
-import { createTenantSelector } from '../../store/selectors/PersistentStorageSelectors';
-import { connectToRedux } from '../../utils/ReduxConnect';
-import { store } from '../../store/index';
-import { getEnvVars } from '../../../Environment';
-
-const env = getEnvVars();
-
-function SettingsScreen({
- navigation,
- language,
- languages,
- setLanguageAsync,
- logoutAsync,
- tenant = {},
-}) {
- const [user, setUser] = useState({});
- const [token, setToken] = useState(store.getState().persistentStorage.token);
-
- const fetchUser = () => {
- getProfileDetail().then(data => {
- setUser(data || {});
- });
- };
-
- useFocusEffect(
- useCallback(() => {
- fetchUser();
- }, []),
- );
-
- const logout = () => {
- const { clientId } = env.oAuthConfig;
- const { access_token, refresh_token } = token;
-
- logoutAsync({
- client_id: clientId,
- token: access_token,
- refresh_token: refresh_token,
- });
- };
-
- return (
-
-
- navigation.navigate('ManageProfile')}>
-
-
-
-
- {tenant.name ? `${tenant.name}/` : ''}
- {user.userName ? `${user.userName}` : ''}
-
-
-
-
-
-
-
- navigation.navigate('ChangePassword')}>
-
- {i18n.t('AbpUi::ChangePassword')}
-
-
-
-
-
-
-
-
- {i18n.t('AbpUi::Language')}
-
-
-
-
-
-
-
-
- );
-}
-
-SettingsScreen.propTypes = {
- setLanguageAsync: PropTypes.func.isRequired,
- logoutAsync: PropTypes.func.isRequired,
- language: PropTypes.object.isRequired,
- languages: PropTypes.array.isRequired,
- tenant: PropTypes.object.isRequired,
-};
-
-export default connectToRedux({
- component: SettingsScreen,
- stateProps: state => ({
- languages: createLanguagesSelector()(state),
- language: createLanguageSelector()(state),
- tenant: createTenantSelector()(state),
- }),
- dispatchProps: {
- setLanguageAsync: AppActions.setLanguageAsync,
- logoutAsync: AppActions.logoutAsync,
- },
-});
diff --git a/templates/app/react-native/src/screens/Tenants/TenantsScreen.js b/templates/app/react-native/src/screens/Tenants/TenantsScreen.js
deleted file mode 100644
index da3dac53af..0000000000
--- a/templates/app/react-native/src/screens/Tenants/TenantsScreen.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Box, HStack, Pressable, Text } from 'native-base';
-import React from 'react';
-import { getTenants } from '../../api/TenantManagementAPI';
-import DataList from '../../components/DataList/DataList';
-import { LocalizationContext } from '../../contexts/LocalizationContext';
-
-function TenantsScreen({ navigation }) {
- const { t } = React.useContext(LocalizationContext);
-
- return (
-
-
- );
-}
-
-const navigateToCreateUpdateTenantScreen = (navigation, tenant = {}) => {
- navigation.navigate('CreateUpdateTenant', {
- tenantId: tenant.id,
- });
-};
-
-export default TenantsScreen;
diff --git a/templates/app/react-native/src/screens/Users/UsersScreen.js b/templates/app/react-native/src/screens/Users/UsersScreen.js
deleted file mode 100644
index b49658cb24..0000000000
--- a/templates/app/react-native/src/screens/Users/UsersScreen.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { Box, HStack, Pressable, Text } from 'native-base';
-import React from 'react';
-import { getUsers } from '../../api/IdentityAPI';
-import DataList from '../../components/DataList/DataList';
-import { LocalizationContext } from '../../contexts/LocalizationContext';
-
-function UsersScreen({ navigation }) {
- const { t } = React.useContext(LocalizationContext);
-
- return (
-