├── .watchmanconfig
├── jest.config.js
├── .bundle
└── config
├── react-native.config.js
├── tsconfig.json
├── src
├── hotel_booking
│ ├── index.ts
│ ├── README.md
│ ├── SliderView.tsx
│ ├── model
│ │ └── hotel_list_data.ts
│ ├── RangeSliderView.tsx
│ ├── HotelListItem.tsx
│ ├── CalendarPopupView.tsx
│ ├── Switch.tsx
│ ├── HotelHomeScreen.tsx
│ └── FiltersModal.tsx
├── introduction_animation
│ ├── index.ts
│ ├── scenes
│ │ ├── index.ts
│ │ ├── WelcomeView.tsx
│ │ ├── MoodDiaryView.tsx
│ │ ├── RelaxView.tsx
│ │ ├── CareView.tsx
│ │ ├── TopBackSkipView.tsx
│ │ ├── SplashView.tsx
│ │ ├── components
│ │ │ └── NextButtonArrow.tsx
│ │ └── CenterNextButton.tsx
│ ├── README.md
│ └── IntroductionAnimationScreen.tsx
├── assets
│ ├── home
│ │ ├── helpImage.png
│ │ ├── userImage.png
│ │ ├── inviteImage.png
│ │ ├── supportIcon.png
│ │ ├── custom_drawer.png
│ │ └── feedbackImage.png
│ ├── hotel
│ │ ├── hotel_1.png
│ │ ├── hotel_2.png
│ │ ├── hotel_3.png
│ │ ├── hotel_4.png
│ │ ├── hotel_5.png
│ │ └── hotel_booking.png
│ ├── fitness_app
│ │ ├── area1.png
│ │ ├── area2.png
│ │ ├── area3.png
│ │ ├── back.png
│ │ ├── bell.png
│ │ ├── eaten.png
│ │ ├── glass.png
│ │ ├── lunch.png
│ │ ├── snack.png
│ │ ├── tab_1.png
│ │ ├── tab_2.png
│ │ ├── tab_3.png
│ │ ├── tab_4.png
│ │ ├── bottle.png
│ │ ├── burned.png
│ │ ├── dinner.png
│ │ ├── runner.png
│ │ ├── tab_1s.png
│ │ ├── tab_2s.png
│ │ ├── tab_3s.png
│ │ ├── tab_4s.png
│ │ ├── breakfast.png
│ │ └── fitness_app.png
│ ├── fonts
│ │ ├── WorkSans-Bold.ttf
│ │ ├── WorkSans-Medium.ttf
│ │ ├── WorkSans-Regular.ttf
│ │ └── WorkSans-SemiBold.ttf
│ ├── design_course
│ │ ├── interFace1.png
│ │ ├── interFace2.png
│ │ ├── interFace3.png
│ │ ├── interFace4.png
│ │ ├── userImage.png
│ │ ├── design_course.png
│ │ └── webInterFace.png
│ ├── introduction_animation
│ │ ├── welcome.png
│ │ ├── care_image.png
│ │ ├── relax_image.png
│ │ ├── mood_dairy_image.png
│ │ ├── introduction_image.png
│ │ └── introduction_animation.png
│ └── index.ts
├── design_course
│ ├── index.ts
│ ├── README.md
│ ├── model
│ │ └── category.ts
│ ├── PopulerCourseListView.tsx
│ ├── CategoryListView.tsx
│ ├── HomeDesignCourse.tsx
│ └── CourseInfoScreen.tsx
├── Config.ts
├── util
│ └── action.ts
├── index.ts
├── AppControlFlow.tsx
├── components
│ ├── MyPressable.tsx
│ └── Toast.tsx
├── InviteFriendScene.tsx
├── HelpScene.tsx
├── AppNavigator.tsx
├── FeedbackScene.tsx
├── HomeScene.tsx
└── DrawerContent.tsx
├── .yarnrc.yml
├── app.json
├── android
├── app
│ ├── debug.keystore
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── values
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ └── drawable
│ │ │ │ │ └── rn_edit_text_material.xml
│ │ │ ├── assets
│ │ │ │ └── fonts
│ │ │ │ │ ├── WorkSans-Bold.ttf
│ │ │ │ │ ├── WorkSans-Medium.ttf
│ │ │ │ │ ├── WorkSans-Regular.ttf
│ │ │ │ │ └── WorkSans-SemiBold.ttf
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── react_native_ui_templates
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ └── MainApplication.kt
│ │ │ └── AndroidManifest.xml
│ │ └── debug
│ │ │ └── AndroidManifest.xml
│ ├── proguard-rules.pro
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── settings.gradle
├── build.gradle
├── link-assets-manifest.json
├── gradle.properties
└── gradlew.bat
├── ios
├── react_native_UI_Templates
│ ├── Images.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── PrivacyInfo.xcprivacy
│ ├── Info.plist
│ └── LaunchScreen.storyboard
├── react_native_UI_Templates.xcworkspace
│ └── contents.xcworkspacedata
├── .xcode.env
├── link-assets-manifest.json
├── Podfile
└── react_native_UI_Templates.xcodeproj
│ └── xcshareddata
│ └── xcschemes
│ └── react_native_UI_Templates.xcscheme
├── babel.config.js
├── .github
├── FUNDING.yml
└── workflows
│ ├── build-android.yml
│ └── build-ios-simulator.yml
├── .prettierrc.js
├── index.js
├── App.tsx
├── __tests__
└── App.test.tsx
├── .eslintrc.js
├── Gemfile
├── metro.config.js
├── LICENSE
├── .gitignore
├── package.json
├── README.md
└── Gemfile.lock
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'react-native',
3 | };
4 |
--------------------------------------------------------------------------------
/.bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/react-native.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | assets: ['./src/assets/fonts'],
3 | };
4 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@react-native/typescript-config/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/hotel_booking/index.ts:
--------------------------------------------------------------------------------
1 | export { default as HotelHomeScreen } from './HotelHomeScreen';
2 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | compressionLevel: mixed
2 |
3 | enableGlobalCache: false
4 |
5 | nodeLinker: node-modules
6 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react_native_ui_templates",
3 | "displayName": "react_native_ui_templates"
4 | }
5 |
--------------------------------------------------------------------------------
/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/debug.keystore
--------------------------------------------------------------------------------
/src/introduction_animation/index.ts:
--------------------------------------------------------------------------------
1 | export { default as IntroductionAnimationScreen } from './IntroductionAnimationScreen';
2 |
--------------------------------------------------------------------------------
/src/assets/home/helpImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/home/helpImage.png
--------------------------------------------------------------------------------
/src/assets/home/userImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/home/userImage.png
--------------------------------------------------------------------------------
/src/assets/hotel/hotel_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/hotel/hotel_1.png
--------------------------------------------------------------------------------
/src/assets/hotel/hotel_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/hotel/hotel_2.png
--------------------------------------------------------------------------------
/src/assets/hotel/hotel_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/hotel/hotel_3.png
--------------------------------------------------------------------------------
/src/assets/hotel/hotel_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/hotel/hotel_4.png
--------------------------------------------------------------------------------
/src/assets/hotel/hotel_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/hotel/hotel_5.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/area1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/area1.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/area2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/area2.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/area3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/area3.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/back.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/bell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/bell.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/eaten.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/eaten.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/glass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/glass.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/lunch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/lunch.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/snack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/snack.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/tab_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/tab_1.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/tab_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/tab_2.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/tab_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/tab_3.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/tab_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/tab_4.png
--------------------------------------------------------------------------------
/src/assets/home/inviteImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/home/inviteImage.png
--------------------------------------------------------------------------------
/src/assets/home/supportIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/home/supportIcon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | react_native_ui_templates
3 |
4 |
--------------------------------------------------------------------------------
/src/assets/fitness_app/bottle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/bottle.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/burned.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/burned.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/dinner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/dinner.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/runner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/runner.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/tab_1s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/tab_1s.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/tab_2s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/tab_2s.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/tab_3s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/tab_3s.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/tab_4s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/tab_4s.png
--------------------------------------------------------------------------------
/src/assets/fonts/WorkSans-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fonts/WorkSans-Bold.ttf
--------------------------------------------------------------------------------
/src/assets/home/custom_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/home/custom_drawer.png
--------------------------------------------------------------------------------
/src/assets/home/feedbackImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/home/feedbackImage.png
--------------------------------------------------------------------------------
/src/assets/hotel/hotel_booking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/hotel/hotel_booking.png
--------------------------------------------------------------------------------
/ios/react_native_UI_Templates/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/assets/fitness_app/breakfast.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/breakfast.png
--------------------------------------------------------------------------------
/src/assets/fonts/WorkSans-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fonts/WorkSans-Medium.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/WorkSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fonts/WorkSans-Regular.ttf
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | plugins: ['react-native-reanimated/plugin'],
4 | };
5 |
--------------------------------------------------------------------------------
/src/assets/design_course/interFace1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/design_course/interFace1.png
--------------------------------------------------------------------------------
/src/assets/design_course/interFace2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/design_course/interFace2.png
--------------------------------------------------------------------------------
/src/assets/design_course/interFace3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/design_course/interFace3.png
--------------------------------------------------------------------------------
/src/assets/design_course/interFace4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/design_course/interFace4.png
--------------------------------------------------------------------------------
/src/assets/design_course/userImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/design_course/userImage.png
--------------------------------------------------------------------------------
/src/assets/fitness_app/fitness_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fitness_app/fitness_app.png
--------------------------------------------------------------------------------
/src/assets/fonts/WorkSans-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/fonts/WorkSans-SemiBold.ttf
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/src/assets/design_course/design_course.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/design_course/design_course.png
--------------------------------------------------------------------------------
/src/assets/design_course/webInterFace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/design_course/webInterFace.png
--------------------------------------------------------------------------------
/src/assets/introduction_animation/welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/introduction_animation/welcome.png
--------------------------------------------------------------------------------
/src/design_course/index.ts:
--------------------------------------------------------------------------------
1 | export { default as HomeDesignCourse } from './HomeDesignCourse';
2 | export { default as CourseInfoScreen } from './CourseInfoScreen';
3 |
--------------------------------------------------------------------------------
/src/Config.ts:
--------------------------------------------------------------------------------
1 | import { Platform } from 'react-native';
2 |
3 | export default {
4 | isAndroid: Platform.OS === 'android',
5 | isIos: Platform.OS === 'ios',
6 | };
7 |
--------------------------------------------------------------------------------
/src/assets/introduction_animation/care_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/introduction_animation/care_image.png
--------------------------------------------------------------------------------
/src/assets/introduction_animation/relax_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/introduction_animation/relax_image.png
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/WorkSans-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/assets/fonts/WorkSans-Bold.ttf
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/WorkSans-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/assets/fonts/WorkSans-Medium.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/WorkSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/assets/fonts/WorkSans-Regular.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/WorkSans-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/assets/fonts/WorkSans-SemiBold.ttf
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src/assets/introduction_animation/mood_dairy_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/introduction_animation/mood_dairy_image.png
--------------------------------------------------------------------------------
/src/assets/introduction_animation/introduction_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/introduction_animation/introduction_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src/assets/introduction_animation/introduction_animation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/src/assets/introduction_animation/introduction_animation.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Aashu-Dubey/React-Native-UI-Templates/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [Aashu-Dubey]
4 | patreon: ashud
5 | buy_me_a_coffee: ashud
6 | custom: [aashud.gumroad.com/l/react-native-samples]
7 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: false,
4 | bracketSpacing: true,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | endOfLine: 'auto',
8 | };
9 |
--------------------------------------------------------------------------------
/src/util/action.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export const toastRef = React.createRef();
4 |
5 | export const showToast = (text: string) => {
6 | toastRef.current?.show(text);
7 | };
8 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'react-native-gesture-handler';
6 | import { AppRegistry } from 'react-native';
7 | import App from './App';
8 | import { name as appName } from './app.json';
9 |
10 | AppRegistry.registerComponent(appName, () => App);
11 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/App.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample React Native App
3 | * https://github.com/facebook/react-native
4 | *
5 | * @format
6 | */
7 |
8 | import React from 'react';
9 | import AppControlFlow from './src/AppControlFlow';
10 |
11 | const App = () => {
12 | return ;
13 | };
14 |
15 | export default App;
16 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default as DrawerContent } from './DrawerContent';
2 |
3 | export { default as HomeScene } from './HomeScene';
4 | export { default as HelpScene } from './HelpScene';
5 | export { default as FeedbackScene } from './FeedbackScene';
6 | export { default as InviteFriendScene } from './InviteFriendScene';
7 |
--------------------------------------------------------------------------------
/__tests__/App.test.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import React from 'react';
6 | import ReactTestRenderer from 'react-test-renderer';
7 | import App from '../App';
8 |
9 | test('renders correctly', async () => {
10 | await ReactTestRenderer.act(() => {
11 | ReactTestRenderer.create();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native',
4 | plugins: ['react-hooks'],
5 | rules: {
6 | 'react-native/no-inline-styles': 'off',
7 | 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
8 | 'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/ios/react_native_UI_Templates.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
2 | plugins { id("com.facebook.react.settings") }
3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
4 | rootProject.name = 'react_native_ui_templates'
5 | include ':app'
6 | includeBuild('../node_modules/@react-native/gradle-plugin')
7 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby ">= 2.6.10"
5 |
6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures.
7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9 | gem 'xcodeproj', '< 1.26.0'
10 | gem 'concurrent-ruby', '< 1.3.4'
11 |
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/index.ts:
--------------------------------------------------------------------------------
1 | export { default as SplashView } from './SplashView';
2 | export { default as RelaxView } from './RelaxView';
3 | export { default as CareView } from './CareView';
4 | export { default as MoodDiaryView } from './MoodDiaryView';
5 | export { default as WelcomeView } from './WelcomeView';
6 | export { default as TopBackSkipView } from './TopBackSkipView';
7 | export { default as CenterNextButton } from './CenterNextButton';
8 |
--------------------------------------------------------------------------------
/metro.config.js:
--------------------------------------------------------------------------------
1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
2 | const { wrapWithReanimatedMetroConfig } = require('react-native-reanimated/metro-config');
3 |
4 | /**
5 | * Metro configuration
6 | * https://reactnative.dev/docs/metro
7 | *
8 | * @type {import('@react-native/metro-config').MetroConfig}
9 | */
10 | const config = {};
11 |
12 | module.exports = wrapWithReanimatedMetroConfig(mergeConfig(getDefaultConfig(__dirname), config));
13 |
--------------------------------------------------------------------------------
/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/src/AppControlFlow.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { NavigationContainer } from '@react-navigation/native';
3 | import { SafeAreaProvider } from 'react-native-safe-area-context';
4 | import AppNavigator from './AppNavigator';
5 | import Toast from './components/Toast';
6 | import { toastRef } from './util/action';
7 |
8 | const AppControlFlow: React.FC = () => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 | );
17 | };
18 |
19 | export default AppControlFlow;
20 |
--------------------------------------------------------------------------------
/ios/link-assets-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "migIndex": 1,
3 | "data": [
4 | {
5 | "path": "src/assets/fonts/WorkSans-Bold.ttf",
6 | "sha1": "8aa832d11d326a9638d73123f13a291f9d17cbc2"
7 | },
8 | {
9 | "path": "src/assets/fonts/WorkSans-Medium.ttf",
10 | "sha1": "8157befeb8f303271b9c754f55d9bee89d4caac7"
11 | },
12 | {
13 | "path": "src/assets/fonts/WorkSans-Regular.ttf",
14 | "sha1": "dde5c5441ea6350524d0e0eb7058c8e672359279"
15 | },
16 | {
17 | "path": "src/assets/fonts/WorkSans-SemiBold.ttf",
18 | "sha1": "08d3f4f2abb01cbe8252dba795e27416a05704d6"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext {
3 | buildToolsVersion = "35.0.0"
4 | minSdkVersion = 24
5 | compileSdkVersion = 35
6 | targetSdkVersion = 35
7 | ndkVersion = "27.1.12297006"
8 | kotlinVersion = "2.0.21"
9 | }
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | dependencies {
15 | classpath("com.android.tools.build:gradle")
16 | classpath("com.facebook.react:react-native-gradle-plugin")
17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
18 | }
19 | }
20 |
21 | apply plugin: "com.facebook.react.rootproject"
22 |
--------------------------------------------------------------------------------
/android/link-assets-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "migIndex": 1,
3 | "data": [
4 | {
5 | "path": "src/assets/fonts/WorkSans-Bold.ttf",
6 | "sha1": "8aa832d11d326a9638d73123f13a291f9d17cbc2"
7 | },
8 | {
9 | "path": "src/assets/fonts/WorkSans-Medium.ttf",
10 | "sha1": "8157befeb8f303271b9c754f55d9bee89d4caac7"
11 | },
12 | {
13 | "path": "src/assets/fonts/WorkSans-Regular.ttf",
14 | "sha1": "dde5c5441ea6350524d0e0eb7058c8e672359279"
15 | },
16 | {
17 | "path": "src/assets/fonts/WorkSans-SemiBold.ttf",
18 | "sha1": "08d3f4f2abb01cbe8252dba795e27416a05704d6"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | -keep class com.facebook.hermes.unicode.** { *; }
13 | -keep class com.facebook.jni.** { *; }
14 |
15 | -keep class com.swmansion.reanimated.** { *; }
16 | -keep class com.facebook.react.turbomodule.** { *; }
17 |
--------------------------------------------------------------------------------
/src/design_course/README.md:
--------------------------------------------------------------------------------
1 | # Design Course Template
2 |
3 |
4 |
5 |
6 |
7 | A design course UI template showing the list of courses related to UI designs, with some interactive animations.
8 |
9 | ## 📦 Packages used
10 |
11 | 1. [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons):- Google Material icons.
12 | 2. [react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context):- Handle UI for iOS safe area.
13 |
14 | ## 🔗 Links
15 |
16 | - **Demo: [twitter](https://twitter.com/aashudubey_ad/status/1578846092694720512) \| [youtube](https://youtube.com/shorts/5G0obPHAdyc)**
17 |
--------------------------------------------------------------------------------
/src/components/MyPressable.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Pressable, StyleProp, ViewStyle, PressableProps } from 'react-native';
3 | import Config from '../Config';
4 |
5 | interface Props extends PressableProps {
6 | style?: StyleProp;
7 | touchOpacity?: number;
8 | }
9 |
10 | const MyPressable: React.FC = ({
11 | style,
12 | android_ripple = { color: 'lightgrey' },
13 | touchOpacity = 0.4,
14 | children,
15 | ...restOfProps
16 | }) => {
17 | return (
18 | [
20 | style,
21 | { opacity: !Config.isAndroid && pressed ? touchOpacity : 1 },
22 | ]}
23 | android_ripple={android_ripple}
24 | {...restOfProps}
25 | >
26 | {children}
27 |
28 | );
29 | };
30 |
31 | export default MyPressable;
32 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/react_native_ui_templates/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.react_native_ui_templates
2 |
3 | import com.facebook.react.ReactActivity
4 | import com.facebook.react.ReactActivityDelegate
5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
6 | import com.facebook.react.defaults.DefaultReactActivityDelegate
7 |
8 | class MainActivity : ReactActivity() {
9 |
10 | /**
11 | * Returns the name of the main component registered from JavaScript. This is used to schedule
12 | * rendering of the component.
13 | */
14 | override fun getMainComponentName(): String = "react_native_ui_templates"
15 |
16 | /**
17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
19 | */
20 | override fun createReactActivityDelegate(): ReactActivityDelegate =
21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
22 | }
23 |
--------------------------------------------------------------------------------
/src/introduction_animation/README.md:
--------------------------------------------------------------------------------
1 | # Animated Onboarding Template
2 |
3 |
4 |
5 |
6 |
7 | An onboarding UI template with smooth animations, for a Mental Wellness App.
8 |
9 | ## 📦 Packages used
10 |
11 | 1. [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons):- Google Material icons.
12 | 2. [react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context):- Handle UI for iOS safe area.
13 |
14 | ## 🌻 Motivation
15 |
16 | Original UI design for this template on [Behance]().
17 |
18 | ## 🔗 Links
19 |
20 | - [UI on Behance]()
21 | - **Demo: [twitter](https://twitter.com/aashudubey_ad/status/1580260456215695360) \| [youtube](https://youtube.com/shorts/AOD9FyiSR3U)**
22 |
--------------------------------------------------------------------------------
/ios/react_native_UI_Templates/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import React
3 | import React_RCTAppDelegate
4 | import ReactAppDependencyProvider
5 |
6 | @main
7 | class AppDelegate: RCTAppDelegate {
8 | override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
9 | self.moduleName = "react_native_ui_templates"
10 | self.dependencyProvider = RCTAppDependencyProvider()
11 |
12 | // You can add your custom initial props in the dictionary below.
13 | // They will be passed down to the ViewController used by React Native.
14 | self.initialProps = [:]
15 |
16 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
17 | }
18 |
19 | override func sourceURL(for bridge: RCTBridge) -> URL? {
20 | self.bundleURL()
21 | }
22 |
23 | override func bundleURL() -> URL? {
24 | #if DEBUG
25 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
26 | #else
27 | Bundle.main.url(forResource: "main", withExtension: "jsbundle")
28 | #endif
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Ashutosh Dubey
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ios/react_native_UI_Templates/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ios/react_native_UI_Templates/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategoryFileTimestamp
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | C617.1
13 |
14 |
15 |
16 | NSPrivacyAccessedAPIType
17 | NSPrivacyAccessedAPICategoryUserDefaults
18 | NSPrivacyAccessedAPITypeReasons
19 |
20 | CA92.1
21 |
22 |
23 |
24 | NSPrivacyAccessedAPIType
25 | NSPrivacyAccessedAPICategorySystemBootTime
26 | NSPrivacyAccessedAPITypeReasons
27 |
28 | 35F9.1
29 |
30 |
31 |
32 | NSPrivacyCollectedDataTypes
33 |
34 | NSPrivacyTracking
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Resolve react_native_pods.rb with node to allow for hoisting
2 | require Pod::Executable.execute_command('node', ['-p',
3 | 'require.resolve(
4 | "react-native/scripts/react_native_pods.rb",
5 | {paths: [process.argv[1]]},
6 | )', __dir__]).strip
7 |
8 | platform :ios, min_ios_version_supported
9 | prepare_react_native_project!
10 |
11 | linkage = ENV['USE_FRAMEWORKS']
12 | if linkage != nil
13 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
14 | use_frameworks! :linkage => linkage.to_sym
15 | end
16 |
17 | target 'react_native_ui_templates' do
18 | config = use_native_modules!
19 |
20 | use_react_native!(
21 | :path => config[:reactNativePath],
22 | # An absolute path to your application root.
23 | :app_path => "#{Pod::Config.instance.installation_root}/.."
24 | )
25 |
26 | post_install do |installer|
27 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
28 | react_native_post_install(
29 | installer,
30 | config[:reactNativePath],
31 | :mac_catalyst_enabled => false,
32 | # :ccache_enabled => true
33 | )
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/src/hotel_booking/README.md:
--------------------------------------------------------------------------------
1 | # Hotel Booking Template
2 |
3 |
4 |
5 |
6 |
7 |
8 | A hotel booking UI template showing the list of hotels nearby with their ratings and other details, filter UI and custom interactive calendar view etc.
9 |
10 | ## 📦 Packages used
11 |
12 | 1. [@aashu-dubey/react-native-rating-bar](https://github.com/Aashu-Dubey/react-native-rating-bar):- Rating view for hotel list item.
13 | 2. [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons):- Google Material icons
14 | 3. [@ptomasroos/react-native-multi-slider](https://github.com/ptomasroos/react-native-multi-slider):- Multi slider for hotel price range in the filters.
15 | 4. [@miblanchard/react-native-slider](https://github.com/miblanchard/react-native-slider):- Slider for hotel distance in the filters.
16 | 5. [@react-native-community/blur](https://github.com/react-native-community/react-native-blur):- Blur background for Calendar modal.
17 | 6. [react-native-safe-area-context](https://github.com/th3rdwave/react-native-safe-area-context):- Handle UI for iOS safe area.
18 |
19 | ## 🔗 Links
20 |
21 | - **Demo: [twitter](https://twitter.com/aashudubey_ad/status/1576292697173766145) \| [youtube](https://youtube.com/shorts/ioFcve0rYnc)**
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | **/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 | .kotlin/
37 |
38 | # node.js
39 | #
40 | node_modules/
41 | npm-debug.log
42 | yarn-error.log
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | **/fastlane/report.xml
52 | **/fastlane/Preview.html
53 | **/fastlane/screenshots
54 | **/fastlane/test_output
55 |
56 | # Bundle artifact
57 | *.jsbundle
58 |
59 | # Ruby / CocoaPods
60 | **/Pods/
61 | /vendor/bundle/
62 |
63 | # Temporary files created by Metro to check the health of the file watcher
64 | .metro-health-check*
65 |
66 | # testing
67 | /coverage
68 |
69 | # Yarn
70 | .yarn/*
71 | !.yarn/patches
72 | !.yarn/plugins
73 | !.yarn/releases
74 | !.yarn/sdks
75 | !.yarn/versions
76 |
--------------------------------------------------------------------------------
/src/hotel_booking/SliderView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { StyleSheet, Text } from 'react-native';
3 | import { Slider } from '@miblanchard/react-native-slider';
4 |
5 | const SliderView: React.FC = () => {
6 | const [distValue, setDistValue] = useState(50.0);
7 |
8 | return (
9 | (
23 |
24 | Less than {(distValue / 10).toFixed(1)} km
25 |
26 | )}
27 | onValueChange={value => setDistValue(value[0])}
28 | />
29 | );
30 | };
31 |
32 | const styles = StyleSheet.create({
33 | thumbStyle: {
34 | height: 24,
35 | width: 24,
36 | borderRadius: 12,
37 | borderWidth: 2,
38 | borderColor: 'white',
39 | elevation: 8,
40 | shadowColor: 'black',
41 | shadowOffset: { width: 0, height: 0 },
42 | shadowOpacity: 0.5,
43 | shadowRadius: 7.49,
44 | },
45 | thumbText: {
46 | width: 170,
47 | color: 'black',
48 | textAlign: 'center',
49 | },
50 | });
51 |
52 | export default SliderView;
53 |
--------------------------------------------------------------------------------
/src/assets/index.ts:
--------------------------------------------------------------------------------
1 | const AppImages = {
2 | support_icon: require('./home/supportIcon.png'),
3 | userImage: require('./home/userImage.png'),
4 | feedbackImage: require('./home/feedbackImage.png'),
5 | helpImage: require('./home/helpImage.png'),
6 | inviteImage: require('./home/inviteImage.png'),
7 |
8 | // hotel
9 | hotel_booking: require('./hotel/hotel_booking.png'),
10 | hotel_1: require('./hotel/hotel_1.png'),
11 | hotel_2: require('./hotel/hotel_2.png'),
12 | hotel_3: require('./hotel/hotel_3.png'),
13 | hotel_4: require('./hotel/hotel_4.png'),
14 | hotel_5: require('./hotel/hotel_5.png'),
15 |
16 | // fitness_app
17 | fitness_app: require('./fitness_app/fitness_app.png'),
18 |
19 | // design_course
20 | design_course: require('./design_course/design_course.png'),
21 | design_header_image: require('./design_course/userImage.png'),
22 | interFace1: require('./design_course/interFace1.png'),
23 | interFace2: require('./design_course/interFace2.png'),
24 | interFace3: require('./design_course/interFace3.png'),
25 | interFace4: require('./design_course/interFace4.png'),
26 | webInterFace: require('./design_course/webInterFace.png'),
27 |
28 | // Animation OnBoarding App
29 | introduction_animation: require('./introduction_animation/introduction_animation.png'),
30 | introduction_image: require('./introduction_animation/introduction_image.png'),
31 | relax_image: require('./introduction_animation/relax_image.png'),
32 | care_image: require('./introduction_animation/care_image.png'),
33 | mood_dairy_image: require('./introduction_animation/mood_dairy_image.png'),
34 | welcome: require('./introduction_animation/welcome.png'),
35 | };
36 |
37 | export { AppImages };
38 |
--------------------------------------------------------------------------------
/src/hotel_booking/model/hotel_list_data.ts:
--------------------------------------------------------------------------------
1 | import { AppImages } from '../../assets';
2 |
3 | export interface HotelListType {
4 | id: number;
5 | imagePath: any;
6 | titleTxt: string;
7 | subTxt: string;
8 | dist: number;
9 | reviews: number;
10 | rating: number;
11 | perNight: number;
12 | }
13 |
14 | export const HOTEL_LIST: HotelListType[] = [
15 | // 1st item dummy for 'stickyHeaderIndices'
16 | {
17 | id: 0,
18 | imagePath: '',
19 | titleTxt: '',
20 | subTxt: '',
21 | dist: 0,
22 | reviews: 0,
23 | rating: 0,
24 | perNight: 0,
25 | },
26 | {
27 | id: 1,
28 | imagePath: AppImages.hotel_1,
29 | titleTxt: 'Grand Royal Hotel',
30 | subTxt: 'Wembley, London',
31 | dist: 2.0,
32 | reviews: 80,
33 | rating: 4.4,
34 | perNight: 180,
35 | },
36 | {
37 | id: 2,
38 | imagePath: AppImages.hotel_2,
39 | titleTxt: 'Queen Hotel',
40 | subTxt: 'Wembley, London',
41 | dist: 4.0,
42 | reviews: 74,
43 | rating: 4.5,
44 | perNight: 200,
45 | },
46 | {
47 | id: 3,
48 | imagePath: AppImages.hotel_3,
49 | titleTxt: 'Grand Royal Hotel',
50 | subTxt: 'Wembley, London',
51 | dist: 3.0,
52 | reviews: 62,
53 | rating: 4.0,
54 | perNight: 60,
55 | },
56 | {
57 | id: 4,
58 | imagePath: AppImages.hotel_4,
59 | titleTxt: 'Queen Hotel',
60 | subTxt: 'Wembley, London',
61 | dist: 7.0,
62 | reviews: 90,
63 | rating: 4.4,
64 | perNight: 170,
65 | },
66 | {
67 | id: 5,
68 | imagePath: AppImages.hotel_5,
69 | titleTxt: 'Grand Royal Hotel',
70 | subTxt: 'Wembley, London',
71 | dist: 2.0,
72 | reviews: 240,
73 | rating: 4.5,
74 | perNight: 200,
75 | },
76 | ];
77 |
--------------------------------------------------------------------------------
/src/design_course/model/category.ts:
--------------------------------------------------------------------------------
1 | import { AppImages } from '../../assets';
2 |
3 | export interface CategoryType {
4 | id: number;
5 | imagePath: any;
6 | title: string;
7 | lessonCount: number;
8 | money: number;
9 | rating: number;
10 | }
11 |
12 | export const CATEGORY_LIST: CategoryType[] = [
13 | {
14 | id: 0,
15 | imagePath: AppImages.interFace1,
16 | title: 'User interface Design',
17 | lessonCount: 24,
18 | money: 25,
19 | rating: 4.3,
20 | },
21 | {
22 | id: 1,
23 | imagePath: AppImages.interFace2,
24 | title: 'User interface Design',
25 | lessonCount: 22,
26 | money: 18,
27 | rating: 4.6,
28 | },
29 | {
30 | id: 2,
31 | imagePath: AppImages.interFace1,
32 | title: 'User interface Design',
33 | lessonCount: 24,
34 | money: 25,
35 | rating: 4.3,
36 | },
37 | {
38 | id: 3,
39 | imagePath: AppImages.interFace2,
40 | title: 'User interface Design',
41 | lessonCount: 22,
42 | money: 18,
43 | rating: 4.6,
44 | },
45 | ];
46 |
47 | export const POPULAR_COURSE_LIST: CategoryType[] = [
48 | {
49 | id: 0,
50 | imagePath: AppImages.interFace3,
51 | title: 'App Design Course',
52 | lessonCount: 12,
53 | money: 25,
54 | rating: 4.8,
55 | },
56 | {
57 | id: 1,
58 | imagePath: AppImages.interFace4,
59 | title: 'Web Design Course',
60 | lessonCount: 28,
61 | money: 208,
62 | rating: 4.9,
63 | },
64 | {
65 | id: 2,
66 | imagePath: AppImages.interFace3,
67 | title: 'App Design Course',
68 | lessonCount: 12,
69 | money: 25,
70 | rating: 4.8,
71 | },
72 | {
73 | id: 3,
74 | imagePath: AppImages.interFace4,
75 | title: 'Web Design Course',
76 | lessonCount: 28,
77 | money: 208,
78 | rating: 4.9,
79 | },
80 | ];
81 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 |
25 | # Use this property to specify which architecture you want to build.
26 | # You can also override it from the CLI using
27 | # ./gradlew -PreactNativeArchitectures=x86_64
28 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
29 |
30 | # Use this property to enable support to the new architecture.
31 | # This will allow you to use TurboModules and the Fabric render in
32 | # your application. You should enable this flag either if you want
33 | # to write custom TurboModules/Fabric components OR use libraries that
34 | # are providing them.
35 | newArchEnabled=true
36 |
37 | # Use this property to enable or disable the Hermes JS engine.
38 | # If set to false, you will be using JSC instead.
39 | hermesEnabled=true
40 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/react_native_ui_templates/MainApplication.kt:
--------------------------------------------------------------------------------
1 | package com.react_native_ui_templates
2 |
3 | import android.app.Application
4 | import com.facebook.react.PackageList
5 | import com.facebook.react.ReactApplication
6 | import com.facebook.react.ReactHost
7 | import com.facebook.react.ReactNativeHost
8 | import com.facebook.react.ReactPackage
9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
11 | import com.facebook.react.defaults.DefaultReactNativeHost
12 | import com.facebook.react.soloader.OpenSourceMergedSoMapping
13 | import com.facebook.soloader.SoLoader
14 |
15 | class MainApplication : Application(), ReactApplication {
16 |
17 | override val reactNativeHost: ReactNativeHost =
18 | object : DefaultReactNativeHost(this) {
19 | override fun getPackages(): List =
20 | PackageList(this).packages.apply {
21 | // Packages that cannot be autolinked yet can be added manually here, for example:
22 | // add(MyReactNativePackage())
23 | }
24 |
25 | override fun getJSMainModuleName(): String = "index"
26 |
27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
28 |
29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
31 | }
32 |
33 | override val reactHost: ReactHost
34 | get() = getDefaultReactHost(applicationContext, reactNativeHost)
35 |
36 | override fun onCreate() {
37 | super.onCreate()
38 | SoLoader.init(this, OpenSourceMergedSoMapping)
39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
40 | // If you opted-in for the New Architecture, we load the native entry point for this app.
41 | load()
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react_native_ui_templates",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "android": "react-native run-android",
7 | "ios": "react-native run-ios",
8 | "lint": "eslint .",
9 | "start": "react-native start",
10 | "test": "jest"
11 | },
12 | "dependencies": {
13 | "@aashu-dubey/react-native-rating-bar": "^0.3.6",
14 | "@miblanchard/react-native-slider": "^2.6.0",
15 | "@ptomasroos/react-native-multi-slider": "^2.2.2",
16 | "@react-native-community/blur": "^4.4.1",
17 | "@react-navigation/drawer": "^7.1.2",
18 | "@react-navigation/native": "^7.0.15",
19 | "@react-navigation/stack": "^7.1.2",
20 | "react": "19.0.0",
21 | "react-native": "0.78.0",
22 | "react-native-gesture-handler": "^2.24.0",
23 | "react-native-reanimated": "^3.17.1",
24 | "react-native-safe-area-context": "^5.3.0",
25 | "react-native-screens": "^4.9.1",
26 | "react-native-vector-icons": "^10.2.0"
27 | },
28 | "devDependencies": {
29 | "@babel/core": "^7.25.2",
30 | "@babel/preset-env": "^7.25.3",
31 | "@babel/runtime": "^7.25.0",
32 | "@react-native-community/cli": "15.0.1",
33 | "@react-native-community/cli-platform-android": "15.0.1",
34 | "@react-native-community/cli-platform-ios": "15.0.1",
35 | "@react-native/babel-preset": "0.78.0",
36 | "@react-native/eslint-config": "0.78.0",
37 | "@react-native/metro-config": "0.78.0",
38 | "@react-native/typescript-config": "0.78.0",
39 | "@types/jest": "^29.5.13",
40 | "@types/react": "^19.0.0",
41 | "@types/react-native-vector-icons": "^6.4.18",
42 | "@types/react-test-renderer": "^19.0.0",
43 | "eslint": "^8.19.0",
44 | "jest": "^29.6.3",
45 | "prettier": "2.8.8",
46 | "react-test-renderer": "19.0.0",
47 | "typescript": "5.0.4"
48 | },
49 | "engines": {
50 | "node": ">=18"
51 | },
52 | "packageManager": "yarn@4.2.2"
53 | }
54 |
--------------------------------------------------------------------------------
/ios/react_native_UI_Templates/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | react_native_ui_templates
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(CURRENT_PROJECT_VERSION)
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSAllowsArbitraryLoads
30 |
31 | NSAllowsLocalNetworking
32 |
33 |
34 | NSLocationWhenInUseUsageDescription
35 |
36 | UIAppFonts
37 |
38 | WorkSans-Bold.ttf
39 | WorkSans-Medium.ttf
40 | WorkSans-Regular.ttf
41 | WorkSans-SemiBold.ttf
42 | MaterialIcons.ttf
43 |
44 | UILaunchStoryboardName
45 | LaunchScreen
46 | UIRequiredDeviceCapabilities
47 |
48 | arm64
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UIViewControllerBasedStatusBarAppearance
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/.github/workflows/build-android.yml:
--------------------------------------------------------------------------------
1 | name: Build an Android APK
2 |
3 | on:
4 | push:
5 | paths:
6 | - '*'
7 | - '.github/workflows/build-android.yml'
8 | - 'android/**'
9 | - 'src/**'
10 | - '!**/*.md'
11 | branches:
12 | - main
13 |
14 | jobs:
15 | build-apk:
16 | permissions:
17 | contents: write
18 | name: Build Android APK
19 | runs-on: ubuntu-latest
20 |
21 | steps:
22 | - uses: actions/checkout@v4
23 |
24 | # 'corepack enable' is needed for now till it's experimental, may remove the command once it becomes stable in later node releases
25 | - name: Enable Corepack
26 | run: corepack enable
27 |
28 | # Setup Web environment to install packages.
29 | - name: Setup Web environment
30 | uses: actions/setup-node@v4
31 | with:
32 | node-version: '22'
33 | cache: 'yarn'
34 |
35 | # Setup Java environment in order to build the Android app.
36 | - name: Setup Java environment
37 | uses: actions/setup-java@v4
38 | with:
39 | distribution: 'zulu'
40 | java-version: '17'
41 |
42 | # Setup gradle using official gradle action
43 | - name: Setup Gradle
44 | uses: gradle/actions/setup-gradle@v4
45 | with:
46 | add-job-summary: 'on-failure'
47 |
48 | - name: Restore node_modules from cache
49 | uses: actions/cache@v4
50 | with:
51 | path: node_modules
52 | key: ${{ runner.os }}-node-modules-${{ hashFiles('yarn.lock') }}
53 | restore-keys: ${{ runner.os }}-node-modules-
54 |
55 | # Here '--immutable' will only use commited 'yarn.lock', and will throw error if some update is needed
56 | - name: Install node_modules
57 | run: yarn install --immutable
58 |
59 | # In some cases, Gradle is not executable by default, so we do this before the build process
60 | - name: Make gradlew executable
61 | working-directory: android
62 | run: chmod +x ./gradlew
63 |
64 | - name: Build Android release APK
65 | working-directory: android
66 | run: ./gradlew assembleRelease --no-daemon
67 |
68 | - name: Save apk file as artifact
69 | uses: actions/upload-artifact@v4
70 | with:
71 | name: rn-ui-templates
72 | path: android/app/build/outputs/apk/release/app-release.apk
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/WelcomeView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react';
2 | import { StyleSheet, Text, Animated, useWindowDimensions } from 'react-native';
3 | import { AppImages } from '../../assets';
4 |
5 | interface Props {
6 | animationController: React.RefObject;
7 | }
8 |
9 | const IMAGE_WIDTH = 350;
10 | const IMAGE_HEIGHT = 350;
11 |
12 | const WelcomeView: React.FC = ({ animationController }) => {
13 | const window = useWindowDimensions();
14 |
15 | const careRef = useRef(null);
16 |
17 | const slideAnim = animationController.current.interpolate({
18 | inputRange: [0, 0.6, 0.8],
19 | outputRange: [window.width, window.width, 0],
20 | });
21 |
22 | const textEndVal = 26 * 2; // 26 being text's height (font size)
23 | const welcomeTextAnim = animationController.current.interpolate({
24 | inputRange: [0, 0.6, 0.8],
25 | outputRange: [textEndVal, textEndVal, 0],
26 | });
27 |
28 | const imageEndVal = IMAGE_WIDTH * 4;
29 | const imageAnim = animationController.current.interpolate({
30 | inputRange: [0, 0.6, 0.8],
31 | outputRange: [imageEndVal, imageEndVal, 0],
32 | });
33 |
34 | return (
35 |
38 |
42 |
46 | Welcome
47 |
48 |
49 | Stay organised and live stress-free with you-do app
50 |
51 |
52 | );
53 | };
54 |
55 | const styles = StyleSheet.create({
56 | container: {
57 | position: 'absolute',
58 | left: 0,
59 | right: 0,
60 | alignItems: 'center',
61 | paddingBottom: 100,
62 | },
63 | image: {
64 | maxWidth: IMAGE_WIDTH,
65 | maxHeight: IMAGE_HEIGHT,
66 | },
67 | title: {
68 | color: 'black',
69 | fontSize: 26,
70 | textAlign: 'center',
71 | fontFamily: 'WorkSans-Bold',
72 | },
73 | subtitle: {
74 | color: 'black',
75 | textAlign: 'center',
76 | fontFamily: 'WorkSans-Regular',
77 | paddingHorizontal: 64,
78 | paddingVertical: 16,
79 | },
80 | });
81 |
82 | export default WelcomeView;
83 |
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/MoodDiaryView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react';
2 | import { StyleSheet, Text, Animated, useWindowDimensions } from 'react-native';
3 | import { AppImages } from '../../assets';
4 |
5 | interface Props {
6 | animationController: React.RefObject;
7 | }
8 |
9 | const IMAGE_WIDTH = 350;
10 | const IMAGE_HEIGHT = 250;
11 |
12 | const MoodDiaryView: React.FC = ({ animationController }) => {
13 | const window = useWindowDimensions();
14 |
15 | const careRef = useRef(null);
16 |
17 | const slideAnim = animationController.current.interpolate({
18 | inputRange: [0, 0.4, 0.6, 0.8],
19 | outputRange: [window.width, window.width, 0, -window.width],
20 | });
21 |
22 | const textEndVal = window.width * 2; // 26 being text's height (font size)
23 | const textAnim = animationController.current.interpolate({
24 | inputRange: [0, 0.4, 0.6, 0.8],
25 | outputRange: [textEndVal, textEndVal, 0, -textEndVal],
26 | });
27 |
28 | const imageEndVal = IMAGE_WIDTH * 4;
29 | const imageAnim = animationController.current.interpolate({
30 | inputRange: [0, 0.4, 0.6, 0.8],
31 | outputRange: [imageEndVal, imageEndVal, 0, -imageEndVal],
32 | });
33 |
34 | return (
35 |
38 |
39 | Mood Dairy
40 |
41 |
44 | Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod
45 | tempor incididunt ut labore
46 |
47 |
51 |
52 | );
53 | };
54 |
55 | const styles = StyleSheet.create({
56 | container: {
57 | position: 'absolute',
58 | left: 0,
59 | right: 0,
60 | alignItems: 'center',
61 | paddingBottom: 100,
62 | },
63 | title: {
64 | color: 'black',
65 | fontSize: 26,
66 | textAlign: 'center',
67 | fontFamily: 'WorkSans-Bold',
68 | },
69 | subtitle: {
70 | color: 'black',
71 | textAlign: 'center',
72 | fontFamily: 'WorkSans-Regular',
73 | paddingHorizontal: 64,
74 | paddingVertical: 16,
75 | },
76 | image: {
77 | maxWidth: IMAGE_WIDTH,
78 | maxHeight: IMAGE_HEIGHT,
79 | },
80 | });
81 |
82 | export default MoodDiaryView;
83 |
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/RelaxView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react';
2 | import { StyleSheet, Text, Animated, useWindowDimensions } from 'react-native';
3 | import { AppImages } from '../../assets';
4 |
5 | interface Props {
6 | animationController: React.RefObject;
7 | }
8 |
9 | const IMAGE_WIDTH = 350;
10 | const IMAGE_HEIGHT = 250;
11 |
12 | const RelaxView: React.FC = ({ animationController }) => {
13 | const window = useWindowDimensions();
14 |
15 | const relaxRef = useRef(null);
16 |
17 | const relaxAnimation = animationController.current.interpolate({
18 | inputRange: [0, 0.2, 0.8],
19 | outputRange: [-(26 * 2), 0, 0],
20 | });
21 | const textAnim = animationController.current.interpolate({
22 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
23 | outputRange: [0, 0, -window.width * 2, 0, 0],
24 | });
25 | const imageAnim = animationController.current.interpolate({
26 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
27 | outputRange: [0, 0, -350 * 4, 0, 0],
28 | });
29 | const slideAnim = animationController.current.interpolate({
30 | inputRange: [0, 0.2, 0.4, 0.8],
31 | outputRange: [0, 0, -window.width, -window.width],
32 | });
33 |
34 | return (
35 |
38 |
42 | Relax
43 |
44 |
47 | Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod
48 | tempor incididunt ut labore
49 |
50 |
54 |
55 | );
56 | };
57 |
58 | const styles = StyleSheet.create({
59 | container: {
60 | alignItems: 'center',
61 | paddingBottom: 100,
62 | },
63 | title: {
64 | color: 'black',
65 | fontSize: 26,
66 | textAlign: 'center',
67 | fontFamily: 'WorkSans-Bold',
68 | },
69 | subtitle: {
70 | color: 'black',
71 | textAlign: 'center',
72 | fontFamily: 'WorkSans-Regular',
73 | paddingHorizontal: 64,
74 | paddingVertical: 16,
75 | },
76 | image: {
77 | maxWidth: IMAGE_WIDTH,
78 | maxHeight: IMAGE_HEIGHT,
79 | },
80 | });
81 |
82 | export default RelaxView;
83 |
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/CareView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react';
2 | import { StyleSheet, Text, Animated, useWindowDimensions } from 'react-native';
3 | import { AppImages } from '../../assets';
4 |
5 | interface Props {
6 | animationController: React.RefObject;
7 | }
8 |
9 | const IMAGE_WIDTH = 350;
10 | const IMAGE_HEIGHT = 250;
11 |
12 | const CareView: React.FC = ({ animationController }) => {
13 | const window = useWindowDimensions();
14 |
15 | const careRef = useRef(null);
16 |
17 | const slideAnim = animationController.current.interpolate({
18 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
19 | outputRange: [window.width, window.width, 0, -window.width, -window.width],
20 | });
21 |
22 | const careEndVal = 26 * 2; // 26 being text's height (font size)
23 | const careAnim = animationController.current.interpolate({
24 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
25 | outputRange: [careEndVal, careEndVal, 0, -careEndVal, -careEndVal],
26 | });
27 |
28 | const imageEndVal = IMAGE_WIDTH * 4;
29 | const imageAnim = animationController.current.interpolate({
30 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
31 | outputRange: [imageEndVal, imageEndVal, 0, -imageEndVal, -imageEndVal],
32 | });
33 |
34 | return (
35 |
38 |
42 |
46 | Care
47 |
48 |
49 | Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod
50 | tempor incididunt ut labore
51 |
52 |
53 | );
54 | };
55 |
56 | const styles = StyleSheet.create({
57 | container: {
58 | position: 'absolute',
59 | left: 0,
60 | right: 0,
61 | alignItems: 'center',
62 | paddingBottom: 100,
63 | },
64 | image: {
65 | maxWidth: IMAGE_WIDTH,
66 | maxHeight: IMAGE_HEIGHT,
67 | },
68 | title: {
69 | color: 'black',
70 | fontSize: 26,
71 | textAlign: 'center',
72 | fontFamily: 'WorkSans-Bold',
73 | },
74 | subtitle: {
75 | color: 'black',
76 | textAlign: 'center',
77 | fontFamily: 'WorkSans-Regular',
78 | paddingHorizontal: 64,
79 | paddingVertical: 16,
80 | },
81 | });
82 |
83 | export default CareView;
84 |
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/TopBackSkipView.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StyleSheet, Text, Animated, StatusBar } from 'react-native';
3 | import { useSafeAreaInsets } from 'react-native-safe-area-context';
4 | import Icon from 'react-native-vector-icons/MaterialIcons';
5 | import MyPressable from '../../components/MyPressable';
6 | import Config from '../../Config';
7 |
8 | interface Props {
9 | onBackClick: () => void;
10 | onSkipClick: () => void;
11 | animationController: React.RefObject;
12 | }
13 |
14 | const TopBackSkipView: React.FC = ({
15 | onBackClick,
16 | onSkipClick,
17 | animationController,
18 | }) => {
19 | const { top } = useSafeAreaInsets();
20 | const marginTop = Config.isIos ? top : StatusBar.currentHeight;
21 |
22 | const headerTranslateY = animationController.current.interpolate({
23 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
24 | outputRange: [-(58 + (marginTop ?? 0)), 0, 0, 0, 0],
25 | });
26 | const skipAnim = animationController.current.interpolate({
27 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
28 | outputRange: [0, 0, 0, 0, 80],
29 | });
30 |
31 | return (
32 |
38 | onBackClick()}
42 | >
43 |
44 |
45 |
46 |
47 | onSkipClick()}
50 | >
51 |
52 | Skip
53 |
54 |
55 |
56 |
57 | );
58 | };
59 |
60 | const styles = StyleSheet.create({
61 | buttonContainer: {
62 | height: 58,
63 | flexDirection: 'row',
64 | alignItems: 'center',
65 | justifyContent: 'space-between',
66 | paddingLeft: 8,
67 | paddingRight: 16,
68 | position: 'absolute',
69 | top: 0,
70 | left: 0,
71 | right: 0,
72 | },
73 | backBtn: {
74 | width: 56,
75 | height: 56,
76 | borderRadius: 30,
77 | justifyContent: 'center',
78 | alignItems: 'center',
79 | },
80 | });
81 |
82 | export default TopBackSkipView;
83 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Native UI Templates
2 |
3 | Free UI templates created in react-native.
4 |
5 |
6 |
7 |
8 |
9 | ## 🧬 Samples
10 | | Project | |
11 | | :--- | --- |
12 | | **[> Expo Snack](https://snack.expo.io/@ashu_dubey/react-native-ui-templates)** (Not handled for web yet). | |
13 | | 1. Hotel Booking
Shows the list of hotels nearby with their ratings and other details, filter UI and custom calendar view etc.
**[> Browse](./src/hotel_booking#readme)**
**> Demo: [twitter](https://twitter.com/aashudubey_ad/status/1576292697173766145) \| [youtube](https://youtube.com/shorts/ioFcve0rYnc)** |
|
14 | | 2. Design Course
A minimal UI showing list of courses related to UI design.
**[> Browse](./src/design_course#readme)**
**> Demo: [twitter](https://twitter.com/aashudubey_ad/status/1578846092694720512) \| [youtube](https://youtube.com/shorts/5G0obPHAdyc)** |
|
15 | | 3. Animated Onboarding
An onboarding UI flow with smooth animations, for a Mental Wellness App.
**[> Browse](./src/introduction_animation#readme)**
**> Demo: [twitter](https://twitter.com/aashudubey_ad/status/1580260456215695360) \| [youtube](https://youtube.com/shorts/AOD9FyiSR3U)** |
|
16 |
17 | ## 💪🏼 Getting Started
18 |
19 | This project is built on react-native CLI, so make sure you've [set up development environment](https://reactnative.dev/docs/environment-setup).
20 |
21 | ```bash
22 | # clone the project and cd into it
23 | git clone https://github.com/Aashu-Dubey/React-Native-UI-Templates.git
24 | cd ./React-Native-UI-Templates
25 |
26 | # install dependencies
27 | yarn install
28 |
29 | # iOS only
30 | npx pod-install ios
31 | # or
32 | cd ios && pod install && cd ..
33 |
34 | # Run iOS
35 | npx react-native run-ios
36 |
37 | # Run Android
38 | npx react-native run-android
39 |
40 | ```
41 |
42 | ## 🌻 Motivation
43 |
44 | This was initially started as my learning project and is inspired from the Flutter project [Best-Flutter-UI-Templates](https://github.com/mitesh77/Best-Flutter-UI-Templates).
45 |
46 | ## 🔗 Links
47 |
48 | - [Original Flutter project](https://github.com/mitesh77/Best-Flutter-UI-Templates)
49 | - [Ionic-UI-Templates](https://github.com/Aashu-Dubey/Ionic-UI-Templates): Ionic version of this project.
50 | - [Twitter Post](https://twitter.com/aashudubey_ad/status/1484571529644212224)
51 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.7)
5 | base64
6 | nkf
7 | rexml
8 | activesupport (6.1.7.10)
9 | concurrent-ruby (~> 1.0, >= 1.0.2)
10 | i18n (>= 1.6, < 2)
11 | minitest (>= 5.1)
12 | tzinfo (~> 2.0)
13 | zeitwerk (~> 2.3)
14 | addressable (2.8.7)
15 | public_suffix (>= 2.0.2, < 7.0)
16 | algoliasearch (1.27.5)
17 | httpclient (~> 2.8, >= 2.8.3)
18 | json (>= 1.5.1)
19 | atomos (0.1.3)
20 | base64 (0.2.0)
21 | claide (1.1.0)
22 | cocoapods (1.15.2)
23 | addressable (~> 2.8)
24 | claide (>= 1.0.2, < 2.0)
25 | cocoapods-core (= 1.15.2)
26 | cocoapods-deintegrate (>= 1.0.3, < 2.0)
27 | cocoapods-downloader (>= 2.1, < 3.0)
28 | cocoapods-plugins (>= 1.0.0, < 2.0)
29 | cocoapods-search (>= 1.0.0, < 2.0)
30 | cocoapods-trunk (>= 1.6.0, < 2.0)
31 | cocoapods-try (>= 1.1.0, < 2.0)
32 | colored2 (~> 3.1)
33 | escape (~> 0.0.4)
34 | fourflusher (>= 2.3.0, < 3.0)
35 | gh_inspector (~> 1.0)
36 | molinillo (~> 0.8.0)
37 | nap (~> 1.0)
38 | ruby-macho (>= 2.3.0, < 3.0)
39 | xcodeproj (>= 1.23.0, < 2.0)
40 | cocoapods-core (1.15.2)
41 | activesupport (>= 5.0, < 8)
42 | addressable (~> 2.8)
43 | algoliasearch (~> 1.0)
44 | concurrent-ruby (~> 1.1)
45 | fuzzy_match (~> 2.0.4)
46 | nap (~> 1.0)
47 | netrc (~> 0.11)
48 | public_suffix (~> 4.0)
49 | typhoeus (~> 1.0)
50 | cocoapods-deintegrate (1.0.5)
51 | cocoapods-downloader (2.1)
52 | cocoapods-plugins (1.0.0)
53 | nap
54 | cocoapods-search (1.0.1)
55 | cocoapods-trunk (1.6.0)
56 | nap (>= 0.8, < 2.0)
57 | netrc (~> 0.11)
58 | cocoapods-try (1.2.0)
59 | colored2 (3.1.2)
60 | concurrent-ruby (1.3.3)
61 | escape (0.0.4)
62 | ethon (0.16.0)
63 | ffi (>= 1.15.0)
64 | ffi (1.17.1)
65 | fourflusher (2.3.1)
66 | fuzzy_match (2.0.4)
67 | gh_inspector (1.1.3)
68 | httpclient (2.9.0)
69 | mutex_m
70 | i18n (1.14.7)
71 | concurrent-ruby (~> 1.0)
72 | json (2.7.6)
73 | minitest (5.25.4)
74 | molinillo (0.8.0)
75 | mutex_m (0.3.0)
76 | nanaimo (0.3.0)
77 | nap (1.1.0)
78 | netrc (0.11.0)
79 | nkf (0.2.0)
80 | public_suffix (4.0.7)
81 | rexml (3.4.1)
82 | ruby-macho (2.5.1)
83 | typhoeus (1.4.1)
84 | ethon (>= 0.9.0)
85 | tzinfo (2.0.6)
86 | concurrent-ruby (~> 1.0)
87 | xcodeproj (1.25.1)
88 | CFPropertyList (>= 2.3.3, < 4.0)
89 | atomos (~> 0.1.3)
90 | claide (>= 1.0.2, < 2.0)
91 | colored2 (~> 3.1)
92 | nanaimo (~> 0.3.0)
93 | rexml (>= 3.3.6, < 4.0)
94 | zeitwerk (2.6.18)
95 |
96 | PLATFORMS
97 | ruby
98 |
99 | DEPENDENCIES
100 | activesupport (>= 6.1.7.5, != 7.1.0)
101 | cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
102 | concurrent-ruby (< 1.3.4)
103 | xcodeproj (< 1.26.0)
104 |
105 | RUBY VERSION
106 | ruby 2.6.10p210
107 |
108 | BUNDLED WITH
109 | 1.17.2
110 |
--------------------------------------------------------------------------------
/src/components/Toast.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useRef, useImperativeHandle, useEffect } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Animated,
7 | ToastAndroid,
8 | useWindowDimensions,
9 | Platform,
10 | } from 'react-native';
11 |
12 | interface Props {}
13 |
14 | export const DURATION = {
15 | LENGTH_SHORT: 2000,
16 | FOREVER: 0,
17 | };
18 |
19 | const Toast: React.FC = React.forwardRef((_props, ref) => {
20 | const { height } = useWindowDimensions();
21 |
22 | const [isShow, setShow] = useState(false);
23 | const [toastText, setToastText] = useState('');
24 | const opacityValue = useRef(new Animated.Value(1)).current;
25 | let animation: Animated.CompositeAnimation | null = null;
26 | let timer: NodeJS.Timeout | null = null;
27 | let isShowing: boolean = false;
28 |
29 | useEffect(() => {
30 | return () => {
31 | animation && animation.stop();
32 | timer && clearTimeout(timer);
33 | };
34 | }, [animation, timer]);
35 |
36 | useImperativeHandle(ref, () => ({
37 | show: (text: string) => {
38 | Platform.OS === 'android'
39 | ? ToastAndroid.show(text, ToastAndroid.SHORT)
40 | : show(text);
41 | },
42 | }));
43 |
44 | const show = (text: string) => {
45 | setShow(true);
46 | setToastText(text);
47 |
48 | animation = Animated.timing(opacityValue, {
49 | toValue: 1,
50 | duration: 500,
51 | useNativeDriver: true,
52 | });
53 | animation.start(() => {
54 | isShowing = true;
55 | close();
56 | });
57 | };
58 |
59 | const close = () => {
60 | let delay = DURATION.LENGTH_SHORT;
61 |
62 | if (!isShowing && !isShow) {
63 | return;
64 | }
65 | timer && clearTimeout(timer);
66 | timer = setTimeout(() => {
67 | animation = Animated.timing(opacityValue, {
68 | toValue: 0.0,
69 | duration: 500,
70 | useNativeDriver: true,
71 | });
72 | animation.start(() => {
73 | setShow(false);
74 | isShowing = false;
75 | });
76 | }, delay);
77 | };
78 |
79 | return (
80 | <>
81 | {isShow && Platform.OS !== 'android' && (
82 |
86 |
87 | {toastText}
88 |
89 |
90 | )}
91 | >
92 | );
93 | });
94 |
95 | const styles = StyleSheet.create({
96 | container: {
97 | position: 'absolute',
98 | left: 0,
99 | right: 0,
100 | elevation: 999,
101 | alignItems: 'center',
102 | zIndex: 10000,
103 | },
104 | content: {
105 | backgroundColor: 'rgba(0,0,0,0.6)',
106 | borderRadius: 12,
107 | padding: 10,
108 | bottom: 64,
109 | maxWidth: '80%',
110 | },
111 | text: {
112 | fontSize: 14,
113 | color: '#f8f8f8',
114 | textAlign: 'center',
115 | paddingHorizontal: 8,
116 | paddingVertical: 4,
117 | },
118 | });
119 |
120 | export default Toast;
121 |
--------------------------------------------------------------------------------
/src/InviteFriendScene.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Image,
7 | Platform,
8 | StatusBar,
9 | useWindowDimensions,
10 | } from 'react-native';
11 | import {
12 | SafeAreaView,
13 | useSafeAreaInsets,
14 | } from 'react-native-safe-area-context';
15 | import { useNavigation } from '@react-navigation/native';
16 | import { DrawerNavigationProp } from '@react-navigation/drawer';
17 | import Icon from 'react-native-vector-icons/MaterialIcons';
18 | import MyPressable from './components/MyPressable';
19 | import { AppImages } from './assets';
20 |
21 | const InviteFriendScene: React.FC = () => {
22 | const { width } = useWindowDimensions();
23 | const navigation = useNavigation>();
24 | const { top } = useSafeAreaInsets();
25 |
26 | const imageSize = width - 32;
27 | const marginTop = Platform.OS === 'ios' ? top : StatusBar.currentHeight ?? 24;
28 |
29 | return (
30 |
34 |
42 | Invite Your Friends
43 |
44 | Are you one of those who makes everything{'\n'} at the last moment?
45 |
46 |
47 |
48 |
49 | Share
50 |
51 |
52 |
53 | navigation.toggleDrawer()}
57 | >
58 |
59 |
60 |
61 | );
62 | };
63 |
64 | const styles = StyleSheet.create({
65 | image: {
66 | backgroundColor: '#FEFEFE',
67 | alignSelf: 'center',
68 | },
69 | title: {
70 | color: 'black',
71 | fontSize: 20,
72 | fontFamily: 'WorkSans-Bold',
73 | textAlign: 'center',
74 | paddingTop: 8,
75 | },
76 | subTitle: {
77 | color: 'black',
78 | fontSize: 16,
79 | fontFamily: 'WorkSans-Regular',
80 | textAlign: 'center',
81 | paddingTop: 16,
82 | },
83 | button: {
84 | flexDirection: 'row',
85 | width: 140,
86 | height: 40,
87 | padding: 8,
88 | backgroundColor: 'dodgerblue',
89 | borderRadius: 4,
90 | elevation: 8,
91 | alignItems: 'center',
92 | justifyContent: 'center',
93 | },
94 | buttonText: {
95 | color: 'white',
96 | fontWeight: '500',
97 | textAlign: 'center',
98 | padding: 4,
99 | },
100 | menuBtn: {
101 | position: 'absolute',
102 | padding: 8,
103 | left: 8,
104 | },
105 | });
106 |
107 | export default InviteFriendScene;
108 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/src/HelpScene.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Image,
7 | Platform,
8 | StatusBar,
9 | useWindowDimensions,
10 | } from 'react-native';
11 | import {
12 | SafeAreaView,
13 | useSafeAreaInsets,
14 | } from 'react-native-safe-area-context';
15 | import { useNavigation } from '@react-navigation/native';
16 | import { DrawerNavigationProp } from '@react-navigation/drawer';
17 | import Icon from 'react-native-vector-icons/MaterialIcons';
18 | import MyPressable from './components/MyPressable';
19 | import { AppImages } from './assets';
20 |
21 | const HelpScene: React.FC = () => {
22 | const { width } = useWindowDimensions();
23 | const navigation = useNavigation>();
24 | const { top } = useSafeAreaInsets();
25 |
26 | const imageSize = width - 32;
27 | const marginTop = Platform.OS === 'ios' ? top : StatusBar.currentHeight ?? 24;
28 |
29 | return (
30 |
34 |
42 | How can we help you?
43 |
44 | It looks like you are experiencing problems{'\n'}with our sign up
45 | process. We are here to{'\n'}help so please get in touch with us
46 |
47 |
48 |
49 | Chat with Us
50 |
51 |
52 |
53 | navigation.openDrawer()}
57 | >
58 |
59 |
60 |
61 | );
62 | };
63 |
64 | const styles = StyleSheet.create({
65 | image: {
66 | backgroundColor: '#FEFEFE',
67 | alignSelf: 'center',
68 | },
69 | title: {
70 | color: 'black',
71 | fontSize: 20,
72 | fontFamily: 'WorkSans-Bold',
73 | textAlign: 'center',
74 | paddingTop: 8,
75 | },
76 | subTitle: {
77 | color: 'black',
78 | fontSize: 16,
79 | fontFamily: 'WorkSans-Regular',
80 | textAlign: 'center',
81 | paddingTop: 16,
82 | },
83 | buttonContainer: {
84 | flex: 1,
85 | justifyContent: 'center',
86 | alignItems: 'center',
87 | },
88 | button: {
89 | width: 140,
90 | height: 40,
91 | padding: 8,
92 | backgroundColor: 'dodgerblue',
93 | borderRadius: 4,
94 | elevation: 8,
95 | justifyContent: 'center',
96 | },
97 | buttonText: {
98 | color: 'white',
99 | fontWeight: '500',
100 | textAlign: 'center',
101 | padding: 4,
102 | },
103 | menuBtn: {
104 | position: 'absolute',
105 | padding: 8,
106 | left: 8,
107 | },
108 | });
109 |
110 | export default HelpScene;
111 |
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/SplashView.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Image,
7 | Animated,
8 | useWindowDimensions,
9 | ScrollView,
10 | } from 'react-native';
11 | import { useSafeAreaInsets } from 'react-native-safe-area-context';
12 | import MyPressable from '../../components/MyPressable';
13 | import { AppImages } from '../../assets';
14 |
15 | interface Props {
16 | onNextClick: () => void;
17 | animationController: React.RefObject;
18 | }
19 |
20 | const SplashView: React.FC = ({ onNextClick, animationController }) => {
21 | const window = useWindowDimensions();
22 | const insets = useSafeAreaInsets();
23 |
24 | const splashTranslateY = animationController.current.interpolate({
25 | inputRange: [0, 0.2, 0.8],
26 | outputRange: [0, -window.height, -window.height],
27 | });
28 |
29 | const introImageData = Image.resolveAssetSource(AppImages.introduction_image);
30 |
31 | return (
32 |
35 |
36 |
37 |
47 |
48 | Clearhead
49 |
50 | Lorem ipsum dolor sit amet,consectetur{'\n'}adipiscing elit,sed do
51 | eiusmod tempor{'\n'}incididunt ut labore
52 |
53 |
54 |
55 |
56 |
57 | onNextClick()}
62 | >
63 | Let's begin
64 |
65 |
66 |
67 |
68 | );
69 | };
70 |
71 | const styles = StyleSheet.create({
72 | title: {
73 | color: 'black',
74 | fontSize: 25,
75 | textAlign: 'center',
76 | fontFamily: 'WorkSans-Bold',
77 | paddingVertical: 8,
78 | },
79 | subtitle: {
80 | color: 'black',
81 | textAlign: 'center',
82 | fontFamily: 'WorkSans-Regular',
83 | paddingHorizontal: 24,
84 | },
85 | footer: {
86 | flexGrow: 1,
87 | justifyContent: 'center',
88 | paddingTop: 8,
89 | },
90 | buttonContainer: {
91 | borderRadius: 38,
92 | overflow: 'hidden',
93 | alignSelf: 'center',
94 | },
95 | button: {
96 | height: 58,
97 | backgroundColor: 'rgb(21, 32, 54)',
98 | paddingVertical: 16,
99 | paddingHorizontal: 56,
100 | },
101 | buttonText: {
102 | fontSize: 18,
103 | fontFamily: 'WorkSans-Regular',
104 | color: 'white',
105 | },
106 | });
107 |
108 | export default SplashView;
109 |
--------------------------------------------------------------------------------
/src/AppNavigator.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StatusBar, StyleSheet, useWindowDimensions } from 'react-native';
3 | import { createDrawerNavigator } from '@react-navigation/drawer';
4 | import { createStackNavigator } from '@react-navigation/stack';
5 | // import { createNativeStackNavigator } from '@react-navigation/native-stack';
6 | import {
7 | HomeScene,
8 | DrawerContent,
9 | HelpScene,
10 | FeedbackScene,
11 | InviteFriendScene,
12 | } from '.';
13 | import { CourseInfoScreen, HomeDesignCourse } from './design_course';
14 | import { IntroductionAnimationScreen } from './introduction_animation';
15 | import HotelHomeScreen from './hotel_booking/HotelHomeScreen';
16 |
17 | const Drawer = createDrawerNavigator();
18 | /**
19 | * TODO:- Temporarily using r-nav-stack instead of r-nav-native-stack cause of following issue:
20 | * https://github.com/react-navigation/react-navigation/issues/10941
21 | * Replace with r-nav-native-stack, once this is fixed.
22 | */
23 | const Stack = createStackNavigator();
24 | // const Stack = createNativeStackNavigator();
25 |
26 | const DrawerNavigator: React.FC = () => {
27 | const window = useWindowDimensions();
28 |
29 | return (
30 | }
44 | // this is just to enable shadow/elevation style on drawer, as it fallback to JS drawer solution instead of native one (v6)
45 | // as explained here:- https://github.com/react-navigation/react-navigation/issues/10946#issuecomment-1287082343
46 | detachInactiveScreens={false}
47 | >
48 |
49 |
50 |
51 |
52 |
53 | );
54 | };
55 |
56 | export default () => {
57 | return (
58 | <>
59 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
79 |
80 | >
81 | );
82 | };
83 |
84 | const styles = StyleSheet.create({
85 | drawerSceneContainer: {
86 | elevation: 24,
87 | shadowColor: 'grey',
88 | shadowOffset: { width: 0, height: 12 },
89 | shadowOpacity: 0.58,
90 | shadowRadius: 16.0,
91 | },
92 | });
93 |
--------------------------------------------------------------------------------
/ios/react_native_UI_Templates.xcodeproj/xcshareddata/xcschemes/react_native_UI_Templates.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/.github/workflows/build-ios-simulator.yml:
--------------------------------------------------------------------------------
1 | name: Create an iOS Simulator build
2 |
3 | on:
4 | push:
5 | paths:
6 | - '*'
7 | - '.github/workflows/build-ios-simulator.yml'
8 | - 'ios/**'
9 | - 'src/**'
10 | - '!**/*.md'
11 | branches:
12 | - main
13 |
14 | jobs:
15 | build-ios-simulator:
16 | name: Create an iOS Simulator build
17 | runs-on: macos-latest
18 |
19 | steps:
20 | - uses: actions/checkout@v4
21 |
22 | # 'corepack enable' is needed for now till it's experimental, may remove the command once it becomes stable in later node releases
23 | - name: Enable Corepack
24 | run: corepack enable
25 |
26 | # Setup Web environment to install packages.
27 | - name: Setup Web environment
28 | uses: actions/setup-node@v4
29 | with:
30 | node-version: '22'
31 | cache: 'yarn'
32 |
33 | - uses: hendrikmuhs/ccache-action@v1.2
34 | name: Xcode Compile Cache
35 | with:
36 | key: ${{ runner.os }}-ccache # makes a unique key w/related restore key internally
37 | create-symlink: true
38 | max-size: 1500M
39 |
40 | - name: Restore node_modules from cache
41 | uses: actions/cache@v4
42 | with:
43 | path: node_modules
44 | key: ${{ runner.os }}-node-modules-${{ hashFiles('yarn.lock') }}
45 | restore-keys: ${{ runner.os }}-node-modules-
46 |
47 | # Here '--immutable' will only use commited 'yarn.lock', and will throw error if some update is needed
48 | - name: Install node_modules
49 | run: yarn install --immutable
50 |
51 | - name: Restore Pods cache
52 | uses: actions/cache@v4
53 | with:
54 | path: |
55 | ios/Pods
56 | ~/Library/Caches/CocoaPods
57 | ~/.cocoapods
58 | key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock') }}
59 | restore-keys: ${{ runner.os }}-pods-
60 |
61 | - name: Restore build artifacts from cache
62 | uses: actions/cache@v4
63 | with:
64 | path: ios/build
65 | key: ${{ runner.os }}-ios-derived-data-${{ hashFiles('ios/Podfile.lock') }}
66 | restore-keys: ${{ runner.os }}-ios-derived-data-
67 |
68 | - name: Install Pod files
69 | run: npx pod-install ios
70 |
71 | - name: Install xcpretty
72 | run: gem install xcpretty
73 |
74 | - name: Run simulator build command
75 | working-directory: ios
76 | run: |
77 | export CCACHE_SLOPPINESS=clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros
78 | export CCACHE_FILECLONE=true
79 | export CCACHE_DEPEND=true
80 | export CCACHE_INODECACHE=true
81 | export CCACHE_LIMIT_MULTIPLE=0.95
82 | ccache -s
83 | set -o pipefail
84 | xcodebuild \
85 | CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
86 | -scheme react_native_UI_Templates \
87 | -workspace react_native_UI_Templates.xcworkspace \
88 | -sdk iphonesimulator \
89 | -configuration Release \
90 | -derivedDataPath build | xcpretty
91 | ccache -s
92 |
93 | - name: Store build .app file as zip
94 | working-directory: ios
95 | run: |
96 | cd build/Build/Products/Release-iphonesimulator
97 | mkdir -p output
98 | zip -r -y -o output/react_native_ui_templates.zip react_native_ui_templates.app
99 |
100 | - name: Save build file as artifact
101 | uses: actions/upload-artifact@v4
102 | with:
103 | name: rn_ui_templates_ios
104 | path: ios/build/Build/Products/Release-iphonesimulator/output
105 |
--------------------------------------------------------------------------------
/src/design_course/PopulerCourseListView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Animated,
7 | ListRenderItemInfo,
8 | Image,
9 | } from 'react-native';
10 | import Icon from 'react-native-vector-icons/MaterialIcons';
11 | import MyPressable from '../components/MyPressable';
12 | import { CategoryType } from './model/category';
13 |
14 | interface Props {
15 | data: ListRenderItemInfo;
16 | onScreenClicked: () => void;
17 | }
18 |
19 | const PopulerCourseListView: React.FC = ({ data, onScreenClicked }) => {
20 | const { index, item } = data;
21 |
22 | const translateY = useRef(new Animated.Value(50)).current;
23 | const opacity = useRef(new Animated.Value(0)).current;
24 |
25 | useEffect(() => {
26 | Animated.parallel([
27 | Animated.timing(translateY, {
28 | toValue: 0,
29 | duration: 1000,
30 | delay: index * (1000 / 3),
31 | useNativeDriver: true,
32 | }),
33 | Animated.timing(opacity, {
34 | toValue: 1,
35 | duration: 1000,
36 | delay: index * (1000 / 3),
37 | useNativeDriver: true,
38 | }),
39 | ]).start();
40 | });
41 |
42 | return (
43 |
47 |
52 |
53 |
54 |
55 | {item.title}
56 |
57 |
58 | {item.lessonCount} lesson
59 |
60 | {item.rating}
61 |
62 |
63 |
64 |
65 |
66 |
70 |
71 |
72 |
73 |
74 |
75 | );
76 | };
77 |
78 | const styles = StyleSheet.create({
79 | container: {
80 | flex: 1,
81 | borderRadius: 16,
82 | overflow: 'hidden',
83 | marginHorizontal: 16,
84 | },
85 | bgColorView: {
86 | flex: 1,
87 | marginBottom: 48,
88 | borderRadius: 16,
89 | backgroundColor: '#F8FAFB',
90 | },
91 | title: {
92 | fontSize: 16,
93 | fontFamily: 'WorkSans-SemiBold',
94 | letterSpacing: 0.27,
95 | color: 'rgb(23, 38, 42)',
96 | },
97 | lessionCountRatingContainer: {
98 | flexDirection: 'row',
99 | alignItems: 'center',
100 | paddingTop: 8,
101 | },
102 | textStyle: {
103 | fontSize: 18,
104 | fontFamily: 'WorkSans-Regular',
105 | letterSpacing: 0.27,
106 | color: 'rgb(58, 81, 96)',
107 | },
108 | imageContainer: {
109 | borderRadius: 16,
110 | marginHorizontal: 16,
111 | marginBottom: 4,
112 | backgroundColor: 'white',
113 | elevation: 6,
114 | shadowColor: 'grey',
115 | shadowOffset: { width: 0, height: 0 },
116 | shadowOpacity: 0.22,
117 | shadowRadius: 6.0,
118 | },
119 | });
120 |
121 | export default PopulerCourseListView;
122 |
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/components/NextButtonArrow.tsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react';
2 | import { StyleSheet, Text, Animated } from 'react-native';
3 | import Icon from 'react-native-vector-icons/MaterialIcons';
4 | import MyPressable from '../../../components/MyPressable';
5 |
6 | interface Props {
7 | onBtnPress: () => void;
8 | animationController: React.MutableRefObject;
9 | }
10 |
11 | const IconPressable = Animated.createAnimatedComponent(Icon);
12 |
13 | /*
14 | * TODO:- find better solution for this animation so we don't have to use 'useNativeDriver: false' in 'IntroductionAnimationScreen.tsx' as width doesn't support it yet
15 | */
16 | const NextButtonArrow: React.FC = ({
17 | onBtnPress,
18 | animationController,
19 | }) => {
20 | const arrowAnim = useRef>(
21 | new Animated.Value(0),
22 | );
23 |
24 | arrowAnim.current = animationController.current.interpolate({
25 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
26 | outputRange: [0, 0, 0, 0, 1],
27 | });
28 |
29 | // for transition from arrow to sign up
30 | const transitionAnim = arrowAnim.current.interpolate({
31 | inputRange: [0, 0.85, 1],
32 | outputRange: [36, 0, 0],
33 | });
34 | const opacityAnim = arrowAnim.current.interpolate({
35 | inputRange: [0, 0.7, 1],
36 | outputRange: [0, 0, 1],
37 | });
38 | const iconTransitionAnim = arrowAnim.current.interpolate({
39 | inputRange: [0, 0.35, 0.85, 1], // or [0, 0.85, 1],
40 | outputRange: [0, 0, -36, -36], // or [0, 0, -36]
41 | });
42 | const iconOpacityAnim = arrowAnim.current.interpolate({
43 | inputRange: [0, 0.7, 1],
44 | outputRange: [1, 0, 0],
45 | });
46 | // end
47 |
48 | const widthAnim = arrowAnim.current.interpolate({
49 | inputRange: [0, 1],
50 | outputRange: [58, 258],
51 | });
52 |
53 | const marginBottomAnim = arrowAnim.current.interpolate({
54 | inputRange: [0, 1],
55 | outputRange: [38, 0],
56 | });
57 |
58 | const radiusAnim = arrowAnim.current.interpolate({
59 | inputRange: [0, 1],
60 | outputRange: [40, 8],
61 | });
62 |
63 | return (
64 |
74 | onBtnPress()}
78 | >
79 |
88 | Sign Up
89 |
90 |
91 |
92 |
104 |
105 |
106 | );
107 | };
108 |
109 | const styles = StyleSheet.create({
110 | container: {
111 | height: 58,
112 | backgroundColor: 'rgb(21, 32, 54)',
113 | overflow: 'hidden',
114 | },
115 | signupContainer: {
116 | flexDirection: 'row',
117 | justifyContent: 'space-between',
118 | paddingHorizontal: 16,
119 | },
120 | signupText: {
121 | fontSize: 18,
122 | fontFamily: 'WorkSans-Medium',
123 | color: 'white',
124 | },
125 | icon: {
126 | position: 'absolute',
127 | alignSelf: 'center',
128 | },
129 | });
130 |
131 | export default NextButtonArrow;
132 |
--------------------------------------------------------------------------------
/src/design_course/CategoryListView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Animated,
7 | Image,
8 | ListRenderItemInfo,
9 | } from 'react-native';
10 | import Icon from 'react-native-vector-icons/MaterialIcons';
11 | import MyPressable from '../components/MyPressable';
12 | import { CategoryType } from './model/category';
13 |
14 | interface Props {
15 | data: ListRenderItemInfo;
16 | onScreenClicked: () => void;
17 | }
18 |
19 | const CategoryListView: React.FC = ({ data, onScreenClicked }) => {
20 | const { index, item } = data;
21 |
22 | const translateX = useRef(new Animated.Value(50));
23 | const opacity = useRef(new Animated.Value(0));
24 |
25 | useEffect(() => {
26 | Animated.parallel([
27 | Animated.timing(translateX.current, {
28 | toValue: 0,
29 | duration: 1000,
30 | delay: index * (1000 / 3),
31 | useNativeDriver: true,
32 | }),
33 | Animated.timing(opacity.current, {
34 | toValue: 1,
35 | duration: 1000,
36 | delay: index * (1000 / 3),
37 | useNativeDriver: true,
38 | }),
39 | ]).start();
40 | }, [index]);
41 |
42 | return (
43 |
52 |
57 |
58 |
59 |
62 |
63 |
67 |
68 |
69 | {item.title}
70 |
71 |
72 | {item.lessonCount} lesson
73 |
74 | {item.rating}
75 |
76 |
77 |
78 |
79 | ${item.money}
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | );
90 | };
91 |
92 | const styles = StyleSheet.create({
93 | container: { borderRadius: 16, overflow: 'hidden' },
94 | bgColorView: {
95 | flex: 1,
96 | marginLeft: 48,
97 | borderRadius: 16,
98 | backgroundColor: '#F8FAFB',
99 | },
100 | title: {
101 | fontSize: 16,
102 | fontFamily: 'WorkSans-SemiBold',
103 | letterSpacing: 0.27,
104 | color: 'rgb(23, 38, 42)',
105 | },
106 | lessionCountRatingContainer: {
107 | flexDirection: 'row',
108 | alignItems: 'center',
109 | paddingRight: 16,
110 | paddingBottom: 8,
111 | },
112 | textStyle: {
113 | fontSize: 18,
114 | fontFamily: 'WorkSans-Regular',
115 | letterSpacing: 0.27,
116 | color: 'rgb(58, 81, 96)',
117 | },
118 | moneyText: {
119 | flex: 1,
120 | fontFamily: 'WorkSans-SemiBold',
121 | color: 'rgb(0, 182, 240)',
122 | },
123 | addIconView: {
124 | padding: 4,
125 | backgroundColor: 'rgb(0, 182, 240)',
126 | borderRadius: 8,
127 | },
128 | });
129 |
130 | export default CategoryListView;
131 |
--------------------------------------------------------------------------------
/src/FeedbackScene.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | TextInput,
7 | Platform,
8 | StatusBar,
9 | Image,
10 | KeyboardAvoidingView,
11 | useWindowDimensions,
12 | ScrollView,
13 | } from 'react-native';
14 | import {
15 | SafeAreaView,
16 | useSafeAreaInsets,
17 | } from 'react-native-safe-area-context';
18 | import { useNavigation } from '@react-navigation/native';
19 | import { DrawerNavigationProp } from '@react-navigation/drawer';
20 | import Icon from 'react-native-vector-icons/MaterialIcons';
21 | import MyPressable from './components/MyPressable';
22 | import { AppImages } from './assets';
23 |
24 | const FeedbackScene: React.FC = () => {
25 | const { width } = useWindowDimensions();
26 | const navigation = useNavigation>();
27 | const { top } = useSafeAreaInsets();
28 |
29 | const imageSize = width - 32;
30 | const marginTop = Platform.OS === 'ios' ? top : StatusBar.currentHeight ?? 24;
31 |
32 | return (
33 |
37 |
38 |
39 |
47 | Your FeedBack
48 |
49 | Give your best time for this moment.
50 |
51 |
52 |
58 |
59 |
60 |
61 | Send
62 |
63 |
64 |
65 |
66 | navigation.openDrawer()}
70 | >
71 |
72 |
73 |
74 | );
75 | };
76 |
77 | const styles = StyleSheet.create({
78 | image: {
79 | backgroundColor: '#FEFEFE',
80 | alignSelf: 'center',
81 | },
82 | title: {
83 | color: 'black',
84 | fontSize: 20,
85 | fontFamily: 'WorkSans-Bold',
86 | textAlign: 'center',
87 | paddingTop: 8,
88 | },
89 | subTitle: {
90 | color: 'black',
91 | fontSize: 16,
92 | fontFamily: 'WorkSans-Regular',
93 | textAlign: 'center',
94 | paddingTop: 16,
95 | },
96 | inputContainer: {
97 | minHeight: 80,
98 | maxHeight: 160,
99 | marginTop: 16,
100 | marginHorizontal: 32,
101 | padding: 16,
102 | backgroundColor: 'white',
103 | borderRadius: 8,
104 | elevation: 8,
105 | shadowColor: 'rgba(158, 158, 158, 0.8)',
106 | shadowOffset: { width: 4, height: 4 },
107 | shadowOpacity: 0.8,
108 | shadowRadius: 8,
109 | },
110 | input: {
111 | height: 48,
112 | color: 'black',
113 | fontSize: 16,
114 | fontFamily: 'WorkSans-Regular',
115 | textAlignVertical: 'top',
116 | },
117 | button: {
118 | width: 120,
119 | height: 40,
120 | padding: 8,
121 | marginTop: 16,
122 | alignSelf: 'center',
123 | justifyContent: 'center',
124 | backgroundColor: 'dodgerblue',
125 | borderRadius: 4,
126 | elevation: 8,
127 | },
128 | buttonText: {
129 | color: 'white',
130 | fontWeight: '500',
131 | textAlign: 'center',
132 | padding: 4,
133 | },
134 | menuBtn: {
135 | position: 'absolute',
136 | padding: 8,
137 | left: 8,
138 | },
139 | });
140 |
141 | export default FeedbackScene;
142 |
--------------------------------------------------------------------------------
/src/introduction_animation/IntroductionAnimationScreen.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useEffect, useRef, useState } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | useWindowDimensions,
6 | Animated,
7 | Easing,
8 | StatusBar,
9 | } from 'react-native';
10 | import { useNavigation } from '@react-navigation/native';
11 | import {
12 | SplashView,
13 | RelaxView,
14 | CareView,
15 | MoodDiaryView,
16 | WelcomeView,
17 | TopBackSkipView,
18 | CenterNextButton,
19 | } from './scenes';
20 |
21 | const IntroductionAnimationScreen: React.FC = () => {
22 | const navigation = useNavigation();
23 | const window = useWindowDimensions();
24 |
25 | const [currentPage, setCurrentPage] = useState(0);
26 |
27 | const animationController = useRef(new Animated.Value(0));
28 | const animValue = useRef(0);
29 |
30 | useEffect(() => {
31 | animationController.current.addListener(({ value }) => {
32 | animValue.current = value;
33 | setCurrentPage(value);
34 | });
35 | }, []);
36 |
37 | const relaxTranslateY = animationController.current.interpolate({
38 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
39 | outputRange: [window.height, 0, 0, 0, 0],
40 | });
41 |
42 | const playAnimation = useCallback(
43 | (toValue: number, duration: number = 1600) => {
44 | Animated.timing(animationController.current, {
45 | toValue,
46 | duration,
47 | easing: Easing.bezier(0.4, 0.0, 0.2, 1.0),
48 | // here it is false only cause of width animation in 'NextButtonArrow.tsx', as width doesn't support useNativeDriver: true
49 | // TODO:- find better solution so we can use true here and animation also work
50 | useNativeDriver: false,
51 | }).start();
52 | },
53 | [],
54 | );
55 |
56 | const onNextClick = useCallback(() => {
57 | let toValue;
58 | if (animValue.current === 0) {
59 | toValue = 0.2;
60 | } else if (animValue.current >= 0 && animValue.current <= 0.2) {
61 | toValue = 0.4;
62 | } else if (animValue.current > 0.2 && animValue.current <= 0.4) {
63 | toValue = 0.6;
64 | } else if (animValue.current > 0.4 && animValue.current <= 0.6) {
65 | toValue = 0.8;
66 | } else if (animValue.current > 0.6 && animValue.current <= 0.8) {
67 | navigation.goBack();
68 | }
69 |
70 | toValue !== undefined && playAnimation(toValue);
71 | }, [playAnimation, navigation]);
72 |
73 | const onBackClick = useCallback(() => {
74 | let toValue;
75 | if (animValue.current >= 0.2 && animValue.current < 0.4) {
76 | toValue = 0.0;
77 | } else if (animValue.current >= 0.4 && animValue.current < 0.6) {
78 | toValue = 0.2;
79 | } else if (animValue.current >= 0.6 && animValue.current < 0.8) {
80 | toValue = 0.4;
81 | } else if (animValue.current === 0.8) {
82 | toValue = 0.6;
83 | }
84 |
85 | toValue !== undefined && playAnimation(toValue);
86 | }, [playAnimation]);
87 |
88 | const onSkipClick = useCallback(() => {
89 | playAnimation(0.8, 1200);
90 | }, [playAnimation]);
91 |
92 | return (
93 |
94 | 0 ? 'dark' : 'light'}-content`} />
95 |
96 |
97 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | );
117 | };
118 |
119 | const styles = StyleSheet.create({
120 | scenesContainer: {
121 | justifyContent: 'center',
122 | ...StyleSheet.absoluteFillObject,
123 | },
124 | });
125 |
126 | export default IntroductionAnimationScreen;
127 |
--------------------------------------------------------------------------------
/ios/react_native_UI_Templates/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/src/hotel_booking/RangeSliderView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | useWindowDimensions,
7 | StyleProp,
8 | ViewStyle,
9 | } from 'react-native';
10 | import MultiSlider, { LabelProps } from '@ptomasroos/react-native-multi-slider';
11 |
12 | const customMarker = (triangleStyle: StyleProp) => (
13 |
14 |
15 |
16 |
17 |
18 | );
19 |
20 | const RangeSliderView: React.FC = () => {
21 | const { width } = useWindowDimensions();
22 |
23 | const { containerStyle, trackStyle, selectedStyle } = styles;
24 |
25 | const customLabel = useCallback(
26 | (prop: LabelProps) => {
27 | const {
28 | oneMarkerValue,
29 | twoMarkerValue,
30 | oneMarkerLeftPosition,
31 | twoMarkerLeftPosition,
32 | } = prop;
33 | const leftLabelDistance = oneMarkerLeftPosition - (width - 32) / 2 + 3;
34 | const rightLabelDistance = twoMarkerLeftPosition - 18 / 2 + 3;
35 |
36 | return (
37 |
38 | {Number.isFinite(oneMarkerLeftPosition) &&
39 | Number.isFinite(oneMarkerValue) && (
40 |
41 | ${oneMarkerValue}
42 |
43 | )}
44 |
45 | {Number.isFinite(twoMarkerLeftPosition) &&
46 | Number.isFinite(twoMarkerValue) && (
47 |
53 | ${twoMarkerValue}
54 |
55 | )}
56 |
57 | );
58 | },
59 | [width],
60 | );
61 |
62 | return (
63 | customMarker(styles.triangleLeftStyle)}
72 | customMarkerRight={_ => customMarker(styles.triangleRightStyle)}
73 | enableLabel
74 | customLabel={customLabel}
75 | />
76 | );
77 | };
78 |
79 | const styles = StyleSheet.create({
80 | containerStyle: {
81 | flex: 1,
82 | justifyContent: 'center',
83 | marginHorizontal: 16,
84 | marginBottom: 8,
85 | alignSelf: 'center',
86 | },
87 | trackStyle: {
88 | backgroundColor: 'lightgrey',
89 | height: 4,
90 | borderRadius: 8,
91 | },
92 | selectedStyle: {
93 | backgroundColor: '#54D3C2',
94 | height: 6,
95 | borderRadius: 8,
96 | },
97 | sliderLabel: { minWidth: 50, padding: 8 },
98 | sliderLabelText: {
99 | color: 'black',
100 | textAlign: 'center',
101 | },
102 | triangleRightStyle: {
103 | width: 0,
104 | height: 0,
105 | borderLeftWidth: 8,
106 | borderBottomWidth: 5,
107 | borderTopWidth: 5,
108 | borderStyle: 'solid',
109 | backgroundColor: 'transparent',
110 | borderLeftColor: 'white',
111 | borderBottomColor: 'transparent',
112 | borderTopColor: 'transparent',
113 | marginLeft: 7,
114 | },
115 | triangleLeftStyle: {
116 | width: 0,
117 | height: 0,
118 | borderRightWidth: 8,
119 | borderBottomWidth: 5,
120 | borderTopWidth: 5,
121 | borderStyle: 'solid',
122 | backgroundColor: 'transparent',
123 | borderRightColor: 'white',
124 | borderBottomColor: 'transparent',
125 | borderTopColor: 'transparent',
126 | marginLeft: 5,
127 | },
128 | markerStyle: {
129 | width: 24,
130 | height: 24,
131 | borderRadius: 12,
132 | backgroundColor: '#54D3C2',
133 | borderColor: 'white',
134 | borderWidth: 2,
135 | justifyContent: 'center',
136 | shadowColor: 'black',
137 | shadowOffset: { width: 0, height: 0 },
138 | shadowOpacity: 0.5,
139 | shadowRadius: 7.49,
140 | },
141 | shadowBg: {
142 | width: 30,
143 | height: 30,
144 | borderRadius: 15,
145 | // backgroundColor: 'rgba(128, 128, 128, 0.1)',
146 | justifyContent: 'center',
147 | alignItems: 'center',
148 | elevation: 12,
149 | },
150 | });
151 |
152 | export default RangeSliderView;
153 |
--------------------------------------------------------------------------------
/src/hotel_booking/HotelListItem.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Image,
7 | Animated,
8 | ListRenderItemInfo,
9 | useWindowDimensions,
10 | } from 'react-native';
11 | import { RatingBar } from '@aashu-dubey/react-native-rating-bar';
12 | import Icon from 'react-native-vector-icons/MaterialIcons';
13 | import { HotelListType } from './model/hotel_list_data';
14 |
15 | interface Props {
16 | data: ListRenderItemInfo;
17 | }
18 |
19 | const HotelListItem: React.FC = ({ data }) => {
20 | const { item, index } = data;
21 |
22 | const { width } = useWindowDimensions();
23 |
24 | const translateY = useRef(new Animated.Value(50)).current;
25 | const opacity = useRef(new Animated.Value(0)).current;
26 |
27 | const imageSize = width - 48;
28 |
29 | useEffect(() => {
30 | Animated.parallel([
31 | Animated.timing(translateY, {
32 | toValue: 0,
33 | duration: 400,
34 | delay: index * (400 / 3),
35 | useNativeDriver: true,
36 | }),
37 | Animated.timing(opacity, {
38 | toValue: 1,
39 | duration: 400,
40 | delay: index * (400 / 3),
41 | useNativeDriver: true,
42 | }),
43 | ]).start();
44 | });
45 |
46 | return (
47 |
50 |
51 |
56 |
62 |
63 |
64 |
65 | {item.titleTxt}
66 | ${item.perNight}
67 |
68 |
69 |
70 | {item.subTxt}
71 |
72 |
73 | {Number(item.dist.toPrecision(2))} km to city
74 |
75 |
76 | /per night
77 |
78 |
79 | ,
88 | half: ,
89 | empty: ,
90 | }}
91 | />
92 | {item.reviews} Reviews
93 |
94 |
95 |
96 | );
97 | };
98 |
99 | const textStyle = {
100 | color: 'rgba(128,128,128, 0.6)',
101 | fontFamily: 'WorkSans-Regular',
102 | };
103 | const styles = StyleSheet.create({
104 | container: {
105 | backgroundColor: 'white',
106 | marginVertical: 12,
107 | marginHorizontal: 24,
108 | borderRadius: 16,
109 | elevation: 8,
110 | shadowColor: 'grey',
111 | shadowOffset: { width: 4, height: 4 },
112 | shadowOpacity: 0.3,
113 | shadowRadius: 12,
114 | },
115 | imageContainer: {
116 | borderTopLeftRadius: 16,
117 | borderTopRightRadius: 16,
118 | overflow: 'hidden',
119 | },
120 | title: {
121 | flex: 1,
122 | color: 'black',
123 | fontSize: 22,
124 | fontFamily: 'WorkSans-SemiBold',
125 | },
126 | subText: {
127 | flex: 1,
128 | flexDirection: 'row',
129 | alignItems: 'center',
130 | paddingRight: 4,
131 | marginTop: 4,
132 | },
133 | perNightPrice: {
134 | color: 'black',
135 | fontSize: 22,
136 | fontFamily: 'WorkSans-SemiBold',
137 | },
138 | perNightText: { ...textStyle, color: 'black', marginTop: 4 },
139 | ratingContainer: {
140 | flexDirection: 'row',
141 | marginTop: 4,
142 | alignItems: 'center',
143 | },
144 | review: {
145 | ...textStyle,
146 | marginLeft: 8,
147 | },
148 | });
149 |
150 | export default HotelListItem;
151 |
--------------------------------------------------------------------------------
/src/introduction_animation/scenes/CenterNextButton.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useMemo, useRef, useState } from 'react';
2 | import { StyleSheet, Text, Animated } from 'react-native';
3 | import { useSafeAreaInsets } from 'react-native-safe-area-context';
4 | import NextButtonArrow from './components/NextButtonArrow';
5 |
6 | interface Props {
7 | onNextClick: () => void;
8 | animationController: React.RefObject;
9 | }
10 |
11 | interface DotIndicatorProps {
12 | index: number;
13 | selectedIndex: number;
14 | }
15 | const DotIndicator: React.FC = ({
16 | index,
17 | selectedIndex,
18 | }) => {
19 | const activeIndexRef = useRef(new Animated.Value(0));
20 |
21 | useEffect(() => {
22 | Animated.timing(activeIndexRef.current, {
23 | toValue: index === selectedIndex ? 1 : 0,
24 | duration: 480,
25 | useNativeDriver: false,
26 | }).start();
27 | }, [selectedIndex, index]);
28 |
29 | const bgColor = activeIndexRef.current.interpolate({
30 | inputRange: [0, 1],
31 | outputRange: ['#E3E4E4', '#132137'],
32 | });
33 |
34 | return (
35 |
38 | );
39 | };
40 |
41 | const CenterNextButton: React.FC = ({
42 | onNextClick,
43 | animationController,
44 | }) => {
45 | const opacity = useRef(new Animated.Value(0));
46 | const currentOpacity = useRef(0);
47 |
48 | const [selectedIndex, setSelectedIndex] = useState(0);
49 |
50 | const { bottom } = useSafeAreaInsets();
51 | const paddingBottom = 16 + bottom;
52 |
53 | const dots = useMemo(() => [0, 1, 2, 3], []);
54 |
55 | useEffect(() => {
56 | // I think this condition could be better?
57 | animationController.current.addListener(({ value }) => {
58 | const isVisible = value >= 0.2 && value <= 0.6;
59 | if (
60 | (isVisible && currentOpacity.current === 0) ||
61 | (!isVisible && currentOpacity.current === 1)
62 | ) {
63 | Animated.timing(opacity.current, {
64 | toValue: isVisible ? 1 : 0,
65 | duration: 480,
66 | useNativeDriver: true,
67 | }).start();
68 | currentOpacity.current = isVisible ? 1 : 0;
69 | }
70 |
71 | if (value >= 0.7) {
72 | setSelectedIndex(3);
73 | } else if (value >= 0.5) {
74 | setSelectedIndex(2);
75 | } else if (value >= 0.3) {
76 | setSelectedIndex(1);
77 | } else if (value >= 0.1) {
78 | setSelectedIndex(0);
79 | }
80 | });
81 | }, [animationController]);
82 |
83 | const topViewAnim = animationController.current.interpolate({
84 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
85 | outputRange: [96 * 5, 0, 0, 0, 0], // 96 is total height of next button view
86 | });
87 | const loginTextMoveAnimation = animationController.current.interpolate({
88 | inputRange: [0, 0.2, 0.4, 0.6, 0.8],
89 | outputRange: [30 * 5, 30 * 5, 30 * 5, 30 * 5, 0], // 96 is total height of next button view
90 | });
91 |
92 | return (
93 |
99 |
102 | {dots.map(item => (
103 |
108 | ))}
109 |
110 |
111 |
112 |
113 |
119 |
120 | Already have an account?{' '}
121 |
122 | Login
123 |
124 |
125 | );
126 | };
127 |
128 | const styles = StyleSheet.create({
129 | container: {
130 | alignItems: 'center',
131 | position: 'absolute',
132 | bottom: 0,
133 | left: 0,
134 | right: 0,
135 | },
136 | dotsContainer: {
137 | flexDirection: 'row',
138 | marginBottom: 16,
139 | },
140 | pageIndicator: {
141 | width: 10,
142 | height: 10,
143 | borderRadius: 5,
144 | margin: 4,
145 | },
146 | footerTextContainer: {
147 | flexDirection: 'row',
148 | marginTop: 8,
149 | },
150 | loginText: {
151 | color: '#132137',
152 | fontSize: 16,
153 | fontFamily: 'WorkSans-Bold',
154 | },
155 | });
156 |
157 | export default CenterNextButton;
158 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 | apply plugin: "org.jetbrains.kotlin.android"
3 | apply plugin: "com.facebook.react"
4 |
5 | /**
6 | * This is the configuration block to customize your React Native Android app.
7 | * By default you don't need to apply any configuration, just uncomment the lines you need.
8 | */
9 | react {
10 | /* Folders */
11 | // The root of your project, i.e. where "package.json" lives. Default is '../..'
12 | // root = file("../../")
13 | // The folder where the react-native NPM package is. Default is ../../node_modules/react-native
14 | // reactNativeDir = file("../../node_modules/react-native")
15 | // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
16 | // codegenDir = file("../../node_modules/@react-native/codegen")
17 | // The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
18 | // cliFile = file("../../node_modules/react-native/cli.js")
19 |
20 | /* Variants */
21 | // The list of variants to that are debuggable. For those we're going to
22 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
23 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
24 | // debuggableVariants = ["liteDebug", "prodDebug"]
25 |
26 | /* Bundling */
27 | // A list containing the node command and its flags. Default is just 'node'.
28 | // nodeExecutableAndArgs = ["node"]
29 | //
30 | // The command to run when bundling. By default is 'bundle'
31 | // bundleCommand = "ram-bundle"
32 | //
33 | // The path to the CLI configuration file. Default is empty.
34 | // bundleConfig = file(../rn-cli.config.js)
35 | //
36 | // The name of the generated asset file containing your JS bundle
37 | // bundleAssetName = "MyApplication.android.bundle"
38 | //
39 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
40 | // entryFile = file("../js/MyApplication.android.js")
41 | //
42 | // A list of extra flags to pass to the 'bundle' commands.
43 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
44 | // extraPackagerArgs = []
45 |
46 | /* Hermes Commands */
47 | // The hermes compiler command to run. By default it is 'hermesc'
48 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
49 | //
50 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
51 | // hermesFlags = ["-O", "-output-source-map"]
52 |
53 | /* Autolinking */
54 | autolinkLibrariesWithApp()
55 | }
56 |
57 | project.ext.vectoricons = [
58 | iconFontNames: [ 'MaterialIcons.ttf' ]
59 | ]
60 | apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
61 |
62 |
63 | /**
64 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
65 | */
66 | def enableProguardInReleaseBuilds = false
67 |
68 | /**
69 | * The preferred build flavor of JavaScriptCore (JSC)
70 | *
71 | * For example, to use the international variant, you can use:
72 | * `def jscFlavor = io.github.react-native-community:jsc-android-intl:2026004.+`
73 | *
74 | * The international variant includes ICU i18n library and necessary data
75 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
76 | * give correct results when using with locales other than en-US. Note that
77 | * this variant is about 6MiB larger per architecture than default.
78 | */
79 | def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
80 |
81 | android {
82 | ndkVersion rootProject.ext.ndkVersion
83 | buildToolsVersion rootProject.ext.buildToolsVersion
84 | compileSdk rootProject.ext.compileSdkVersion
85 |
86 | namespace "com.react_native_ui_templates"
87 | defaultConfig {
88 | applicationId "com.react_native_ui_templates"
89 | minSdkVersion rootProject.ext.minSdkVersion
90 | targetSdkVersion rootProject.ext.targetSdkVersion
91 | versionCode 1
92 | versionName "1.0"
93 | }
94 | signingConfigs {
95 | debug {
96 | storeFile file('debug.keystore')
97 | storePassword 'android'
98 | keyAlias 'androiddebugkey'
99 | keyPassword 'android'
100 | }
101 | }
102 | buildTypes {
103 | debug {
104 | signingConfig signingConfigs.debug
105 | }
106 | release {
107 | // Caution! In production, you need to generate your own keystore file.
108 | // see https://reactnative.dev/docs/signed-apk-android.
109 | signingConfig signingConfigs.debug
110 | minifyEnabled enableProguardInReleaseBuilds
111 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
112 | }
113 | }
114 | }
115 |
116 | dependencies {
117 | // The version of react-native is set by the React Native Gradle Plugin
118 | implementation("com.facebook.react:react-android")
119 |
120 | if (hermesEnabled.toBoolean()) {
121 | implementation("com.facebook.react:hermes-android")
122 | } else {
123 | implementation jscFlavor
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/hotel_booking/CalendarPopupView.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Modal,
7 | SafeAreaView,
8 | TouchableWithoutFeedback,
9 | } from 'react-native';
10 | import { BlurView } from '@react-native-community/blur';
11 | import CustomCalendar from './CustomCalendar';
12 | import MyPressable from '../components/MyPressable';
13 |
14 | interface Props {
15 | showCal: boolean;
16 | setShowCal: any;
17 | minimumDate: Date | null;
18 | initialStartDate: Date | null;
19 | initialEndDate: Date | null;
20 | onApplyClick: (startData: Date | null, endData: Date | null) => void;
21 | }
22 |
23 | const HALF_MONTHS = [
24 | 'Jan',
25 | 'Feb',
26 | 'Mar',
27 | 'Apr',
28 | 'May',
29 | 'Jun',
30 | 'July',
31 | 'Aug',
32 | 'Sep',
33 | 'Oct',
34 | 'Nov',
35 | 'Dec',
36 | ];
37 |
38 | const WEEKS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
39 |
40 | const CustomerCalendar: React.FC = ({
41 | showCal,
42 | setShowCal,
43 | minimumDate,
44 | initialStartDate,
45 | initialEndDate,
46 | onApplyClick,
47 | }) => {
48 | const [startDate, setStartDate] = useState(initialStartDate);
49 | const [endDate, setEndDate] = useState(initialEndDate);
50 |
51 | const formattedDate = (date: Date | null) => {
52 | return date
53 | ? `${WEEKS[date?.getDay()]}, ${String(date.getDate()).padStart(2, '0')} ${
54 | HALF_MONTHS[date.getMonth()]
55 | }`
56 | : '--/--';
57 | };
58 |
59 | return (
60 | setShowCal(false)}
66 | >
67 | setShowCal(false)}
70 | >
71 |
72 |
78 | {}}>
79 |
82 |
83 |
84 | From
85 |
86 | {formattedDate(startDate)}
87 |
88 |
89 |
90 |
91 | To
92 |
93 | {formattedDate(endDate)}
94 |
95 |
96 |
97 |
98 |
99 | {
104 | setStartDate(startDateData);
105 | setEndDate(endDateData);
106 | }}
107 | />
108 |
109 |
110 |
111 | {
115 | onApplyClick(startDate, endDate);
116 | setShowCal(false);
117 | }}
118 | >
119 | Apply
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | );
129 | };
130 |
131 | const styles = StyleSheet.create({
132 | containerStyle: {
133 | flex: 1,
134 | justifyContent: 'center',
135 | backgroundColor: 'rgba(0,0,0, 0.5)',
136 | },
137 | timelineContainerStyle: {
138 | flex: 1,
139 | alignItems: 'center',
140 | justifyContent: 'center',
141 | },
142 | fromToTextStyle: {
143 | fontSize: 16,
144 | fontFamily: 'WorkSans-Regular',
145 | color: 'rgba(128, 128, 128, 0.8)',
146 | marginBottom: 4,
147 | },
148 | startEndDateTextStyles: {
149 | color: 'black',
150 | fontSize: 16,
151 | fontFamily: 'WorkSans-Bold',
152 | },
153 | applyBtnContainer: {
154 | backgroundColor: '#54D3C2',
155 | borderRadius: 24,
156 | elevation: 8,
157 | overflow: 'hidden',
158 | },
159 | applyBtn: {
160 | height: 48,
161 | alignItems: 'center',
162 | justifyContent: 'center',
163 | borderRadius: 24,
164 | },
165 | applyBtnShadow: {
166 | backgroundColor: '#54D3C2',
167 | borderRadius: 24,
168 | margin: 16,
169 | marginTop: 8,
170 | shadowColor: 'grey',
171 | shadowOffset: { width: 4, height: 4 },
172 | shadowOpacity: 0.6,
173 | shadowRadius: 8,
174 | },
175 | applyBtnText: {
176 | fontSize: 18,
177 | color: 'white',
178 | fontFamily: 'WorkSans-Medium',
179 | },
180 | verticleDivider: {
181 | height: 74,
182 | width: 1,
183 | backgroundColor: 'grey',
184 | opacity: 0.4,
185 | },
186 | });
187 |
188 | export default CustomerCalendar;
189 |
--------------------------------------------------------------------------------
/src/HomeScene.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from 'react';
2 | import {
3 | StyleSheet,
4 | Image,
5 | Animated,
6 | ListRenderItemInfo,
7 | View,
8 | Text,
9 | FlatList,
10 | Easing,
11 | useWindowDimensions,
12 | GestureResponderEvent,
13 | } from 'react-native';
14 | import {
15 | SafeAreaView,
16 | useSafeAreaInsets,
17 | } from 'react-native-safe-area-context';
18 | import { useNavigation } from '@react-navigation/native';
19 | import Icon from 'react-native-vector-icons/MaterialIcons';
20 | import MyPressable from './components/MyPressable';
21 | import { AppImages } from './assets';
22 | import { showToast } from './util/action';
23 |
24 | const DEMOS = [
25 | {
26 | name: 'onBoarding',
27 | background: AppImages.introduction_animation,
28 | screenName: 'onBoarding',
29 | },
30 | {
31 | name: 'hotel',
32 | background: AppImages.hotel_booking,
33 | screenName: 'Hotel',
34 | },
35 | {
36 | name: 'fitness_app',
37 | background: AppImages.fitness_app,
38 | screenName: '',
39 | },
40 | {
41 | name: 'design_course',
42 | background: AppImages.design_course,
43 | screenName: 'DesignCourse',
44 | },
45 | ];
46 |
47 | interface ListItemProps {
48 | data: ListRenderItemInfo<(typeof DEMOS)[0]>;
49 | isGrid: boolean;
50 | onScreenClicked: ((event: GestureResponderEvent) => void) | null | undefined;
51 | }
52 |
53 | const ListItem: React.FC = ({
54 | data,
55 | isGrid,
56 | onScreenClicked,
57 | }) => {
58 | const { index, item } = data;
59 |
60 | const { width } = useWindowDimensions();
61 |
62 | const translateY = useRef(new Animated.Value(50)).current;
63 | const opacity = useRef(new Animated.Value(0)).current;
64 |
65 | useEffect(() => {
66 | Animated.parallel([
67 | Animated.timing(translateY, {
68 | toValue: 0,
69 | duration: 1000,
70 | delay: index * (1000 / 3),
71 | easing: Easing.bezier(0.4, 0.0, 0.2, 1.0),
72 | useNativeDriver: true,
73 | }),
74 | Animated.timing(opacity, {
75 | toValue: 1,
76 | duration: 1000,
77 | delay: index * (1000 / 3),
78 | useNativeDriver: true,
79 | }),
80 | ]).start();
81 | });
82 |
83 | const itemWidth = isGrid ? (width - 36) / 2 : width - 24;
84 |
85 | return (
86 |
96 |
104 |
105 |
111 |
112 | );
113 | };
114 |
115 | const HomeScene: React.FC = () => {
116 | const navigation = useNavigation();
117 | const inset = useSafeAreaInsets();
118 |
119 | const [isGrid, setGrid] = useState(true);
120 |
121 | const onTemplateClicked = (temp: (typeof DEMOS)[0]) => {
122 | if (temp.screenName) {
123 | navigation.navigate(temp.screenName);
124 | } else {
125 | showToast('Coming soon...');
126 | }
127 | };
128 |
129 | return (
130 |
134 |
135 | navigation.toggleDrawer()}
140 | >
141 |
142 |
143 | React-Native UI
144 | setGrid(!isGrid)}
149 | >
150 |
155 |
156 |
157 |
158 | (
166 | onTemplateClicked(data.item)}
169 | />
170 | )}
171 | keyExtractor={item => item.name}
172 | />
173 |
174 | );
175 | };
176 |
177 | const styles = StyleSheet.create({
178 | headerContainer: {
179 | height: 52,
180 | flexDirection: 'row',
181 | alignItems: 'center',
182 | paddingHorizontal: 8,
183 | paddingBottom: 0,
184 | },
185 | headerText: {
186 | flex: 1,
187 | color: 'black',
188 | fontSize: 22,
189 | fontFamily: 'WorkSans-Bold',
190 | textAlign: 'center',
191 | textAlignVertical: 'center',
192 | },
193 | demoImg: {
194 | width: '100%',
195 | height: '100%',
196 | borderRadius: 4,
197 | },
198 | demoPressable: {
199 | ...StyleSheet.absoluteFillObject,
200 | backgroundColor: 'rgba(128,128,128,0.1)',
201 | borderRadius: 4,
202 | },
203 | });
204 |
205 | export default HomeScene;
206 |
--------------------------------------------------------------------------------
/src/hotel_booking/Switch.tsx:
--------------------------------------------------------------------------------
1 | // This component is taken from wix/react-native-ui-lib.
2 | // ref:- "https://github.com/wix/react-native-ui-lib/blob/master/src/components/switch/index.tsx"
3 | import React, { Component } from 'react';
4 | import {
5 | TouchableOpacity,
6 | StyleSheet,
7 | Animated,
8 | Easing,
9 | StyleProp,
10 | ViewStyle,
11 | I18nManager,
12 | } from 'react-native';
13 |
14 | const INNER_PADDING = 2;
15 | const DEFAULT_WIDTH = 50;
16 | const DEFAULT_HEIGHT = 30;
17 | const DEFAULT_THUMB_SIZE = 26;
18 |
19 | export type SwitchProps = {
20 | /**
21 | * The value of the switch. If true the switch will be turned on. Default value is false
22 | */
23 | value?: boolean;
24 | /**
25 | * Invoked with the new value when the value changes
26 | */
27 | onValueChange?: (value: boolean) => void;
28 | /**
29 | * Whether the switch should be disabled
30 | */
31 | disabled?: boolean;
32 | /**
33 | * The Switch width
34 | */
35 | width?: number;
36 | /**
37 | * The Switch height
38 | */
39 | height?: number;
40 | /**
41 | * The Switch background color when it's turned on
42 | */
43 | onColor?: string;
44 | /**
45 | * The Switch background color when it's turned off
46 | */
47 | offColor?: string;
48 | /**
49 | * The Switch background color when it's disabled
50 | */
51 | disabledColor?: string;
52 | /**
53 | * The Switch's thumb color
54 | */
55 | thumbColor?: string;
56 | /**
57 | * The Switch's thumb size (width & height)
58 | */
59 | thumbSize?: number;
60 | /**
61 | * The Switch's thumb style
62 | */
63 | thumbStyle?: object /* | number | [] */;
64 | style?: StyleProp;
65 | testID?: string;
66 | };
67 |
68 | /**
69 | * Switch component for toggling boolean value related to some context
70 | */
71 | class Switch extends Component {
72 | static displayName = 'Switch';
73 |
74 | state = {
75 | thumbPosition: new Animated.Value(this.props.value ? 1 : 0),
76 | };
77 |
78 | styles = createStyles(this.props);
79 |
80 | componentDidUpdate(prevProps: SwitchProps) {
81 | const { value } = this.props;
82 | if (prevProps.value !== value) {
83 | this.toggle(value);
84 | }
85 | }
86 |
87 | getAccessibilityProps() {
88 | const { disabled, value } = this.props;
89 |
90 | return {
91 | accessible: true,
92 | accessibilityRole: 'switch',
93 | accessibilityState: {
94 | disabled,
95 | checked: value ? 'checked' : 'unchecked',
96 | },
97 | accessibilityValue: { text: value ? '1' : '0' },
98 | };
99 | }
100 |
101 | toggle(value?: boolean) {
102 | const { thumbPosition } = this.state;
103 |
104 | Animated.timing(thumbPosition, {
105 | toValue: value ? 1 : 0,
106 | duration: 200,
107 | easing: Easing.bezier(0.77, 0.0, 0.175, 1.0),
108 | useNativeDriver: true,
109 | }).start();
110 | }
111 |
112 | onPress = () => {
113 | const { disabled } = this.props;
114 |
115 | if (!disabled) {
116 | this.props.onValueChange?.(!this.props.value);
117 | }
118 | };
119 |
120 | calcThumbOnPosition() {
121 | const props = this.props;
122 | const width = props.width || DEFAULT_WIDTH;
123 | const thumbSize = props.thumbSize || DEFAULT_THUMB_SIZE;
124 | let position = width - (2 * INNER_PADDING + thumbSize);
125 | position *= I18nManager.isRTL ? -1 : 1;
126 | return position;
127 | }
128 |
129 | getSwitchStyle() {
130 | const {
131 | value,
132 | onColor,
133 | offColor,
134 | style: propsStyle,
135 | disabled,
136 | disabledColor,
137 | } = this.props;
138 | const style: SwitchProps['style'] = [this.styles.switch];
139 |
140 | if (disabled) {
141 | style.push(
142 | disabledColor
143 | ? { backgroundColor: disabledColor }
144 | : this.styles.switchDisabled,
145 | );
146 | } else if (value) {
147 | style.push(onColor ? { backgroundColor: onColor } : this.styles.switchOn);
148 | } else {
149 | style.push(
150 | offColor ? { backgroundColor: offColor } : this.styles.switchOff,
151 | );
152 | }
153 |
154 | style.push(propsStyle);
155 | return style;
156 | }
157 |
158 | renderThumb() {
159 | const { thumbStyle } = this.props;
160 | const { thumbPosition } = this.state;
161 |
162 | const interpolatedTranslateX = thumbPosition.interpolate({
163 | inputRange: [0, 1],
164 | outputRange: [0, this.calcThumbOnPosition()],
165 | });
166 |
167 | const thumbPositionStyle = {
168 | transform: [{ translateX: interpolatedTranslateX }],
169 | };
170 |
171 | return (
172 |
175 | );
176 | }
177 |
178 | render() {
179 | return (
180 | // @ts-ignore
181 |
187 | {this.renderThumb()}
188 |
189 | );
190 | }
191 | }
192 |
193 | function createStyles({
194 | width = DEFAULT_WIDTH,
195 | height = DEFAULT_HEIGHT,
196 | onColor = '#54D3C2',
197 | offColor = 'rgba(158,158,158, 0.3)', // 'lightgrey'
198 | disabledColor = 'lightgrey',
199 | thumbColor = 'white',
200 | thumbSize = DEFAULT_THUMB_SIZE,
201 | }) {
202 | return StyleSheet.create({
203 | switch: {
204 | width,
205 | height,
206 | borderRadius: 999,
207 | justifyContent: 'center',
208 | padding: INNER_PADDING,
209 | },
210 | switchOn: {
211 | backgroundColor: onColor,
212 | },
213 | switchOff: {
214 | backgroundColor: offColor,
215 | },
216 | switchDisabled: {
217 | backgroundColor: disabledColor,
218 | },
219 | thumb: {
220 | width: thumbSize,
221 | height: thumbSize,
222 | borderRadius: thumbSize / 2,
223 | backgroundColor: thumbColor,
224 | },
225 | });
226 | }
227 |
228 | export default Switch;
229 |
--------------------------------------------------------------------------------
/src/design_course/HomeDesignCourse.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | StatusBar,
7 | Image,
8 | TextInput,
9 | useWindowDimensions,
10 | FlatList,
11 | } from 'react-native';
12 | import { useSafeAreaInsets } from 'react-native-safe-area-context';
13 | import { useNavigation } from '@react-navigation/native';
14 | import Icon from 'react-native-vector-icons/MaterialIcons';
15 | import CategoryListView from './CategoryListView';
16 | import PopulerCourseListView from './PopulerCourseListView';
17 | import MyPressable from '../components/MyPressable';
18 | import { CATEGORY_LIST, POPULAR_COURSE_LIST } from './model/category';
19 | import { AppImages } from '../assets';
20 | import Config from '../Config';
21 |
22 | interface CategoryBtn {
23 | text: string;
24 | selectedCat: string;
25 | onPress: () => void;
26 | }
27 |
28 | const CATEGORIES = ['Ui/Ux', 'Coding', 'Basic UI'];
29 |
30 | const CategoryButton = ({ text, selectedCat, onPress }: CategoryBtn) => (
31 | <>
32 |
33 |
34 |
35 | {text}
36 |
37 |
38 |
39 | {text !== CATEGORIES[2] && }
40 | >
41 | );
42 |
43 | const HomeDesignCourse: React.FC = () => {
44 | const { width } = useWindowDimensions();
45 | const insets = useSafeAreaInsets();
46 | const navigation = useNavigation();
47 |
48 | const [selectedCategory, setSelectedCategory] = useState('Ui/Ux');
49 |
50 | const paddingTop = Config.isIos
51 | ? Math.max(insets.top, 20)
52 | : StatusBar.currentHeight;
53 |
54 | const renderScrollableHeader = (
55 | <>
56 |
57 |
58 |
68 |
69 |
70 |
71 | Category
72 |
73 | {CATEGORIES.map(text => (
74 | setSelectedCategory(text)}
79 | />
80 | ))}
81 |
82 |
83 | (
89 | navigation.navigate('CourseInfo')}
92 | />
93 | )}
94 | keyExtractor={item => item.id.toString()}
95 | />
96 | Popular Course
97 | >
98 | );
99 |
100 | return (
101 |
102 |
103 |
104 |
105 | Choose your
106 | Design Course
107 |
108 |
112 |
113 |
114 | }
125 | renderItem={data => (
126 | navigation.navigate('CourseInfo')}
129 | />
130 | )}
131 | keyExtractor={item => item.id.toString()}
132 | />
133 |
134 | );
135 | };
136 |
137 | const styles = StyleSheet.create({
138 | searchInputMainContainer: {
139 | marginTop: 8,
140 | marginLeft: 18,
141 | height: 64,
142 | },
143 | searchInputContainer: {
144 | flexDirection: 'row',
145 | backgroundColor: '#F8FAFB',
146 | marginVertical: 8,
147 | borderRadius: 13,
148 | paddingHorizontal: 16,
149 | alignItems: 'center',
150 | },
151 | searchInput: {
152 | flex: 1,
153 | fontSize: 16,
154 | fontFamily: 'WorkSans-SemiBold',
155 | color: 'dodgerblue',
156 | },
157 | sectionHeaderText: {
158 | color: 'black',
159 | fontSize: 22,
160 | fontFamily: 'WorkSans-SemiBold',
161 | letterSpacing: 0.27,
162 | paddingTop: 8,
163 | paddingLeft: 18,
164 | paddingRight: 16,
165 | marginBottom: 16,
166 | },
167 | categoryRowContainer: {
168 | flexDirection: 'row',
169 | paddingHorizontal: 16,
170 | marginBottom: 8,
171 | },
172 | header: {
173 | flexDirection: 'row',
174 | paddingTop: 8,
175 | paddingHorizontal: 18,
176 | },
177 | headerTextNormal: {
178 | color: 'grey',
179 | fontFamily: 'WorkSans-Regular',
180 | letterSpacing: 0.2,
181 | },
182 | headerTextBold: {
183 | color: 'black',
184 | fontSize: 22,
185 | fontFamily: 'WorkSans-Bold',
186 | letterSpacing: 0.2,
187 | },
188 | });
189 |
190 | const styleCatrgory = (selected: boolean) =>
191 | StyleSheet.create({
192 | categoryBtnContainer: {
193 | flex: 1,
194 | overflow: 'hidden',
195 | borderRadius: 24,
196 | borderColor: 'rgb(0, 182, 240)',
197 | borderWidth: 1,
198 | backgroundColor: selected ? 'rgb(0, 182, 240)' : 'transparent',
199 | },
200 | categoryBtnText: {
201 | padding: 18,
202 | paddingVertical: 12,
203 | fontSize: 12,
204 | fontFamily: 'WorkSans-SemiBold',
205 | letterSpacing: 0.27,
206 | alignSelf: 'center',
207 | color: selected ? 'white' : 'rgb(0, 182, 240)',
208 | },
209 | });
210 |
211 | export default HomeDesignCourse;
212 |
--------------------------------------------------------------------------------
/src/DrawerContent.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | useWindowDimensions,
7 | Image,
8 | ViewStyle,
9 | StyleProp,
10 | } from 'react-native';
11 | import { SafeAreaView } from 'react-native-safe-area-context';
12 | import {
13 | DrawerContentComponentProps,
14 | DrawerContentScrollView,
15 | useDrawerProgress,
16 | } from '@react-navigation/drawer';
17 | import { DrawerActions, NavigationState } from '@react-navigation/native';
18 | import Animated, {
19 | AnimatedStyle,
20 | interpolate,
21 | SharedValue,
22 | useAnimatedStyle,
23 | } from 'react-native-reanimated';
24 | import Icon from 'react-native-vector-icons/MaterialIcons';
25 | import MyPressable from './components/MyPressable';
26 | import { AppImages } from './assets';
27 |
28 | type DrawerScene = {
29 | label: string;
30 | icon: any;
31 | isAssetIcon?: boolean;
32 | routeKey?: string;
33 | };
34 |
35 | interface DrawerItemProps extends DrawerScene {
36 | bgAnimStyle: AnimatedStyle>;
37 | }
38 |
39 | const DRAWER_SCENES: DrawerScene[] = [
40 | { label: 'Home', icon: 'home', routeKey: 'home' },
41 | {
42 | label: 'Help',
43 | icon: AppImages.support_icon,
44 | isAssetIcon: true,
45 | routeKey: 'help',
46 | },
47 | { label: 'Feedback', icon: 'help', routeKey: 'feedback' },
48 | { label: 'Invite Friend', icon: 'group', routeKey: 'invite_friend' },
49 | { label: 'Rate the app', icon: 'share' },
50 | { label: 'About Us', icon: 'info' },
51 | ];
52 |
53 | const getActiveRouteState = (
54 | routes: NavigationState['routes'],
55 | index: number,
56 | routeKey: string,
57 | ) => routes[index].name.toLowerCase().indexOf(routeKey?.toLowerCase()) >= 0;
58 |
59 | const DrawerItemRow: React.FC<
60 | DrawerItemProps & DrawerContentComponentProps
61 | > = props => {
62 | const {
63 | state,
64 | label,
65 | icon,
66 | isAssetIcon = false,
67 | routeKey,
68 | bgAnimStyle,
69 | } = props;
70 | const { routes, index } = state;
71 |
72 | const sceneOptions = props.descriptors[routes[index].key]?.options;
73 |
74 | const window = useWindowDimensions();
75 | const rowWidth = (window.width * 0.75 * 80) / 100;
76 |
77 | const focused = routeKey
78 | ? getActiveRouteState(routes, index, routeKey)
79 | : false;
80 |
81 | const tintColor = focused
82 | ? sceneOptions?.drawerActiveBackgroundColor
83 | : 'black';
84 |
85 | return (
86 |
90 | routeKey
91 | ? props.navigation.navigate(routeKey)
92 | : props.navigation.dispatch(DrawerActions.closeDrawer())
93 | }
94 | >
95 |
107 |
108 | {isAssetIcon ? (
109 |
114 | ) : (
115 |
116 | )}
117 |
121 | {label}
122 |
123 |
124 |
125 | );
126 | };
127 |
128 | const DrawerContent: React.FC = props => {
129 | const window = useWindowDimensions();
130 | const rowWidth = (window.width * 0.75 * 80) / 100;
131 | const progress = useDrawerProgress();
132 |
133 | const drawerStyle = useAnimatedStyle(() => {
134 | const drawerProgress = progress as SharedValue;
135 |
136 | return {
137 | transform: [
138 | { rotate: `${interpolate(drawerProgress.value, [0, 1], [0.2, 0])}rad` },
139 | { scale: interpolate(drawerProgress.value, [0, 1], [0.9, 1]) },
140 | ],
141 | };
142 | }, []);
143 | const bgAnimStyle = useAnimatedStyle(() => {
144 | const drawerProgress = progress as SharedValue;
145 |
146 | return {
147 | transform: [
148 | {
149 | translateX: interpolate(drawerProgress.value, [0, 1], [-rowWidth, 0]),
150 | },
151 | ],
152 | };
153 | }, []);
154 |
155 | return (
156 |
157 |
158 |
161 |
165 |
166 | Chris Hemsworth
167 |
168 |
169 |
170 |
174 | {DRAWER_SCENES.map(scene => (
175 |
179 | ))}
180 |
181 |
182 |
183 | Sign Out
184 |
185 |
186 |
187 | );
188 | };
189 |
190 | const styles = StyleSheet.create({
191 | userName: {
192 | fontSize: 18,
193 | color: '#3A5160',
194 | fontFamily: 'WorkSans-SemiBold',
195 | paddingTop: 8,
196 | paddingLeft: 4,
197 | },
198 | drawerRowStyle: {
199 | marginHorizontal: 0,
200 | paddingVertical: 8,
201 | justifyContent: 'center',
202 | overflow: 'hidden',
203 | },
204 | drawerRowbackViewStyle: {
205 | opacity: 0.3,
206 | height: 48,
207 | borderRadius: 24,
208 | borderTopStartRadius: 0,
209 | borderBottomStartRadius: 0,
210 | },
211 | drawerRowTextStyle: {
212 | fontSize: 16,
213 | marginLeft: 10,
214 | fontWeight: '500',
215 | },
216 | drawerRowContentContainer: {
217 | flexDirection: 'row',
218 | padding: 8,
219 | paddingHorizontal: 16,
220 | position: 'absolute',
221 | },
222 | drawerAvatarStyle: {
223 | width: 120,
224 | height: 120,
225 | borderRadius: 60,
226 | },
227 | avatarShadow: {
228 | backgroundColor: 'white',
229 | elevation: 24,
230 | shadowColor: '#3A5160',
231 | shadowOffset: { width: 2, height: 4 },
232 | shadowOpacity: 0.6,
233 | shadowRadius: 8,
234 | },
235 | divider: {
236 | backgroundColor: 'darkgrey',
237 | height: StyleSheet.hairlineWidth,
238 | },
239 | signOutBtnStyle: {
240 | flexDirection: 'row',
241 | padding: 16,
242 | borderTopWidth: StyleSheet.hairlineWidth,
243 | borderColor: 'darkgrey',
244 | },
245 | signOutText: {
246 | flex: 1,
247 | color: 'black',
248 | fontSize: 16,
249 | fontFamily: 'WorkSans-SemiBold',
250 | },
251 | });
252 |
253 | export default DrawerContent;
254 |
--------------------------------------------------------------------------------
/src/hotel_booking/HotelHomeScreen.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useState } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | TextInput,
7 | FlatList,
8 | useWindowDimensions,
9 | ListRenderItemInfo,
10 | } from 'react-native';
11 | import { useSafeAreaInsets } from 'react-native-safe-area-context';
12 | import { useNavigation } from '@react-navigation/native';
13 | import Icon from 'react-native-vector-icons/MaterialIcons';
14 | import CustomerCalendar from './CalendarPopupView';
15 | import FilterModal from './FiltersModal';
16 | import HotelListItem from './HotelListItem';
17 | import MyPressable from '../components/MyPressable';
18 | import { HOTEL_LIST, HotelListType } from './model/hotel_list_data';
19 |
20 | const HALF_MONTHS = [
21 | 'Jan',
22 | 'Feb',
23 | 'Mar',
24 | 'Apr',
25 | 'May',
26 | 'Jun',
27 | 'July',
28 | 'Aug',
29 | 'Sep',
30 | 'Oct',
31 | 'Nov',
32 | 'Dec',
33 | ];
34 |
35 | const HotelHomeScreen: React.FC = () => {
36 | const window = useWindowDimensions();
37 | const inset = useSafeAreaInsets();
38 | const navigation = useNavigation();
39 |
40 | const [startDate, setStartDate] = useState(new Date());
41 | const [endDate, setEndDate] = useState(() => {
42 | const date = new Date();
43 | date.setDate(date.getDate() + 5);
44 | return date;
45 | });
46 | const [showCal, setShowCal] = useState(false);
47 | const [showFilter, setShowFilter] = useState(false);
48 |
49 | const contentHeader = (
50 |
51 |
52 |
58 |
59 |
64 |
65 |
66 |
67 |
68 |
69 | setShowCal(true)}
73 | >
74 | Choose date
75 |
76 | {`${String(startDate.getDate()).padStart(2, '0')}, ${
77 | HALF_MONTHS[startDate.getMonth()]
78 | } - ${String(endDate.getDate()).padStart(2, '0')}, ${
79 | HALF_MONTHS[endDate.getMonth()]
80 | }`}
81 |
82 |
83 |
84 |
85 | Number of Rooms
86 | 1 Room - 2 Adults
87 |
88 |
89 |
90 | );
91 |
92 | const renderItem = useCallback(
93 | (data: ListRenderItemInfo) =>
94 | data.index > 0 ? (
95 |
96 | ) : (
97 |
98 | 530 hotels found
99 |
100 | setShowFilter(true)}
103 | >
104 | Filter
105 |
111 |
112 |
113 |
114 | ),
115 | [],
116 | );
117 |
118 | return (
119 | <>
120 | {/* Header */}
121 |
127 |
128 |
133 |
134 |
135 |
136 |
142 |
143 | Explore
144 |
145 |
146 |
147 |
153 |
159 |
160 |
161 |
162 |
163 | item.id.toString()}
171 | />
172 |
173 |
174 | {
180 | if (startData != null && endData != null) {
181 | setStartDate(startData);
182 | setEndDate(endData);
183 | }
184 | }}
185 | />
186 |
187 | >
188 | );
189 | };
190 |
191 | const styles = StyleSheet.create({
192 | header: {
193 | flexDirection: 'row',
194 | alignItems: 'center',
195 | backgroundColor: 'white',
196 | paddingHorizontal: 8,
197 | borderBottomWidth: StyleSheet.hairlineWidth,
198 | borderBottomColor: 'lightgrey',
199 | },
200 | headerLeft: {
201 | alignItems: 'flex-start',
202 | flexGrow: 1,
203 | flexBasis: 0,
204 | },
205 | headerTitle: {
206 | color: 'black',
207 | fontSize: 22,
208 | fontFamily: 'WorkSans-SemiBold',
209 | textAlign: 'center',
210 | },
211 | headerRight: {
212 | flexDirection: 'row',
213 | justifyContent: 'flex-end',
214 | flexGrow: 1,
215 | flexBasis: 0,
216 | },
217 | container: {
218 | flex: 1,
219 | backgroundColor: 'rgb(242, 242, 242)',
220 | },
221 | list: {
222 | flexGrow: 1,
223 | backgroundColor: 'white',
224 | },
225 | searchInput: {
226 | flex: 1,
227 | backgroundColor: 'white',
228 | borderRadius: 32,
229 | paddingHorizontal: 16,
230 | paddingVertical: 12,
231 | marginRight: 16,
232 | color: 'black',
233 | fontSize: 18,
234 | elevation: 8,
235 | shadowColor: 'lightgrey',
236 | shadowOffset: { width: 0, height: 4 },
237 | shadowOpacity: 0.3,
238 | shadowRadius: 4.65,
239 | },
240 | searchBtnContainer: {
241 | borderRadius: 36,
242 | elevation: 12,
243 | },
244 | searchBtn: {
245 | padding: 12,
246 | backgroundColor: '#54D3C2',
247 | borderRadius: 36,
248 | shadowColor: 'grey',
249 | shadowOffset: { width: 4, height: 4 },
250 | shadowOpacity: 0.3,
251 | shadowRadius: 12,
252 | },
253 | headerDetailContainer: {
254 | flexDirection: 'row',
255 | paddingHorizontal: 16,
256 | paddingBottom: 16,
257 | },
258 | headerDetailTitle: {
259 | color: 'darkgrey',
260 | fontSize: 16,
261 | marginBottom: 8,
262 | fontFamily: 'WorkSans-Regular',
263 | },
264 | sectionText: {
265 | color: 'black',
266 | fontSize: 16,
267 | fontFamily: 'WorkSans-Regular',
268 | },
269 | verticalDivider: {
270 | width: 1,
271 | backgroundColor: 'darkgrey',
272 | marginRight: 8,
273 | marginVertical: 8,
274 | },
275 | headerSectionContainer: {
276 | flex: 1,
277 | paddingHorizontal: 8,
278 | paddingVertical: 4,
279 | },
280 | stickyHeaderContainer: {
281 | backgroundColor: 'white',
282 | flexDirection: 'row',
283 | paddingHorizontal: 24,
284 | paddingVertical: 8,
285 | },
286 | hotelCountText: {
287 | flex: 1,
288 | color: 'black',
289 | fontSize: 16,
290 | alignSelf: 'center',
291 | fontFamily: 'WorkSans-Regular',
292 | },
293 | });
294 |
295 | export default HotelHomeScreen;
296 |
--------------------------------------------------------------------------------
/src/hotel_booking/FiltersModal.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | Modal,
7 | SafeAreaView,
8 | StatusBar,
9 | ScrollView,
10 | } from 'react-native';
11 | import Icon from 'react-native-vector-icons/MaterialIcons';
12 | import RangeSliderView from './RangeSliderView';
13 | import SliderView from './SliderView';
14 | import MyPressable from '../components/MyPressable';
15 | import MySwitch from './Switch';
16 | import Config from '../Config';
17 |
18 | interface Props {
19 | showFilter: boolean;
20 | setShowFilter: any;
21 | }
22 |
23 | const popularFList = [
24 | { titleTxt: 'Free Breakfast', isSelected: false },
25 | { titleTxt: 'Free Parking', isSelected: false },
26 | { titleTxt: 'Pool', isSelected: true },
27 | { titleTxt: 'Pet Friendly', isSelected: false },
28 | { titleTxt: 'Free wifi', isSelected: false },
29 | ];
30 |
31 | const accomodation_List = [
32 | { titleTxt: 'All', isSelected: false },
33 | { titleTxt: 'Apartment', isSelected: false },
34 | { titleTxt: 'Home', isSelected: true },
35 | { titleTxt: 'Villa', isSelected: false },
36 | { titleTxt: 'Hotel', isSelected: false },
37 | { titleTxt: 'Resort', isSelected: false },
38 | ];
39 |
40 | const FilterModal: React.FC = ({ showFilter, setShowFilter }) => {
41 | const [popularFilterList, setPopularFilterList] = useState(popularFList);
42 | const [accomodationList, setAccomodationList] = useState(accomodation_List);
43 |
44 | const getPList = () => {
45 | const noList: React.JSX.Element[] = [];
46 | let count = 0;
47 | const columnCount = 2;
48 |
49 | for (let i = 0; i < popularFilterList.length / columnCount; i++) {
50 | const listUI: React.JSX.Element[] = [];
51 | for (let j = 0; j < columnCount; j++) {
52 | const data = popularFilterList[count];
53 | listUI.push(
54 |
58 | {
62 | data.isSelected = !data.isSelected;
63 | setPopularFilterList([...popularFilterList]);
64 | }}
65 | >
66 |
71 | {data.titleTxt}
72 |
73 | ,
74 | );
75 |
76 | if (count < popularFilterList.length - 1) {
77 | count += 1;
78 | } else {
79 | break;
80 | }
81 | }
82 | noList.push(
83 |
84 | {listUI}
85 | ,
86 | );
87 | }
88 |
89 | return noList;
90 | };
91 |
92 | const checkAppPosition = (index: number) => {
93 | if (index === 0) {
94 | const isAllSelected = accomodationList[0].isSelected;
95 | accomodationList.forEach(d => (d.isSelected = !isAllSelected));
96 | } else {
97 | accomodationList[index].isSelected = !accomodationList[index].isSelected;
98 |
99 | let count = 0;
100 | for (let i = 0; i < accomodationList.length; i++) {
101 | if (i !== 0) {
102 | const data = accomodationList[i];
103 | if (data.isSelected) {
104 | count += 1;
105 | }
106 | }
107 | }
108 |
109 | accomodationList[0].isSelected = count === accomodationList.length - 1;
110 | }
111 |
112 | setAccomodationList([...accomodationList]);
113 | };
114 |
115 | const getAccomodationListUI = () => {
116 | const noList: React.JSX.Element[] = [];
117 | for (let i = 0; i < accomodationList.length; i++) {
118 | const data = accomodationList[i];
119 | noList.push(
120 |
121 | checkAppPosition(i)}
125 | >
126 | {data.titleTxt}
127 | checkAppPosition(i)}
133 | />
134 |
135 | ,
136 | );
137 | if (i === 0) {
138 | noList.push();
139 | }
140 | }
141 | return noList;
142 | };
143 |
144 | return (
145 | setShowFilter(false)}
150 | >
151 |
152 |
153 |
154 |
155 | setShowFilter(false)}
160 | >
161 |
162 |
163 |
164 | Filters
165 |
166 |
167 |
168 |
169 |
173 | Price (for 1 night)
174 |
175 |
176 |
177 |
178 | Popular filters
179 |
180 | {getPList()}
181 |
182 |
183 |
186 | Distance from city center
187 |
188 |
189 |
190 |
191 |
194 | Type of Accommodation
195 |
196 |
197 | {getAccomodationListUI()}
198 |
199 |
200 |
201 |
202 |
203 |
204 | setShowFilter(false)}
208 | >
209 | Apply
210 |
211 |
212 |
213 |
214 |
215 | );
216 | };
217 |
218 | const styles = StyleSheet.create({
219 | header: {
220 | flexDirection: 'row',
221 | alignItems: 'center',
222 | padding: 8,
223 | },
224 | headerText: {
225 | color: 'black',
226 | fontSize: 22,
227 | fontFamily: 'WorkSans-Bold',
228 | textAlign: 'center',
229 | textAlignVertical: 'center',
230 | },
231 | headerShadow: {
232 | height: Config.isAndroid ? 0.2 : 1,
233 | elevation: 4,
234 | backgroundColor: 'lightgrey',
235 | },
236 | divider: { height: StyleSheet.hairlineWidth, backgroundColor: 'lightgrey' },
237 | sectionTitle: {
238 | fontSize: 18,
239 | fontFamily: 'WorkSans-Regular',
240 | color: 'darkgrey',
241 | paddingHorizontal: 16,
242 | },
243 | checkBoxBtn: {
244 | alignSelf: 'flex-start',
245 | alignItems: 'center',
246 | flexDirection: 'row',
247 | padding: 8,
248 | },
249 | checkTitle: {
250 | color: 'black',
251 | marginStart: 4,
252 | fontFamily: 'WorkSans-Regular',
253 | },
254 | switchText: {
255 | flex: 1,
256 | color: 'black',
257 | fontFamily: 'WorkSans-Regular',
258 | alignSelf: 'center',
259 | },
260 | buttonContainer: {
261 | backgroundColor: '#54D3C2',
262 | borderRadius: 24,
263 | elevation: 8,
264 | overflow: 'hidden',
265 | },
266 | button: {
267 | height: 48,
268 | alignItems: 'center',
269 | justifyContent: 'center',
270 | borderRadius: 24,
271 | },
272 | applyBtnShadow: {
273 | backgroundColor: '#54D3C2',
274 | borderRadius: 24,
275 | margin: 16,
276 | marginTop: 8,
277 | shadowColor: 'grey',
278 | shadowOffset: { width: 4, height: 4 },
279 | shadowOpacity: 0.6,
280 | shadowRadius: 8,
281 | },
282 | buttonText: {
283 | fontSize: 18,
284 | color: 'white',
285 | fontFamily: 'WorkSans-Medium',
286 | },
287 | });
288 |
289 | export default FilterModal;
290 |
--------------------------------------------------------------------------------
/src/design_course/CourseInfoScreen.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef } from 'react';
2 | import {
3 | StyleSheet,
4 | View,
5 | Text,
6 | StatusBar,
7 | ImageBackground,
8 | useWindowDimensions,
9 | ScrollView,
10 | Platform,
11 | Animated,
12 | Easing,
13 | } from 'react-native';
14 | import { useSafeAreaInsets } from 'react-native-safe-area-context';
15 | import { useNavigation } from '@react-navigation/native';
16 | import Icon from 'react-native-vector-icons/MaterialIcons';
17 | import MyPressable from '../components/MyPressable';
18 | import { AppImages } from '../assets';
19 | import Config from '../Config';
20 |
21 | const infoHeight = 364.0;
22 |
23 | const CourseInfoScreen: React.FC = () => {
24 | const window = useWindowDimensions();
25 | const navigation = useNavigation();
26 | const insets = useSafeAreaInsets();
27 |
28 | const favIconScale = useRef(new Animated.Value(0.1));
29 | const opacity1 = useRef(new Animated.Value(0));
30 | const opacity2 = useRef(new Animated.Value(0));
31 | const opacity3 = useRef(new Animated.Value(0));
32 |
33 | // const tempHeight = window.height - window.width / 1.2 + 24.0;
34 | const marginTop = Config.isIos
35 | ? Math.max(insets.top, 20)
36 | : StatusBar.currentHeight;
37 |
38 | useEffect(() => {
39 | Animated.timing(favIconScale.current, {
40 | toValue: 1,
41 | duration: 1000,
42 | easing: Easing.out(Easing.cubic),
43 | useNativeDriver: true,
44 | }).start();
45 |
46 | Animated.parallel([
47 | Animated.timing(opacity1.current, {
48 | toValue: 1,
49 | duration: 500,
50 | delay: 200,
51 | useNativeDriver: true,
52 | }),
53 | Animated.timing(opacity2.current, {
54 | toValue: 1,
55 | duration: 500,
56 | delay: 400,
57 | useNativeDriver: true,
58 | }),
59 | Animated.timing(opacity3.current, {
60 | toValue: 1,
61 | duration: 500,
62 | delay: 600,
63 | useNativeDriver: true,
64 | }),
65 | ]).start();
66 | }, []);
67 |
68 | const getTimeBoxUI = (text1: string, text2: string) => (
69 |
70 | {text1}
71 | {text2}
72 |
73 | );
74 |
75 | return (
76 |
77 |
78 |
83 |
89 | infoHeight ? tempHeight : infoHeight,
95 | }}
96 | >
97 | {'Web Design\nCourse'}
98 |
99 | $28.99
100 | 4.3
101 |
102 |
103 |
107 | {getTimeBoxUI('24', 'Classes')}
108 | {getTimeBoxUI('2 hours', 'Time')}
109 | {getTimeBoxUI('24', 'Seat')}
110 |
111 |
115 | Lorem ipsum is simply dummy text of printing & typesetting
116 | industry, Lorem ipsum is simply dummy text of printing &
117 | typesetting industry.
118 |
119 |
120 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | Join Course
134 |
135 |
136 |
137 |
138 |
139 |
148 |
149 |
150 |
151 | navigation.goBack()}
155 | >
156 |
157 |
158 |
159 |
160 | );
161 | };
162 |
163 | const styles = StyleSheet.create({
164 | contentContainer: {
165 | flex: 1,
166 | backgroundColor: 'white',
167 | borderTopLeftRadius: 32,
168 | borderTopRightRadius: 32,
169 | shadowColor: 'grey',
170 | shadowOffset: { width: 1.1, height: 1.1 },
171 | shadowOpacity: 0.2,
172 | shadowRadius: 10.0,
173 | elevation: 16,
174 | },
175 | scrollContainer: {
176 | borderTopLeftRadius: 32,
177 | borderTopRightRadius: 32,
178 | paddingHorizontal: 8,
179 | },
180 | courseTitle: {
181 | color: 'black',
182 | fontSize: 22,
183 | fontFamily: 'WorkSans-SemiBold',
184 | letterSpacing: 0.27,
185 | paddingTop: 32,
186 | paddingLeft: 18,
187 | paddingRight: 16,
188 | },
189 | priceRatingContainer: {
190 | flexDirection: 'row',
191 | paddingHorizontal: 16,
192 | paddingTop: 12,
193 | paddingBottom: 8,
194 | alignItems: 'center',
195 | },
196 | price: {
197 | flex: 1,
198 | color: 'rgb(0, 182, 240)',
199 | },
200 | textStyle: {
201 | fontSize: 22,
202 | fontFamily: 'WorkSans-Regular',
203 | color: 'darkslategrey',
204 | letterSpacing: 0.27,
205 | },
206 | timeBoxContainer: {
207 | backgroundColor: 'white',
208 | borderRadius: 16,
209 | alignItems: 'center',
210 | margin: 8,
211 | paddingHorizontal: 18,
212 | paddingVertical: 12,
213 | elevation: 8,
214 | shadowColor: 'grey',
215 | shadowOffset: { width: 1.1, height: 1.1 },
216 | shadowOpacity: 0.22,
217 | shadowRadius: 8.0,
218 | },
219 | timeBoxTitle: {
220 | fontSize: 14,
221 | fontFamily: 'WorkSans-SemiBold',
222 | color: 'rgb(0, 182, 240)',
223 | },
224 | boxesContainer: {
225 | flexDirection: 'row',
226 | padding: 8,
227 | },
228 | courseDescription: {
229 | flex: 1,
230 | fontSize: 14,
231 | fontFamily: 'WorkSans-Regular',
232 | textAlign: 'justify',
233 | color: 'darkslategrey',
234 | letterSpacing: 0.27,
235 | paddingHorizontal: 16,
236 | paddingVertical: 8,
237 | },
238 | footerContainer: {
239 | flexDirection: 'row',
240 | paddingHorizontal: 24,
241 | // paddingBottom: 16,
242 | },
243 | addView: {
244 | width: 48,
245 | height: 48,
246 | borderColor: 'lightgrey',
247 | borderWidth: 1,
248 | borderRadius: 16,
249 | justifyContent: 'center',
250 | alignItems: 'center',
251 | },
252 | joinCourse: {
253 | flex: 1,
254 | borderRadius: 16,
255 | backgroundColor: 'rgb(0, 182, 240)',
256 | elevation: 4,
257 | shadowColor: 'rgb(0, 182, 240)',
258 | shadowOffset: { width: 1.1, height: 1.1 },
259 | shadowOpacity: 0.5,
260 | shadowRadius: 10.0,
261 | ...Platform.select({ android: { overflow: 'hidden' } }),
262 | },
263 | joinCourseText: {
264 | padding: 18,
265 | paddingVertical: 12,
266 | fontSize: 18,
267 | fontFamily: 'WorkSans-SemiBold',
268 | alignSelf: 'center',
269 | color: 'white',
270 | },
271 | favoriteIcon: {
272 | position: 'absolute',
273 | right: 35,
274 | width: 60,
275 | height: 60,
276 | borderRadius: 30,
277 | backgroundColor: 'rgb(0, 182, 240)',
278 | justifyContent: 'center',
279 | alignItems: 'center',
280 | elevation: 18,
281 | shadowColor: 'black',
282 | shadowOffset: { width: 0, height: 5 },
283 | shadowOpacity: 0.34,
284 | shadowRadius: 6.27,
285 | },
286 | backBtn: {
287 | position: 'absolute',
288 | width: 56,
289 | height: 56,
290 | borderRadius: 30,
291 | justifyContent: 'center',
292 | alignItems: 'center',
293 | },
294 | });
295 |
296 | export default CourseInfoScreen;
297 |
--------------------------------------------------------------------------------