├── src
├── screens
│ ├── myjobs
│ │ ├── myjobsheader.js
│ │ └── index.js
│ ├── jobs
│ │ ├── MainThread.js
│ │ ├── WorkAreaNotSet.js
│ │ ├── NoOpenJobAlert.js
│ │ └── index.js
│ ├── home
│ │ └── index.js
│ ├── menu
│ │ ├── userinfo.js
│ │ └── index.js
│ ├── page
│ │ └── index.js
│ ├── chatscreen
│ │ ├── chatheader.js
│ │ └── index.js
│ └── login
│ │ └── index.js
├── components
│ ├── ChatComponents
│ │ ├── Chat
│ │ │ ├── document.js
│ │ │ ├── priceask.js
│ │ │ ├── termschanged.js
│ │ │ ├── daysask.js
│ │ │ └── index.js
│ │ ├── label
│ │ │ └── index.js
│ │ ├── ChatAlert
│ │ │ └── index.js
│ │ ├── ChangeJobStatus
│ │ │ └── index.js
│ │ ├── ChatInput
│ │ │ └── index.js
│ │ └── ChatJobDescription
│ │ │ └── index.js
│ ├── dumbcomponent.js
│ ├── ItemContainer
│ │ └── index.js
│ ├── Button
│ │ └── index.js
│ ├── Item
│ │ └── index.js
│ ├── Alerts
│ │ └── index.js
│ ├── Card
│ │ ├── cardfooter.js
│ │ ├── index.js
│ │ ├── cardheader.js
│ │ └── cardbody.js
│ ├── Search
│ │ └── index.js
│ ├── Input
│ │ └── index.js
│ ├── BackgroundImage
│ │ └── index.js
│ └── Header
│ │ └── index.js
├── modules
│ ├── package.json
│ └── account
│ │ ├── types.js
│ │ ├── index.js
│ │ ├── actions.js
│ │ └── reducers.js
├── utils
│ ├── package.json
│ ├── StartAJob.db
│ ├── configs.js
│ └── Functions.js
├── global.js
├── store.js
├── router.js
└── Database.js
├── assets
├── flag
│ ├── package.json
│ ├── IL.png
│ └── RU.png
├── clip.png
├── docx.png
├── flag.png
├── glob.png
├── help.png
├── icon.jpg
├── icon.png
├── logo.jpg
├── logo.png
├── map.png
├── tick.png
├── avatar.png
├── block.png
├── clock.png
├── emoji.png
├── house.png
├── login.png
├── o-icon.png
├── search.png
├── splash.png
├── wallet.png
├── baglogo.png
├── barcode.png
├── cabinet.png
├── download.png
├── home-icon.png
├── ion-menu.png
├── money-bag.png
├── my-work.png
├── no_image.png
├── setting.png
├── sign-in.png
├── star-icon.png
├── arrow-down.png
├── background.png
├── camera-icon.png
├── clock-blue.png
├── clock-green.png
├── double-tick.png
├── left-arrow.png
├── login-black.png
├── my-business.png
├── phone-icon.png
├── right-arrow.png
├── sand-watch.png
├── trust-icon.png
├── trust-white.png
├── wallet-blue.png
├── bag-icon-blue.png
├── bag-icon-gray.png
├── bag-icon-white.png
├── deposit-fund.png
├── facebook_icon.png
├── home-icon-blue.png
├── home-icon-gray.png
├── menu-icon-blue.png
├── menu-icon-gray.png
├── no-jobs-icon.png
├── rate-employe.png
├── withdraw-fund.png
├── blue-double-tick.png
├── hand-shake-green.png
├── hand-shake-white.png
├── home-icon-white.png
├── menu-icon-white.png
├── new-message-icon.png
├── sand-watch-blue.png
├── background-pattern.png
├── fulltime-job-icon.png
├── no-work-area-icon.png
├── one-time-job-icon.png
├── three-vertical-dots.png
├── bag-icon-blue-outline.png
├── background-pattern-gray.png
├── Union.svg
└── chat-background.svg
├── startajob.keystore
├── babel.config.js
├── .expo-shared
└── assets.json
├── .gitignore
├── app.json
├── App.js
└── package.json
/src/screens/myjobs/myjobsheader.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/ChatComponents/Chat/document.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/flag/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flag"
3 | }
--------------------------------------------------------------------------------
/src/modules/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@modules"
3 | }
--------------------------------------------------------------------------------
/src/utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@utils"
3 | }
--------------------------------------------------------------------------------
/assets/clip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/clip.png
--------------------------------------------------------------------------------
/assets/docx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/docx.png
--------------------------------------------------------------------------------
/assets/flag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/flag.png
--------------------------------------------------------------------------------
/assets/glob.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/glob.png
--------------------------------------------------------------------------------
/assets/help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/help.png
--------------------------------------------------------------------------------
/assets/icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/icon.jpg
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/icon.png
--------------------------------------------------------------------------------
/assets/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/logo.jpg
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/logo.png
--------------------------------------------------------------------------------
/assets/map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/map.png
--------------------------------------------------------------------------------
/assets/tick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/tick.png
--------------------------------------------------------------------------------
/assets/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/avatar.png
--------------------------------------------------------------------------------
/assets/block.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/block.png
--------------------------------------------------------------------------------
/assets/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/clock.png
--------------------------------------------------------------------------------
/assets/emoji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/emoji.png
--------------------------------------------------------------------------------
/assets/house.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/house.png
--------------------------------------------------------------------------------
/assets/login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/login.png
--------------------------------------------------------------------------------
/assets/o-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/o-icon.png
--------------------------------------------------------------------------------
/assets/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/search.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/splash.png
--------------------------------------------------------------------------------
/assets/wallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/wallet.png
--------------------------------------------------------------------------------
/assets/baglogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/baglogo.png
--------------------------------------------------------------------------------
/assets/barcode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/barcode.png
--------------------------------------------------------------------------------
/assets/cabinet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/cabinet.png
--------------------------------------------------------------------------------
/assets/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/download.png
--------------------------------------------------------------------------------
/assets/flag/IL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/flag/IL.png
--------------------------------------------------------------------------------
/assets/flag/RU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/flag/RU.png
--------------------------------------------------------------------------------
/assets/home-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/home-icon.png
--------------------------------------------------------------------------------
/assets/ion-menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/ion-menu.png
--------------------------------------------------------------------------------
/assets/money-bag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/money-bag.png
--------------------------------------------------------------------------------
/assets/my-work.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/my-work.png
--------------------------------------------------------------------------------
/assets/no_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/no_image.png
--------------------------------------------------------------------------------
/assets/setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/setting.png
--------------------------------------------------------------------------------
/assets/sign-in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/sign-in.png
--------------------------------------------------------------------------------
/assets/star-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/star-icon.png
--------------------------------------------------------------------------------
/startajob.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/startajob.keystore
--------------------------------------------------------------------------------
/assets/arrow-down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/arrow-down.png
--------------------------------------------------------------------------------
/assets/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/background.png
--------------------------------------------------------------------------------
/assets/camera-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/camera-icon.png
--------------------------------------------------------------------------------
/assets/clock-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/clock-blue.png
--------------------------------------------------------------------------------
/assets/clock-green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/clock-green.png
--------------------------------------------------------------------------------
/assets/double-tick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/double-tick.png
--------------------------------------------------------------------------------
/assets/left-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/left-arrow.png
--------------------------------------------------------------------------------
/assets/login-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/login-black.png
--------------------------------------------------------------------------------
/assets/my-business.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/my-business.png
--------------------------------------------------------------------------------
/assets/phone-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/phone-icon.png
--------------------------------------------------------------------------------
/assets/right-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/right-arrow.png
--------------------------------------------------------------------------------
/assets/sand-watch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/sand-watch.png
--------------------------------------------------------------------------------
/assets/trust-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/trust-icon.png
--------------------------------------------------------------------------------
/assets/trust-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/trust-white.png
--------------------------------------------------------------------------------
/assets/wallet-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/wallet-blue.png
--------------------------------------------------------------------------------
/src/utils/StartAJob.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/src/utils/StartAJob.db
--------------------------------------------------------------------------------
/assets/bag-icon-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/bag-icon-blue.png
--------------------------------------------------------------------------------
/assets/bag-icon-gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/bag-icon-gray.png
--------------------------------------------------------------------------------
/assets/bag-icon-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/bag-icon-white.png
--------------------------------------------------------------------------------
/assets/deposit-fund.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/deposit-fund.png
--------------------------------------------------------------------------------
/assets/facebook_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/facebook_icon.png
--------------------------------------------------------------------------------
/assets/home-icon-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/home-icon-blue.png
--------------------------------------------------------------------------------
/assets/home-icon-gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/home-icon-gray.png
--------------------------------------------------------------------------------
/assets/menu-icon-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/menu-icon-blue.png
--------------------------------------------------------------------------------
/assets/menu-icon-gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/menu-icon-gray.png
--------------------------------------------------------------------------------
/assets/no-jobs-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/no-jobs-icon.png
--------------------------------------------------------------------------------
/assets/rate-employe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/rate-employe.png
--------------------------------------------------------------------------------
/assets/withdraw-fund.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/withdraw-fund.png
--------------------------------------------------------------------------------
/assets/blue-double-tick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/blue-double-tick.png
--------------------------------------------------------------------------------
/assets/hand-shake-green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/hand-shake-green.png
--------------------------------------------------------------------------------
/assets/hand-shake-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/hand-shake-white.png
--------------------------------------------------------------------------------
/assets/home-icon-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/home-icon-white.png
--------------------------------------------------------------------------------
/assets/menu-icon-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/menu-icon-white.png
--------------------------------------------------------------------------------
/assets/new-message-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/new-message-icon.png
--------------------------------------------------------------------------------
/assets/sand-watch-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/sand-watch-blue.png
--------------------------------------------------------------------------------
/assets/background-pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/background-pattern.png
--------------------------------------------------------------------------------
/assets/fulltime-job-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/fulltime-job-icon.png
--------------------------------------------------------------------------------
/assets/no-work-area-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/no-work-area-icon.png
--------------------------------------------------------------------------------
/assets/one-time-job-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/one-time-job-icon.png
--------------------------------------------------------------------------------
/assets/three-vertical-dots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/three-vertical-dots.png
--------------------------------------------------------------------------------
/assets/bag-icon-blue-outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/bag-icon-blue-outline.png
--------------------------------------------------------------------------------
/src/modules/account/types.js:
--------------------------------------------------------------------------------
1 | export default {
2 | SET_USER: 'SET_USER',
3 | SIGN_IN: 'SIGN_IN',
4 | SIGN_OUT: 'SIGN_OUT'
5 | }
--------------------------------------------------------------------------------
/assets/background-pattern-gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactnative1126/StartAJob_ReactNative/HEAD/assets/background-pattern-gray.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "f9155ac790fd02fadcdeca367b02581c04a353aa6d5aa84409a59f6804c87acd": true,
3 | "89ed26367cdb9b771858e026f2eb95bfdb90e5ae943e716575327ec325f39c44": true
4 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/**/*
2 | .expo/*
3 | npm-debug.*
4 | *.jks
5 | *.p8
6 | *.p12
7 | *.key
8 | *.mobileprovision
9 | *.orig.*
10 | web-build/
11 | web-report/
12 |
13 | # macOS
14 | .DS_Store
15 |
--------------------------------------------------------------------------------
/src/utils/configs.js:
--------------------------------------------------------------------------------
1 | export default {
2 | generalURL: "http://isapi.mekashron.com/StartAJob/General.dll/soap/IGeneral",
3 | jobURL: "http://isapi.mekashron.com/StartAJob/JobManagement.dll/soap/IJobManagement",
4 | }
--------------------------------------------------------------------------------
/src/modules/account/index.js:
--------------------------------------------------------------------------------
1 | import accountReducer from './reducers';
2 |
3 | export { default as accountActionTypes } from './types';
4 | export { default as accountActions } from './actions';
5 |
6 | export default accountReducer;
7 |
--------------------------------------------------------------------------------
/src/screens/jobs/MainThread.js:
--------------------------------------------------------------------------------
1 | import { self } from 'react-native-threads';
2 | // import { self } from 'react-native-workers';
3 |
4 | let count = 0;
5 |
6 | self.onmessage = message => {
7 | console.log(`THREAD: got message ${message}`);
8 |
9 | count++;
10 |
11 | self.postMessage(`Message #${count} from worker thread!`);
12 | }
--------------------------------------------------------------------------------
/src/modules/account/actions.js:
--------------------------------------------------------------------------------
1 | import types from './types';
2 |
3 | export const setUser = (data) => ({
4 | type: types.SET_USER,
5 | payload: data,
6 | });
7 |
8 | export const signIn = (data) => ({
9 | type: types.SIGN_IN,
10 | payload: data,
11 | });
12 |
13 | export const signOut = (data) => ({
14 | type: types.SIGN_OUT,
15 | payload: data,
16 | })
--------------------------------------------------------------------------------
/src/components/dumbcomponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet
6 | } from 'react-native'
7 |
8 | // Local components
9 | import { Color } from './../../global'
10 |
11 | /**
12 | * Card Component
13 | *
14 | * @version 1.0.0
15 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
16 | */
17 |
18 | class Card extends React.Component {
19 | render(){
20 | return(
21 | Jobs
22 | )
23 | }
24 | }
25 |
26 | const styles = StyleSheet.create({
27 | container : {
28 | paddingHorizontal: 15
29 | }
30 | })
31 | export default Card
--------------------------------------------------------------------------------
/src/components/ItemContainer/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet
6 | } from 'react-native'
7 |
8 | // Local components
9 | import Item from './../Item'
10 | // Config
11 | import { Color } from './../../global'
12 |
13 | /**
14 | * ItemContainer Component
15 | *
16 | * @version 1.0.0
17 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
18 | */
19 |
20 | class ItemContainer extends React.Component {
21 | render(){
22 | return(
23 | { this.props.children }
24 | )
25 | }
26 | }
27 |
28 | const styles = StyleSheet.create({
29 | container : {
30 | marginBottom: 20
31 | }
32 | })
33 | export default ItemContainer
--------------------------------------------------------------------------------
/src/global.js:
--------------------------------------------------------------------------------
1 | import { Dimensions, Platform, PixelRatio } from 'react-native';
2 |
3 | export const Color = {
4 | primary: "#02245D",
5 | color2: "#101010",
6 | color3: "#E8ECEF",
7 | color4: "#A4A4A4",
8 | color5: "#EEEEEE",
9 | color6: "#3D3D3D",
10 | color7: "#315FAD",
11 | color8: "#FF9900"
12 | }
13 |
14 |
15 |
16 | const {
17 | width: SCREEN_WIDTH,
18 | height: SCREEN_HEIGHT,
19 | } = Dimensions.get('window');
20 | // based on iphone 5s's scale
21 | const scale = SCREEN_WIDTH / 320;
22 |
23 | export function normalize(size) {
24 | const newSize = size * scale
25 | if (Platform.OS === 'ios') {
26 | return Math.round(PixelRatio.roundToNearestPixel(newSize))
27 | } else {
28 | return Math.round(PixelRatio.roundToNearestPixel(newSize)) - 2
29 | }
30 | }
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "Start A Job",
4 | "slug": "start-a-job",
5 | "privacy": "public",
6 | "sdkVersion": "36.0.0",
7 | "platforms": [
8 | "ios",
9 | "android",
10 | "web"
11 | ],
12 | "android": {
13 | "package": "com.startajob"
14 | },
15 | "version": "1.0.1",
16 | "orientation": "portrait",
17 | "icon": "./assets/icon.png",
18 | "splash": {
19 | "image": "./assets/splash.png",
20 | "resizeMode": "contain",
21 | "backgroundColor": "#ffffff"
22 | },
23 | "updates": {
24 | "fallbackToCacheTimeout": 0
25 | },
26 | "assetBundlePatterns": [
27 | "**/*"
28 | ],
29 | "ios": {
30 | "supportsTablet": true,
31 | "bundleIdentifier": "com.startajob"
32 | },
33 | "description": ""
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/modules/account/reducers.js:
--------------------------------------------------------------------------------
1 | import types from './types';
2 |
3 | const initialState = {
4 | logged: false,
5 | user: {
6 | email: '',
7 | password: '',
8 | }
9 | };
10 |
11 | export default function accountReducer(state = initialState, action) {
12 | switch (action.type) {
13 | case types.SET_USER:
14 | return {
15 | ...state,
16 | logged: true,
17 | user: action.payload,
18 | };
19 | case types.SIGN_IN:
20 | return {
21 | ...state,
22 | logged: true,
23 | user: action.payload,
24 | };
25 | case types.SIGN_OUT:
26 | return {
27 | ...state,
28 | logged: false,
29 | user: initialState,
30 | }
31 | default:
32 | return state;
33 | }
34 | }
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment } from 'react';
2 | import { StyleSheet, StatusBar } from 'react-native';
3 | import AppNavigation from './src/router'
4 |
5 | import { Provider } from 'react-redux';
6 | import { PersistGate } from 'redux-persist/integration/react';
7 | import { store, persistor } from './src/store';
8 |
9 | export default function App() {
10 | return (
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 | }
24 |
25 | const styles = StyleSheet.create({
26 | container: {
27 | flex: 1,
28 | backgroundColor: '#fff',
29 | alignItems: 'center',
30 | justifyContent: 'center',
31 | },
32 | });
33 |
--------------------------------------------------------------------------------
/src/utils/Functions.js:
--------------------------------------------------------------------------------
1 | export const verifyEmail = (value) => {
2 | var emailRex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
3 | if (emailRex.test(value)) {
4 | return true;
5 | }
6 | return false;
7 | }
8 |
9 | export const verifyPhone = (value) => {
10 | var phoneRex = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im;
11 | if (phoneRex.test(value)) {
12 | return true;
13 | }
14 | return false;
15 | }
16 |
17 | export const verifyAlias = (value) => {
18 | var aliasRex = /^[a-zA-Z0-9_]{5,}[a-zA-Z]+[0-9]*$/;
19 | if (aliasRex.test(value)) {
20 | return true;
21 | }
22 | return false;
23 | }
24 |
25 | export const verifyLength = (value, length) => {
26 | if (value.length >= length) {
27 | return true;
28 | }
29 | return false;
30 | }
--------------------------------------------------------------------------------
/src/store.js:
--------------------------------------------------------------------------------
1 | // import { AsyncStorage } from '@react-native-community/async-storage';
2 | import { AsyncStorage } from 'react-native';
3 | import {createStore, combineReducers, applyMiddleware } from 'redux';
4 | import { createLogger } from 'redux-logger';
5 | import { persistStore, persistReducer } from 'redux-persist';
6 |
7 | import accountReducer from '@modules/account/reducers';
8 |
9 | const peresistConfig = {
10 | key: 'root',
11 | storage: AsyncStorage,
12 | whitelist: [
13 | 'accountReducer',
14 | ],
15 | blacklist: [
16 | ]
17 | }
18 |
19 | const rootReducer = combineReducers({
20 | account: accountReducer,
21 | });
22 |
23 | const persistedReducer = persistReducer(peresistConfig, rootReducer);
24 |
25 | const store = createStore(
26 | persistedReducer,
27 | applyMiddleware(
28 | createLogger(),
29 | )
30 | )
31 |
32 | let persistor = persistStore(store);
33 |
34 | export {
35 | store, persistor,
36 | }
--------------------------------------------------------------------------------
/assets/Union.svg:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/src/screens/home/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import {
3 | View,
4 | Text,
5 | Image
6 | } from 'react-native'
7 |
8 | // local component
9 | import CutomButton from './../../components/Button'
10 | import Background from './../../../assets/background.png'
11 | import Chat from './../../components/ChatComponents/Chat'
12 | class Home extends Component {
13 | render(){
14 | return(
15 |
16 | This is a test based on your requirement.
17 |
18 | {
20 | this.props.navigation.navigate('PageStack')
21 | }}
22 | backgroundColor= "#28A745"
23 | title={'Start Test'}/>
24 |
25 |
26 |
27 |
28 |
29 | )
30 | }
31 | }
32 |
33 | export default Home
--------------------------------------------------------------------------------
/src/components/ChatComponents/label/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Platform
7 | } from 'react-native'
8 |
9 | // Local components
10 | import { Color, normalize } from './../../../global'
11 |
12 | /**
13 | * Label Component
14 | *
15 | * @version 1.0.0
16 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
17 | */
18 |
19 | class Label extends React.Component {
20 | render(){
21 | return(
22 |
28 | { this.props.text }
29 |
30 | )
31 | }
32 | }
33 |
34 | Label.defaultProps = {
35 | text:''
36 | }
37 | const styles = StyleSheet.create({
38 | container : {
39 | paddingHorizontal: 15
40 | },
41 | shadow : Platform.os === "ios" ? {
42 | shadowColor: "#000",
43 | shadowOffset: {
44 | width: 0,
45 | height: 2,
46 | },
47 | shadowOpacity: 0.25,
48 | shadowRadius: 3.84,
49 | } : {
50 | elevation: 5
51 | },
52 | })
53 | export default Label
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "node_modules/expo/AppEntry.js",
3 | "scripts": {
4 | "start": "expo start",
5 | "android": "expo start --android",
6 | "ios": "expo start --ios",
7 | "web": "expo start --web",
8 | "eject": "expo eject"
9 | },
10 | "dependencies": {
11 | "expo": "~36.0.0",
12 | "expo-device": "~2.0.0",
13 | "expo-sqlite": "~8.0.0",
14 | "react": "~16.9.0",
15 | "react-dom": "~16.9.0",
16 | "react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz",
17 | "react-native-autolink": "^1.9.1",
18 | "react-native-gesture-handler": "~1.5.0",
19 | "react-native-material-menu": "^1.0.0",
20 | "react-native-reanimated": "~1.4.0",
21 | "react-native-sqlite-storage": "^4.1.0",
22 | "react-native-status-bar-height": "^2.4.0",
23 | "react-native-svg": "9.13.3",
24 | "react-native-threads": "0.0.17",
25 | "react-native-web": "~0.11.7",
26 | "react-native-workers": "^0.3.1",
27 | "react-native-xml2js": "^1.0.3",
28 | "react-navigation": "^4.0.10",
29 | "react-navigation-stack": "^1.10.3",
30 | "react-navigation-tabs": "^2.6.2",
31 | "react-redux": "^7.1.3",
32 | "redux": "^4.0.5",
33 | "redux-logger": "^3.0.6",
34 | "redux-persist": "^6.0.0",
35 | "soap-everywhere": "^1.0.7"
36 | },
37 | "devDependencies": {
38 | "babel-preset-expo": "~8.0.0"
39 | },
40 | "private": true
41 | }
42 |
--------------------------------------------------------------------------------
/src/components/Button/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import {
3 | View,
4 | Text,
5 | Button,
6 | TouchableOpacity,
7 | Platform,
8 | Image
9 | } from 'react-native'
10 |
11 | class CutomButton extends Component {
12 | render(){
13 | return(
14 |
33 |
34 | {this.props.logo && }
35 | {this.props.title}
36 |
37 | )
38 | }
39 | }
40 |
41 | CutomButton.defaultProps = {
42 | title: 'No name'
43 | }
44 | export default CutomButton
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/src/components/Item/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | TouchableOpacity,
8 | TouchableNativeFeedback
9 | } from 'react-native'
10 |
11 | // Local components
12 |
13 | // Config
14 | import { Color } from './../../global'
15 |
16 | // Icon
17 | import RightArrow from './../../../assets/right-arrow.png'
18 |
19 | /**
20 | * Item Component
21 | *
22 | * @version 1.0.0
23 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
24 | */
25 |
26 | class Item extends React.Component {
27 |
28 | componentDidMount(){
29 | if(Platform.OS === "android")
30 | TouchableNativeFeedback.Ripple()
31 | }
32 |
33 | render(){
34 | let content = (
35 | { this.props.icon &&
36 | { this.props.icon }
37 | }
38 |
42 | { this.props.text }
43 |
44 | { !this.props.rightComponent &&
45 |
51 | }
52 | { this.props.rightComponent &&
53 | { this.props.rightComponent }
54 | }
55 | )
56 |
57 | return (
61 | { content }
62 | )
63 |
64 | }
65 | }
66 |
67 | Item.defaultProps = {
68 | text: '',
69 | icon: null,
70 | rightComponent: null
71 | }
72 | const styles = StyleSheet.create({
73 | container : {
74 | paddingHorizontal: 10,
75 | backgroundColor: 'white',
76 | height: 50,
77 | alignItems: 'center',
78 | flexDirection: 'row',
79 | marginBottom: 1
80 | }
81 | })
82 | export default Item
--------------------------------------------------------------------------------
/assets/chat-background.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/src/screens/jobs/WorkAreaNotSet.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | TouchableOpacity
7 | } from 'react-native'
8 |
9 | // Local components
10 | import Alert from './../../components/Alerts'
11 | import CutomButton from './../../components/Button'
12 |
13 | // Icons
14 | import NoWorkArea from './../../../assets/no-work-area-icon.png'
15 |
16 | // Config
17 | import { Color, normalize } from './../../global'
18 | /**
19 | * WorkAreaNotSet Component
20 | *
21 | * @version 1.0.0
22 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
23 | */
24 |
25 | class WorkAreaNotSet extends React.Component {
26 | render(){
27 | return(
34 |
39 | Please configure your work areas in order to see related jobs
45 |
46 |
52 |
63 |
64 |
65 | }
66 | />)
67 | }
68 | }
69 |
70 | WorkAreaNotSet.defaultProps = {
71 | onPressConfigure: null
72 | }
73 |
74 | const styles = StyleSheet.create({
75 | container : {
76 | paddingHorizontal: 15
77 | }
78 | })
79 | export default WorkAreaNotSet
--------------------------------------------------------------------------------
/src/components/Alerts/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | Platform
8 | } from 'react-native'
9 |
10 | // Local components
11 | // Config
12 | import { Color, normalize } from './../../global'
13 |
14 | /**
15 | * Alert Component
16 | *
17 | * @version 1.0.0
18 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
19 | */
20 |
21 | class Alert extends React.Component {
22 | render(){
23 | return(
24 |
25 |
29 | { this.props.icon &&
35 |
42 | }
43 |
44 |
47 | { this.props.title }
54 |
55 |
56 |
57 |
58 | { this.props.body }
59 |
60 | )
61 | }
62 | }
63 |
64 | Alert.defaultProps = {
65 | icon: null,
66 | body : null,
67 | title: 'No open jobs found'
68 | }
69 | const styles = StyleSheet.create({
70 | container : {
71 | paddingHorizontal: 15,
72 | paddingVertical: 10,
73 | backgroundColor: 'white',
74 | margin: 10,
75 | borderRadius: 2
76 | },
77 | shadow : Platform.os === "ios" ? {
78 | shadowColor: "#000",
79 | shadowOffset: {
80 | width: 0,
81 | height: 2,
82 | },
83 | shadowOpacity: 0.20,
84 | shadowRadius: 1.41,
85 | } : {
86 | elevation: 2
87 | }
88 | })
89 | export default Alert
--------------------------------------------------------------------------------
/src/screens/jobs/NoOpenJobAlert.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet
6 | } from 'react-native'
7 |
8 | // Local components
9 | import Alert from './../../components/Alerts'
10 | import NoJobIcon from './../../../assets/no-jobs-icon.png'
11 |
12 | // Config
13 | import { Color, normalize } from './../../global'
14 |
15 | /**
16 | * NoOpenJobAlert Component
17 | *
18 | * @version 1.0.0
19 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
20 | */
21 |
22 | class NoOpenJobAlert extends React.Component {
23 | render(){
24 | return(
31 |
36 | Check us out later - we have new jobs every day!
42 |
43 |
48 |
53 |
54 | Pro tips: Try refining your search keywords, adjusting your existing
60 | work areas or add new ones
67 |
68 |
69 |
70 | }
71 | />)
72 | }
73 | }
74 |
75 | const styles = StyleSheet.create({
76 | container : {
77 | paddingHorizontal: 15
78 | }
79 | })
80 | export default NoOpenJobAlert
--------------------------------------------------------------------------------
/src/components/Card/cardfooter.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image
7 | } from 'react-native'
8 |
9 | // Local components
10 | import { Color, normalize } from './../../global'
11 |
12 | // Icons
13 | import Home from './../../../assets/home-icon.png'
14 | import FullTime from './../../../assets/fulltime-job-icon.png'
15 | import OneTime from './../../../assets/one-time-job-icon.png'
16 |
17 | /**
18 | * CardFooter Component
19 | *
20 | * @version 1.0.0
21 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
22 | */
23 |
24 | class CardFooter extends React.Component {
25 |
26 | render() {
27 | let jobTypeIcon
28 | if (this.props.jobType === 2) {
29 | jobTypeIcon = FullTime
30 | }
31 | else if (this.props.jobType === 1) {
32 | jobTypeIcon = OneTime
33 | }
34 | else {
35 | jobTypeIcon = Home
36 | }
37 | return (
38 |
39 |
46 |
47 |
54 |
61 | {this.props.category + " > "}
62 |
63 |
64 | {this.props.subCategories.map((item, key) => {
65 | return (
66 | item.SkillName + ", "
67 | )
68 | })}
69 |
70 |
71 | )
72 | }
73 | }
74 |
75 | CardFooter.defaultProps = {
76 | category: 'No Category',
77 | subCategories: 'No Sub Categories',
78 | jobType: 'FULL_TIME'
79 | }
80 |
81 | const styles = StyleSheet.create({
82 | container: {
83 | paddingHorizontal: 15,
84 | flexDirection: 'row',
85 | marginTop: 15,
86 | marginBottom: 15
87 | }
88 | })
89 | export default CardFooter
--------------------------------------------------------------------------------
/src/components/Search/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import {
3 | View,
4 | Text,
5 | Button,
6 | TouchableOpacity,
7 | Platform,
8 | TextInput,
9 | Image
10 | } from 'react-native'
11 | import SearchIcon from './../../../assets/search.png'
12 | import BarCode from './../../../assets/barcode.png'
13 |
14 | // Config
15 | import { Color } from './../../global'
16 | class Search extends Component {
17 | render(){
18 | return(
19 |
29 |
30 |
31 |
37 | { this.props.SearchIconrightButton &&
38 |
47 |
48 |
49 |
50 |
51 | }
52 |
53 | )
54 | }
55 | }
56 |
57 | Search.defaultProps = {
58 | title: 'No name',
59 | placeholder: '',
60 | rightButton: null,
61 | rightButtonIcon: null,
62 | rightButtonStyle: null
63 | }
64 | export default Search
--------------------------------------------------------------------------------
/src/components/ChatComponents/ChatAlert/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Platform
7 | } from 'react-native'
8 |
9 | // Local components
10 | import { Color } from '../../../global'
11 |
12 | /**
13 | * ChatAlert Component
14 | *
15 | * @version 1.0.0
16 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
17 | */
18 |
19 | class ChatAlert extends React.Component {
20 |
21 |
22 | render(){
23 | return ( {
28 | if( this.props.type === "warn" )
29 | return '#ECEACA'
30 | else if( this.props.type === "success" )
31 | return '#EBFFE8'
32 | else if( this.props.type === "error" )
33 | return '#ECC8CA'
34 | })()
35 | }
36 | ]}>
37 |
46 |
47 | { this.props.headerIcon }
48 |
49 |
50 | { this.props.title }
56 |
57 |
58 |
63 | { this.props.body }
64 |
65 | )
66 |
67 | }
68 | }
69 |
70 | ChatAlert.defaultProps = {
71 | // This will take OFFER_APPROVAL, OFFER_ACCEPTED, OFFER_REJECTED
72 | headerIcon: null,
73 | title: '',
74 | body: null,
75 | type: 'warn'
76 | }
77 |
78 | const styles = StyleSheet.create({
79 | container : {
80 | marginBottom: 5,
81 | borderRadius: 10,
82 | marginHorizontal: 10
83 | },
84 | shadow : Platform.os === "ios" ? {
85 | shadowColor: "#000",
86 | shadowOffset: {
87 | width: 0,
88 | height: 2,
89 | },
90 | shadowOpacity: 0.25,
91 | shadowRadius: 3.84,
92 | } : {
93 | elevation: 5
94 | }
95 | })
96 | export default ChatAlert
--------------------------------------------------------------------------------
/src/components/Input/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import {
3 | View,
4 | Text,
5 | Button,
6 | TouchableOpacity,
7 | Platform,
8 | TextInput,
9 | Image
10 | } from 'react-native'
11 | import SearchIcon from './../../../assets/search.png'
12 | import BarCode from './../../../assets/barcode.png'
13 |
14 | // Config
15 | import { Color } from './../../global'
16 | class Input extends Component {
17 | render(){
18 | return(
19 |
27 |
28 | { this.props.icon &&
29 |
30 | }
31 |
39 |
50 | { this.props.rightButton &&
51 |
60 |
61 | { this.props.rightButtonIcon &&
62 | }
68 |
69 |
70 | }
71 |
72 | )
73 | }
74 | }
75 |
76 | Input.defaultProps = {
77 | title: 'No name',
78 | icon: null,
79 | rightButton: null,
80 | rightButtonIcon: null,
81 | rightButtonStyle: null
82 | }
83 | export default Input
--------------------------------------------------------------------------------
/src/components/BackgroundImage/index.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment } from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | Dimensions
8 | } from 'react-native'
9 |
10 | // Local components
11 | import { Color } from './../../global'
12 |
13 | // Images
14 | import BackgroundPattern from './../../../assets/background-pattern-gray.png'
15 |
16 | /**
17 | * BackgroundImage Component
18 | *
19 | * @version 1.0.0
20 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
21 | */
22 |
23 | class BackgroundImage extends React.Component {
24 | row = (num) => {
25 | let content = []
26 | let precent = this.props.precent || 0.20
27 | let Background = this.props.source || BackgroundPattern
28 | let opacity = this.props.opacity || 0.1
29 |
30 | let screenHeight = Dimensions.get('screen').height
31 | let imageWidth = Dimensions.get('screen').width - ( Dimensions.get('screen').width * precent )
32 | let imageHeight = Dimensions.get('screen').width - ( Dimensions.get('screen').width * precent )
33 | let numRows = Math.ceil((screenHeight/imageHeight))
34 | console.log(numRows)
35 | for(let i = 0 ; i < numRows; i++ ){
36 | content.push(
40 |
48 |
56 | )
57 | }
58 | return content
59 |
60 | }
61 | render(){
62 | return(
67 |
68 | {this.row(2)}
69 |
70 | )
71 | }
72 | }
73 |
74 | const styles = StyleSheet.create({
75 | container : {
76 | paddingHorizontal: 15
77 | }
78 | })
79 | export default BackgroundImage
--------------------------------------------------------------------------------
/src/components/Card/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | StyleSheet,
5 | TouchableNativeFeedback,
6 | Platform,
7 | TouchableOpacity
8 | } from 'react-native'
9 |
10 | // Local components
11 | import CardHeader from './cardheader'
12 | import CardBody from './cardbody'
13 | import CardFooter from './cardfooter'
14 |
15 | // Config
16 | import { Color } from './../../global'
17 |
18 | class Card extends React.Component {
19 |
20 | componentDidMount() {
21 | if (Platform.OS === "android")
22 | TouchableNativeFeedback.Ripple()
23 | }
24 | render() {
25 | let content =
29 |
41 |
48 |
53 |
54 |
55 | return (
56 |
63 | {content}
64 |
65 | )
66 |
67 | }
68 | }
69 |
70 | // Default Props
71 | Card.defaultProps = {
72 | jobState: null,
73 | jobTitle: '',
74 | userName: '',
75 | timestamp: '',
76 | isRead: null,
77 | jobType: null,
78 | bid: {},
79 | address: 'No address',
80 | avatarUri: null,
81 | countryFlag: null,
82 | category: "No Category",
83 | subCategories: "No Sub Categories",
84 | description: '',
85 | newMessageCount: 0,
86 | timestampCustom: null,
87 | distance: '',
88 | context: 'JOBS',
89 | separater: true
90 | }
91 |
92 | const styles = StyleSheet.create({
93 | container: {
94 | backgroundColor: "white"
95 | },
96 | newJob: {
97 | margin: 5,
98 | borderRadius: 4,
99 | borderWidth: 2,
100 | borderColor: Color.color8,
101 | backgroundColor: "white"
102 | }
103 | })
104 | export default Card
--------------------------------------------------------------------------------
/src/components/ChatComponents/ChangeJobStatus/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | TouchableOpacity,
7 | Image
8 | } from 'react-native'
9 |
10 | // Local components
11 | import { Color } from '../../../global'
12 |
13 | // Icon
14 | import HandShakeWhite from './../../../../assets/hand-shake-white.png'
15 | import Tick from './../../../../assets/tick.png'
16 |
17 | /**
18 | * Overlay Component
19 | *
20 | * @version 1.0.0
21 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
22 | */
23 |
24 | class Overlay extends React.Component {
25 | render(){
26 | return(
33 |
43 |
44 |
48 |
54 |
55 |
56 | Mark job completed
63 |
64 |
65 |
66 |
75 |
76 |
80 |
86 |
87 |
88 | Change terms
95 |
96 |
97 |
98 | )
99 | }
100 | }
101 |
102 | Overlay.defaultProps = {
103 | onPressMarkJobCompleted: null,
104 | onPressChangeTerms: null
105 | }
106 | const styles = StyleSheet.create({
107 | container : {
108 | paddingHorizontal: 15
109 | }
110 | })
111 | export default Overlay
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { createAppContainer, createSwitchNavigator } from 'react-navigation';
3 | import { createStackNavigator } from 'react-navigation-stack';
4 | import { createBottomTabNavigator } from 'react-navigation-tabs';
5 | import {
6 | View,
7 | Text,
8 | Image
9 | } from 'react-native'
10 |
11 | // Screen Component
12 | import Home from './screens/home'
13 | import Page from './screens/page'
14 | import ChatScreen from './screens/chatscreen'
15 | import Login from './screens/login'
16 | import Jobs from './screens/jobs'
17 | import Menu from './screens/menu'
18 | import MyJobs from './screens/myjobs'
19 |
20 | // Icons
21 | import HomeIconBlue from './../assets/home-icon-blue.png'
22 | import HomeIconWhite from './../assets/home-icon-white.png'
23 | import HomeIconGray from './../assets/home-icon-gray.png'
24 | import BagIconBlue from './../assets/bag-icon-blue.png'
25 | import BagIconWhite from './../assets/bag-icon-white.png'
26 | import BagIconGray from './../assets/bag-icon-gray.png'
27 | import MenuIconBlue from './../assets/menu-icon-blue.png'
28 | import MenuIconWhite from './../assets/menu-icon-white.png'
29 | import MenuIconGray from './../assets/menu-icon-gray.png'
30 |
31 |
32 | // Config
33 | import { Color } from './global'
34 |
35 |
36 | // Tab Navigation
37 | const TabNavigator = createBottomTabNavigator( {
38 | Jobs,
39 | MyJobs: {
40 | screen: MyJobs
41 | },
42 | Menu
43 |
44 | } ,{
45 | defaultNavigationOptions: ({ navigation }) => ({
46 | tabBarIcon: ({ focused, horizontal, tintColor }) => {
47 | const { routeName } = navigation.state;
48 | let icon
49 | if (routeName === 'Jobs') {
50 | if( focused )
51 | icon=
52 | else icon =
53 | }
54 | else if( routeName === 'MyJobs') {
55 |
56 | if( focused )
57 | icon=
58 | else icon =
59 |
60 | }
61 | else if( routeName === 'Menu') {
62 |
63 | if( focused )
64 | icon=
65 | else icon =
66 |
67 | }
68 |
69 | // You can return any component that you like here!
70 | return
71 | { icon }
72 | ;
73 | },
74 | tabBarLabel: ({ focused, horizontal, tintColor }) => {
75 | const { routeName } = navigation.state;
76 | let labelName = null
77 | if (routeName === 'Jobs') {
78 | labelName = "Jobs nearby"
79 | }
80 | else if( routeName === 'MyJobs') {
81 | labelName = "My jobs"
82 | }
83 | else if( routeName === 'Menu') {
84 | labelName = "Menu"
85 | }
86 | // You can return any component that you like here!
87 | return
88 | {labelName}
89 |
90 | },
91 | }),
92 | tabBarOptions: {
93 | activeTintColor: Color.primary,
94 | style: {
95 | paddingBottom: 4,
96 | backgroundColor: Color.primary
97 | }
98 | },
99 | }
100 | );
101 |
102 | const screenStack = createStackNavigator({
103 | TabNavigator,
104 | ChatScreen
105 | },{
106 | defaultNavigationOptions: ({ navigation }) => ({
107 |
108 | header : null
109 | })
110 | })
111 |
112 | let AppNavigation = createSwitchNavigator({
113 | Home: {
114 | screen: Home
115 | },
116 | Screen: {
117 | screen: screenStack
118 | },
119 | Login: {
120 | screen: Login
121 | }
122 | },{
123 | initialRouteName: 'Login'
124 | })
125 |
126 | export default createAppContainer(AppNavigation)
--------------------------------------------------------------------------------
/src/components/ChatComponents/ChatInput/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | TextInput,
7 | Image,
8 | TouchableOpacity,
9 | KeyboardAvoidingView
10 | } from 'react-native'
11 | import PropTypes from 'prop-types'
12 | // Local components
13 | import Input from './../../Input'
14 | import ChangeJobStatus from './../ChangeJobStatus'
15 |
16 | // Icon
17 | import BagIconBlue from './../../../../assets/bag-icon-blue.png'
18 | import BagIconBlueOutline from './../../../../assets/bag-icon-blue-outline.png'
19 | import Clip from './../../../../assets/clip.png'
20 | import Camera from './../../../../assets/camera-icon.png'
21 |
22 |
23 | // Config
24 | import { Color } from './../../../global'
25 | import { Platform } from '@unimodules/core';
26 |
27 | /**
28 | * ChatInput Component
29 | *
30 | * @version 1.0.0
31 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
32 | */
33 |
34 | class ChatInput extends React.Component {
35 | state = {
36 | overlay: false
37 | }
38 |
39 | render(){
40 | return(
41 |
42 | { this.state.overlay && }
46 |
56 | {
58 | this.setState({ overlay: !this.state.overlay })
59 | }}
60 | style={{
61 | padding: 5
62 | }}
63 | >
64 |
70 |
71 |
80 |
90 |
91 |
97 |
103 |
104 |
110 |
116 |
117 |
118 | )
119 | }
120 | }
121 |
122 | /** Default Props */
123 | ChatInput.defaultProps = {
124 | onChangeChatInput: null,
125 | onPressChangeTerms: null,
126 | onPressMarkJobCompleted: null,
127 | onPressCamera: null,
128 | value: '',
129 | onPressAttachment: null
130 | }
131 |
132 | /** Prop Type */
133 | ChatInput.propTypes = {
134 | /** Description of prop "baz". */
135 | value: PropTypes.string,
136 | /**
137 | * Gets called when the user starts typing
138 | * @param {SyntheticEvent} event The react `SyntheticEvent`
139 | */
140 | onChangeChatInput: PropTypes.func,
141 | /** Called when changed terms button is pressed */
142 | onPressChangeTerms: PropTypes.func,
143 | /** Called when Mark Job Done button is pressed */
144 | onPressMarkJobCompleted: PropTypes.func,
145 | /** Called when camera button is pressed */
146 | onPressCamera: PropTypes.func,
147 | /** Called when attachment button is pressed */
148 | onPressAttachment: PropTypes.func
149 | }
150 |
151 | const styles = StyleSheet.create({
152 | container : {
153 | }
154 | })
155 | export default ChatInput
--------------------------------------------------------------------------------
/src/components/ChatComponents/Chat/priceask.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | Dimensions
8 | } from 'react-native'
9 |
10 | // Local components
11 | import Input from './../../Input'
12 |
13 | // Icons
14 | import MoneyBag from './../../../../assets/money-bag.png'
15 | import Tick from './../../../../assets/tick.png'
16 | import BlueDoubleTick from './../../../../assets/blue-double-tick.png'
17 | import DoubleTick from './../../../../assets/double-tick.png'
18 |
19 | // Config
20 | import { Color, normalize } from './../../../global'
21 |
22 | /**
23 | * PriceAsk Component
24 | *
25 | * @version 1.0.0
26 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
27 | */
28 |
29 | class PriceAsk extends React.Component {
30 | render(){
31 | return(
41 |
46 | How much are you asking for the job?
52 |
60 |
65 |
73 |
74 |
79 |
101 |
102 |
103 |
104 |
105 |
106 | { this.props.timestamp }
107 | {this.props.isRead === false || this.props.isRead === true ?
108 |
115 | : null }
116 |
117 |
118 |
119 |
120 | )
121 | }
122 | }
123 |
124 | PriceAsk.defaultProps = {
125 | tail: true,
126 | onChangePrice: null,
127 | onPressDone: null,
128 | isRead: null,
129 | timestamp: ''
130 |
131 | }
132 | const styles = StyleSheet.create({
133 | container : {
134 | paddingHorizontal: 15
135 | },
136 | messageContainer: {
137 | padding: 5,
138 | marginVertical: 5,
139 | width: Dimensions.get('window').width-50,
140 | },
141 | outgoing: {
142 | borderTopLeftRadius: 10,
143 | borderTopRightRadius: 10,
144 | borderBottomLeftRadius: 10,
145 | backgroundColor: '#D5FFCE'
146 | },
147 | incoming: {
148 | borderTopLeftRadius: 10,
149 | borderTopRightRadius: 10,
150 | borderBottomRightRadius: 10,
151 | backgroundColor: 'white'
152 | },
153 | chatboxFooterTimeStamp : {
154 | fontSize: 12,
155 | flexDirection: 'row'
156 | }
157 | })
158 | export default PriceAsk
159 |
160 |
161 |
--------------------------------------------------------------------------------
/src/screens/menu/userinfo.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Platform,
7 | Image,
8 | TouchableNativeFeedback,
9 | TouchableOpacity
10 | } from 'react-native'
11 |
12 | // Local components
13 | import { Color } from '../../global'
14 |
15 | // Icon
16 | import Avatar from './../../../assets/avatar.png'
17 | import RightArrow from './../../../assets/right-arrow.png'
18 | import TrustWhite from './../../../assets/trust-white.png'
19 | import Trust from './../../../assets/trust-icon.png'
20 |
21 |
22 |
23 | /**
24 | * UserInfo Component
25 | *
26 | * @version 1.0.0
27 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
28 | */
29 |
30 | class UserInfo extends React.Component {
31 |
32 | componentDidMount(){
33 | if(Platform.OS === "android")
34 | TouchableNativeFeedback.Ripple()
35 | }
36 |
37 | render(){
38 | return (
44 |
59 |
65 |
66 |
74 |
75 | {/* Seperatpr */}
76 |
81 |
82 |
86 |
92 | { this.props.name }
98 | { this.props.isVarified && }
105 |
106 |
109 | My balance:
115 | ${ this.props.balance }
123 |
124 |
125 |
129 |
135 |
136 |
137 | { !this.props.isVarified &&
147 |
152 |
158 |
164 |
165 |
166 | Verify account
173 |
174 |
175 | }
176 | )
177 | }
178 | }
179 |
180 | UserInfo.defaultProps = {
181 | name: '',
182 | balance: 0,
183 | isVarified: false,
184 | avatar: null
185 | }
186 | const styles = StyleSheet.create({
187 | container : {
188 | paddingHorizontal: 10
189 | },
190 | shadow : Platform.os === "ios" ? {
191 | shadowColor: "#000",
192 | shadowOffset: {
193 | width: 0,
194 | height: 2,
195 | },
196 | shadowOpacity: 0.25,
197 | shadowRadius: 3.84,
198 | } : {
199 | elevation: 5
200 | }
201 | })
202 | export default UserInfo
--------------------------------------------------------------------------------
/src/screens/page/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import {
3 | View,
4 | Text,
5 | Button,
6 | ScrollView,
7 | TouchableOpacity,
8 | Image
9 | } from 'react-native'
10 | import CutomButton from './../../components/Button'
11 | import Search from './../../components/Search'
12 | import ItemContainer from './../../components/ItemContainer'
13 | import BagLogo from './../../../assets/baglogo.png'
14 | import IonMenu from './../../../assets/ion-menu.png'
15 | import Avatar from './../../../assets/avatar.png'
16 | import DownArrow from './../../../assets/arrow-down.png'
17 | import Background from './../../../assets/background.png'
18 | import Chat from './../../components/ChatComponents/Chat'
19 |
20 |
21 |
22 |
23 | const items = [
24 | {
25 | name:"Kendall Jackson Vintner's Reserve Chardonnay",
26 | discount: null,
27 | quantity: 1,
28 | amount: '349.38',
29 | url: null
30 | },
31 | {
32 | name:"Kendall Jackson Vintner's Reserve Chardonnay Luxury Wine",
33 | discount: null,
34 | quantity: 2,
35 | amount: '2035.67',
36 | url: null
37 | },
38 | {
39 | name:"Kendall Chardonnay",
40 | discount: null,
41 | quantity: 1,
42 | amount: '349.38',
43 | url: null
44 | },
45 | {
46 | name:"Kendall Jackson Vintner's Reserve Chardonnay ",
47 | discount: null,
48 | quantity: 1,
49 | amount: '5349.38',
50 | url: null
51 | },
52 | {
53 | name:"Jackson Luxury Wine",
54 | discount: 10,
55 | quantity: 2,
56 | amount: '439.98',
57 | url: null
58 | }
59 | ]
60 | class Page extends Component {
61 | static navigationOptions = {
62 | headerRight: () =>
70 |
71 |
72 |
73 | ,
74 | headerLeft: () =>
82 |
83 |
84 |
85 | ,
86 | headerTitle: () => (
87 |
88 | alert('This is button')} style={{ flexDirection: 'row', alignItems: 'center' }}>
89 |
90 | Johnissimus Van-Doe
91 |
92 |
93 |
94 | ),
95 |
96 | };
97 | render(){
98 | return(
99 |
100 | {/* Buttons Container */}
101 |
102 | {
104 | this.props.navigation.navigate('PageStack')
105 | }}
106 | logo={BagLogo}
107 | backgroundColor= "#28A745"
108 | title={'Club Member'}/>
109 |
110 |
111 | {/* List Container */}
112 |
113 |
114 |
115 |
116 |
117 |
118 | {/* Checkout Container */}
119 |
120 |
121 | {
128 | this.props.navigation.navigate('PageStack')
129 | }}
130 | title={'New Order'}/>
131 | {
140 | this.props.navigation.navigate('PageStack')
141 | }}
142 | title={'Cancel Order'}/>
143 |
144 |
145 | {
151 | this.props.navigation.navigate('PageStack')
152 | }}
153 | backgroundColor= "#002A5C"
154 | title={'Checkout'}/>
155 |
156 |
157 |
158 | )
159 | }
160 | }
161 |
162 | export default Page
--------------------------------------------------------------------------------
/src/components/ChatComponents/Chat/termschanged.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | Dimensions,
8 | Platform,
9 | TouchableOpacity
10 | } from 'react-native'
11 |
12 | // Local components
13 | import Input from './../../Input'
14 |
15 | // Icons
16 | import MoneyBag from './../../../../assets/money-bag.png'
17 | import Tick from './../../../../assets/tick.png'
18 | import ClockGreen from './../../../../assets/clock-green.png'
19 |
20 | // Config
21 | import { Color } from './../../../global'
22 |
23 | /**
24 | * TermsChanged Component
25 | *
26 | * @version 1.0.0
27 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
28 | */
29 |
30 | class TermsChanged extends React.Component {
31 | render(){
32 | return(
42 |
47 |
48 |
53 | The employer changed terms to ${ this.props.newPrice } in { this.props.newDuration } day{this.props.newDuration > 1 && 's'}.
58 |
59 |
64 | Do you accept?
70 |
71 |
72 |
77 |
83 |
92 |
93 |
97 |
103 |
104 |
105 | Yes
112 |
113 |
114 |
115 |
116 |
120 |
129 |
130 |
131 | No
137 |
138 |
139 |
140 |
141 |
142 |
143 | )
144 | }
145 | }
146 |
147 | TermsChanged.defaultProps = {
148 | tail: true,
149 | newPrice: 0,
150 | newDuration: 0
151 | }
152 | const styles = StyleSheet.create({
153 | container : {
154 | paddingHorizontal: 15
155 | },
156 | messageContainer: {
157 | padding: 5,
158 | marginVertical: 5,
159 | width: Dimensions.get('window').width-50,
160 | },
161 | outgoing: {
162 | borderTopLeftRadius: 10,
163 | borderTopRightRadius: 10,
164 | borderBottomLeftRadius: 10,
165 | backgroundColor: '#D5FFCE'
166 | },
167 | incoming: {
168 | borderTopLeftRadius: 10,
169 | borderTopRightRadius: 10,
170 | borderBottomRightRadius: 10,
171 | backgroundColor: 'white'
172 | },
173 | shadow : Platform.os === "ios" ? {
174 | shadowColor: "#000",
175 | shadowOffset: {
176 | width: 0,
177 | height: 2,
178 | },
179 | shadowOpacity: 0.25,
180 | shadowRadius: 3.84,
181 | } : {
182 | elevation: 5
183 | },
184 | })
185 | export default TermsChanged
186 |
187 |
188 |
--------------------------------------------------------------------------------
/src/components/ChatComponents/Chat/daysask.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | Dimensions,
8 | Platform,
9 | TouchableOpacity
10 | } from 'react-native'
11 |
12 | // Local components
13 | import Input from './../../Input'
14 |
15 | // Icons
16 | import MoneyBag from './../../../../assets/money-bag.png'
17 | import Tick from './../../../../assets/tick.png'
18 | import ClockGreen from './../../../../assets/clock-green.png'
19 | import BlueDoubleTick from './../../../../assets/blue-double-tick.png'
20 | import DoubleTick from './../../../../assets/double-tick.png'
21 |
22 | // Config
23 | import { Color, normalize} from './../../../global'
24 |
25 | /**
26 | * DaysAsk Component
27 | *
28 | * @version 1.0.0
29 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
30 | */
31 |
32 | class DaysAsk extends React.Component {
33 | render(){
34 | return(
44 |
49 | How much are you asking for the job?
55 |
62 |
67 |
75 |
76 |
81 |
96 |
97 |
103 | days
109 |
110 |
114 |
123 |
124 |
125 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | { this.props.timestamp }
139 | {this.props.isRead === false || this.props.isRead === true ?
140 |
147 | : null }
148 |
149 |
150 |
151 |
152 | )
153 | }
154 | }
155 |
156 | DaysAsk.defaultProps = {
157 | tail: true,
158 | onChangePrice: null,
159 | onPressDone: null,
160 | isRead: null,
161 | timestamp: ''
162 | }
163 | const styles = StyleSheet.create({
164 | container : {
165 | paddingHorizontal: 15
166 | },
167 | messageContainer: {
168 | padding: 5,
169 | marginVertical: 5,
170 | width: Dimensions.get('window').width-50,
171 | },
172 | outgoing: {
173 | borderTopLeftRadius: 10,
174 | borderTopRightRadius: 10,
175 | borderBottomLeftRadius: 10,
176 | backgroundColor: '#D5FFCE'
177 | },
178 | incoming: {
179 | borderTopLeftRadius: 10,
180 | borderTopRightRadius: 10,
181 | borderBottomRightRadius: 10,
182 | backgroundColor: 'white'
183 | },
184 | shadow : Platform.os === "ios" ? {
185 | shadowColor: "#000",
186 | shadowOffset: {
187 | width: 0,
188 | height: 2,
189 | },
190 | shadowOpacity: 0.25,
191 | shadowRadius: 3.84,
192 | } : {
193 | elevation: 5
194 | },
195 | chatboxFooterTimeStamp : {
196 | fontSize: 12,
197 | flexDirection: 'row'
198 | }
199 | })
200 | export default DaysAsk
201 |
202 |
203 |
--------------------------------------------------------------------------------
/src/screens/myjobs/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | Animated
8 | } from 'react-native'
9 | import Menu, { MenuItem, MenuDivider } from 'react-native-material-menu';
10 | import { getStatusBarHeight } from 'react-native-status-bar-height';
11 |
12 | // Local components
13 | import Header from './../../components/Header'
14 | import Card from './../../components/Card'
15 | import Search from './../../components/Search'
16 |
17 | // Icon
18 | import ThreeVerticalDots from './../../../assets/three-vertical-dots.png'
19 | // Config
20 | import { Color, normalize } from '../../global'
21 | import { TouchableOpacity } from 'react-native-gesture-handler'
22 |
23 | /**
24 | * Login Component
25 | *
26 | * @version 1.0.0
27 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
28 | */
29 | class MyJobs extends React.Component {
30 | _menu = null;
31 |
32 | constructor(props) {
33 | super(props)
34 |
35 | const scrollAnim = new Animated.Value(0)
36 | const offsetAnim = new Animated.Value(0)
37 |
38 | this.state = {
39 | scrollAnim,
40 | offsetAnim,
41 | clampedScroll: Animated.diffClamp(
42 | Animated.add(
43 | scrollAnim.interpolate({
44 | inputRange: [ 0, 1 ],
45 | outputRange: [ 0, 1 ],
46 | extrapolateLeft: 'clamp'
47 | }),
48 | offsetAnim
49 | ),
50 | 0,
51 | 112
52 | )
53 | };
54 | }
55 |
56 | setMenuRef = ref => {
57 | this._menu = ref;
58 | };
59 |
60 | hideMenu = () => {
61 | this._menu.hide();
62 | };
63 |
64 | showMenu = () => {
65 | this._menu.show();
66 | };
67 |
68 | render(){
69 |
70 | return(
71 | }
78 | mainText = "My jobs"
79 | contextMenu={
80 | [
81 | {
82 | text: 'Job archive',
83 | onPress: () =>{
84 | alert('Button')
85 | }
86 | },
87 | {
88 | text: 'Log out',
89 | onPress: () =>{
90 | alert('Button')
91 | }
92 | }
93 | ]
94 | }
95 | />
96 |
116 | {
118 | alert('Job Card')
119 | }}
120 | jobState="JOB_IN_PROGRESS"
121 | bid = {{
122 | acceptedPrice: 1000,
123 | proposedPrice: 1000,
124 | days: 10
125 | }}
126 | description="Hello John! I have done a couple of similar project on"
127 | jobTitle="Build website on WordPress using PHP"
128 | userName="John Doe"
129 | distance = '0.5 Km'
130 | isRead= { false }
131 | timestampCustom = {Hired 21 days}
132 | jobType= "ONE_TIME"
133 | context= "MY_JOBS"
134 | category= {'Web Design'}
135 | subCategories= "WordPress, HTML/CSS, CRM, JavaScript"
136 | />
137 | {
139 | alert('Job Card')
140 | }}
141 | jobState="JOB_AWAIT_CONFIRMATION"
142 | bid = {{
143 | acceptedPrice: 1000,
144 | proposedPrice: 1000,
145 | days: 10
146 | }}
147 | description="Hello John! I have done a couple of similar project on"
148 | jobTitle="Build website on WordPress using PHP"
149 | userName="John Doe"
150 | distance = '0.5 Km'
151 | isRead= { false }
152 | timestampCustom = {Hired 21 hrs 50 m}
153 | jobType= "ONE_TIME"
154 | context= "MY_JOBS"
155 | category= {'Web Design'}
156 | subCategories= "WordPress, HTML/CSS, CRM, JavaScript"
157 | />
158 | {
160 | alert('Job Card')
161 | }}
162 | jobState="BID_REJECTED"
163 | bid = {{
164 | acceptedPrice: 1000,
165 | proposedPrice: 1000,
166 | days: 0
167 | }}
168 | onPress={()=>{
169 | this.props.navigation.navigate('ChatScreen',{
170 | jobState: "BID_REJECTED",
171 | varified: true,
172 | oIcon: true
173 | })
174 | }}
175 | description="Hello John! I have done a couple of similar project on"
176 | jobTitle="Build website on WordPress using PHP"
177 | userName="John Doe"
178 | distance = '0.5 Km'
179 | isRead= { false }
180 | timestamp='2 min'
181 | jobType= "ONE_TIME"
182 | context= "MY_JOBS"
183 | category= {'Web Design'}
184 | subCategories= "WordPress, HTML/CSS, CRM, JavaScript"
185 | />
186 |
187 | )
188 | }
189 | }
190 |
191 | const styles = StyleSheet.create({
192 | container: {
193 | backgroundColor: '#fff',
194 | flex: 1
195 | },
196 | searchContainer : {
197 | paddingHorizontal: 15,
198 | backgroundColor: '#FAFAFA',
199 | zIndex: 40
200 |
201 | },
202 | shadow : Platform.OS === "ios" ? {
203 | shadowColor: "#000",
204 | shadowOffset: {
205 | width: 0,
206 | height: 2,
207 | },
208 | shadowOpacity: 0.25,
209 | shadowRadius: 3.84,
210 | } : {
211 | elevation: 5
212 | }
213 | })
214 |
215 | export default MyJobs
--------------------------------------------------------------------------------
/src/components/Card/cardheader.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image
7 | } from 'react-native'
8 |
9 | // Local components
10 | import { Color } from './../../global'
11 |
12 | // Icons
13 | import MapIcon from './../../../assets/map.png'
14 | import Avatar from './../../../assets/avatar.png'
15 | import RightArrow from './../../../assets/right-arrow.png'
16 | import NewMessage from './../../../assets/new-message-icon.png'
17 | import Flag from './../../../assets/flag.png'
18 |
19 |
20 | /**
21 | * CardHeader Component
22 | *
23 | * @version 1.0.0
24 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
25 | */
26 |
27 | class CardHeader extends React.Component {
28 | render() {
29 | return (
30 |
31 | {/* For avatar */}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | {/* User details */}
41 |
42 |
43 |
44 |
52 | {this.props.userName}
53 |
54 | {!this.props.timestampCustom ? {this.props.timestamp} : this.props.timestampCustom}
55 |
56 |
57 |
58 |
59 | {this.props.jobTitle}
67 |
68 |
69 |
70 |
71 | {/* User's Address Container */}
72 |
73 |
74 | {/* Map logo */}
75 |
76 |
77 |
78 | {/* Distance */}
79 | {this.props.distance}
86 |
87 |
88 | {/* Address */}
89 |
90 | {this.props.address}
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | {this.props.jobState === "NEW_JOB" &&
103 |
104 | }
105 | {this.props.jobState === "NEW_MESSAGE" &&
106 |
116 | 9 ? 10 : 14 }}>{this.props.newMessageCount}
117 |
118 | }
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | )
127 | }
128 | }
129 |
130 | // Default Props
131 | CardHeader.defaultProps = {
132 | jobState: null,
133 | userName: 'No name',
134 | jobTitle: 'No job title',
135 | distance: '',
136 | avatarUri: null,
137 | countryFlag: null,
138 | address: 'No address',
139 | timestamp: '',
140 | timestampCustom: null,
141 | newMessageCount: 0,
142 | distance: '0 km'
143 | }
144 |
145 | const styles = StyleSheet.create({
146 | container: {
147 | paddingHorizontal: 10,
148 | paddingVertical: 10,
149 | flexDirection: 'row',
150 | },
151 | nameContainer: {
152 | justifyContent: 'space-between',
153 | flexDirection: 'row',
154 | },
155 | addressContainer: {
156 | flexDirection: 'row',
157 | marginTop: 4
158 | },
159 | avatarContainer: {
160 |
161 | }
162 | })
163 | export default CardHeader
--------------------------------------------------------------------------------
/src/components/Header/index.js:
--------------------------------------------------------------------------------
1 | import React,{ Fragment } from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Platform,
7 | Animated,
8 | TouchableOpacity,
9 | Image,
10 | Dimensions
11 | } from 'react-native'
12 | import { getStatusBarHeight } from 'react-native-status-bar-height';
13 | import PropTypes from 'prop-types';
14 | import Menu, { MenuItem, MenuDivider } from 'react-native-material-menu';
15 |
16 | // Config
17 | import { Color } from './../../global'
18 |
19 | // Icon
20 | import ThreeVerticalDots from './../../../assets/three-vertical-dots.png'
21 |
22 | /**
23 | * Header Component
24 | *
25 | * @version 1.0.0
26 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
27 | */
28 | class Header extends React.Component {
29 | _menu = null;
30 | state = {
31 | position: 0
32 | }
33 |
34 | setMenuRef = ref => {
35 | this._menu = ref;
36 | };
37 |
38 | hideMenu = () => {
39 | this._menu.hide();
40 | };
41 |
42 | showMenu = () => {
43 | this._menu.show();
44 | };
45 |
46 | renderMenuItems = () => {
47 | return this.props.contextMenu.map(( item, index )=>{
48 | return
49 |
53 |
54 |
55 | })
56 | }
57 |
58 | render() {
59 | console.log("======================")
60 | let changeSearch
61 | changeSearch = this.props.clampedScroll && this.props.clampedScroll.interpolate({
62 | inputRange: [ 0, 112 ],
63 | outputRange: [ 0, -112],
64 | extrapolate: 'clamp'
65 | })
66 |
67 | let changeTop = this.props.clampedScroll && this.props.clampedScroll.interpolate({
68 | inputRange: [ 56 , 80 ],
69 | outputRange: [ 1, 0],
70 | extrapolate: 'clamp'
71 | })
72 | let fadeInOut = this.props.clampedScroll && this.props.clampedScroll.interpolate({
73 | inputRange: [ 60, 80 ],
74 | outputRange: [ 0, 1 ],
75 | extrapolate: 'clamp'
76 | })
77 | if( this.props.type === "custom"){
78 | return
79 |
88 |
89 | { this.props.children }
90 |
91 | }
92 | else
93 | return(
94 |
104 |
105 |
116 | { this.props.mainText }
121 |
122 |
135 |
136 | { this.props.mainText }
141 | {this.props.contextMenu && }
166 |
167 |
184 | { this.props.bottomComponent }
185 |
186 |
187 | )
188 | }
189 | }
190 |
191 | // Default props
192 | Header.defaultProps = {
193 | type : null,
194 | style : null,
195 | mainText: '',
196 | bottomComponent: null,
197 | contextMenu: null
198 | }
199 |
200 | // Props types
201 | Header.propTypes = {
202 | // Style config
203 | style : PropTypes.object,
204 | /*
205 | type to custom component
206 | takes 'custom' or null
207 | */
208 | type: PropTypes.oneOf([ 'custom', null ]),
209 | }
210 |
211 | const styles = StyleSheet.create({
212 | container: {
213 | marginTop: getStatusBarHeight(),
214 | justifyContent: 'center',
215 | backgroundColor :'#fff'
216 | },
217 | shadow : Platform.OS === "ios" ? {
218 | shadowColor: "#000",
219 | shadowOffset: {
220 | width: 0,
221 | height: 2,
222 | },
223 | shadowOpacity: 0.25,
224 | shadowRadius: 3.84,
225 | } : {
226 | elevation: 5
227 | },
228 | searchContainer : {
229 | paddingHorizontal: 15,
230 | backgroundColor: '#FAFAFA'
231 | }
232 | })
233 |
234 |
235 | export default Header
--------------------------------------------------------------------------------
/src/components/ChatComponents/ChatJobDescription/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Platform,
7 | Image,
8 | TouchableOpacity
9 | } from 'react-native'
10 |
11 | // Local components
12 | import { Color, normalize } from '../../../global'
13 |
14 | // Icon
15 | import BlueDoubleTick from './../../../../assets/blue-double-tick.png'
16 | import DoubleTick from './../../../../assets/double-tick.png'
17 | import DocxIcon from './../../../../assets/docx.png'
18 | import Download from './../../../../assets/download.png'
19 |
20 | /**
21 | * ChatJobDescription Component
22 | *
23 | * @version 1.0.0
24 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
25 | */
26 |
27 | class ChatJobDescription extends React.Component {
28 |
29 | renderAdditionalInfo = () => {
30 | return this.props.additionalInfo.map( ({ question, answer },index) => {
31 | return(
32 | { question }
33 | { answer}
34 | )
35 | })
36 | }
37 | render(){
38 | return (
42 |
51 |
52 | { this.props.title }
59 |
60 |
61 |
70 |
71 | { this.props.body }
72 |
73 |
74 | {this.props.additionalInfo.length > 0 &&
79 | Additional info
85 | {this.renderAdditionalInfo()}
86 | }
87 | { this.props.document.type &&
89 | { this.props.document.previewImage && }
98 |
104 |
105 |
112 |
113 |
114 | { this.props.document.name }
120 |
121 |
122 |
129 |
130 |
131 | }
132 |
133 |
134 | {this.props.document.type &&
135 | {this.props.document.pages} page{this.props.document.pages > 1 && 's'} • { this.props.document.type.toUpperCase() } • { this.props.document.size } mb
136 | }
137 |
138 | { this.props.timestamp }
139 | {this.props.isRead === false || this.props.isRead === true ?
140 |
147 | : null }
148 |
149 |
150 |
151 | )
152 |
153 | }
154 | }
155 |
156 | ChatJobDescription.defaultProps = {
157 | // This will take OFFER_APPROVAL, OFFER_ACCEPTED, OFFER_REJECTED
158 | headerIcon: null,
159 | title: '',
160 | body: null,
161 | type: 'warn',
162 | isRead: null,
163 | additionalInfo:[],
164 | document: {
165 | type: null,
166 | uri: '',
167 | previewImage: null,
168 | pages: 0,
169 | size: 0,
170 | name: ''
171 | },
172 | onPressDownload: null
173 | }
174 |
175 | const styles = StyleSheet.create({
176 | container : {
177 | marginVertical: 5,
178 | marginBottom: 0,
179 | borderRadius: 10,
180 | marginHorizontal: 10,
181 | backgroundColor: 'white',
182 | paddingBottom: 5
183 | },
184 | shadow : Platform.os === "ios" ? {
185 | shadowColor: "#000",
186 | shadowOffset: {
187 | width: 0,
188 | height: 2,
189 | },
190 | shadowOpacity: 0.25,
191 | shadowRadius: 3.84,
192 | } : {
193 | elevation: 5
194 | },
195 | chatboxFooterTimeStamp : {
196 | fontSize: 12,
197 | flexDirection: 'row',
198 | paddingHorizontal: 5
199 | }
200 | })
201 | export default ChatJobDescription
--------------------------------------------------------------------------------
/src/components/Card/cardbody.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | Platform
8 | } from 'react-native'
9 |
10 | // Local components
11 | import { Color } from './../../global'
12 |
13 | // Icons
14 | import BlueDoubleTick from './../../../assets/blue-double-tick.png'
15 | import DoubleTick from './../../../assets/double-tick.png'
16 | import RateEmployer from './../../../assets/rate-employe.png'
17 |
18 | /**
19 | * CardBody Component
20 | *
21 | * @version 1.0.0
22 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
23 | */
24 |
25 | class CardBody extends React.Component {
26 |
27 | render() {
28 | let title = ''
29 | if (this.props.jobState === "BID_PLACED") {
30 | title = 'Set your price:'
31 | }
32 | else if (this.props.jobState === "BID_ACCEPTED")
33 | title = 'Funds in escrow :):'
34 |
35 |
36 | if (this.props.context === "MY_JOBS")
37 | title = "My payment:"
38 |
39 | return (
40 |
41 | {this.props.isRead === false || this.props.isRead === true ?
42 |
49 | : null}
50 |
51 | {this.props.description}
52 |
53 |
54 |
62 | {(this.props.jobState === "BID_PLACED" || this.props.jobState === "BID_REJECTED") &&
63 |
77 |
78 | {title}
79 |
80 | ${this.props.bid.acceptedPrice}
81 | out of
82 | {this.props.bid.proposedPrice > 0 ? `$` + this.props.bid.proposedPrice : '?'}
83 |
84 |
85 |
86 | Complete in:
87 |
88 | {this.props.bid.days > 0 ? this.props.bid.days : '?'}
89 | {this.props.bid.days > 0 && Days}
90 |
91 |
92 | }
93 | {(this.props.jobState === "BID_ACCEPTED" || this.props.jobState === "JOB_AWAIT_CONFIRMATION" || this.props.jobState === "JOB_IN_PROGRESS") &&
94 |
108 |
109 | {title}
110 |
111 | ${this.props.bid.acceptedPrice}
112 | out of
113 | ${this.props.bid.proposedPrice > 0 ? this.props.bid.proposedPrice : '?'}
114 |
115 |
116 |
117 | Complete in:
118 |
119 | {this.props.bid.days}
120 | Days
121 |
122 |
123 | }
124 | {this.props.jobState === "BID_COMPLETED_RELEASED" &&
125 |
139 |
140 | Paid :)
141 |
142 | +${this.props.bid.acceptedPrice}
143 |
144 |
145 |
146 | Rate employer
147 |
148 |
155 | ?
156 |
157 |
158 | }
159 |
160 | )
161 | }
162 | }
163 |
164 | CardBody.defaultProps = {
165 | isRead: null,
166 | jobState: null,
167 | bid: {
168 | acceptedPrice: 0,
169 | proposedPrice: 0,
170 | days: 0,
171 | status: ''
172 | },
173 | description: "No description",
174 | // It will take JOBS or MY_JOBS
175 | context: 'JOBS'
176 | }
177 | const styles = StyleSheet.create({
178 | container: {
179 | },
180 | descriptionContainer: {
181 | flexDirection: 'row',
182 | paddingHorizontal: 15
183 | },
184 | shadow: Platform.os === "ios" ? {
185 | shadowColor: "#000",
186 | shadowOffset: {
187 | width: 0,
188 | height: 1,
189 | },
190 | shadowOpacity: 0.22,
191 | shadowRadius: 2.22,
192 | } : {
193 | elevation: 3
194 | }
195 | })
196 | export default CardBody
--------------------------------------------------------------------------------
/src/screens/menu/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | ScrollView,
7 | Animated,
8 | Image,
9 | Platform,
10 | AsyncStorage,
11 | Picker
12 | } from 'react-native'
13 |
14 | // Local components
15 | import Header from './../../components/Header'
16 | import ItemContainer from './../../components/ItemContainer'
17 | import Item from './../../components/Item'
18 | import UserInfo from './userinfo'
19 | import BackgroundImage from './../../components/BackgroundImage'
20 |
21 | // Icon
22 | import Avatar from './../../../assets/avatar.png'
23 | import RightArrow from './../../../assets/right-arrow.png'
24 | import MyBusinessIcon from './../../../assets/my-business.png'
25 | import MyWork from './../../../assets/my-work.png'
26 | import WalletBlue from './../../../assets/wallet-blue.png'
27 | import Emoji from './../../../assets/emoji.png'
28 | import WithdrawFund from './../../../assets/withdraw-fund.png'
29 | import DepositFund from './../../../assets/deposit-fund.png'
30 | import Glob from './../../../assets/glob.png'
31 | import Setting from './../../../assets/setting.png'
32 | import Help from './../../../assets/help.png'
33 | import LoginBlack from './../../../assets/login-black.png'
34 |
35 | // Images
36 | import Background from './../../../assets/background-pattern-gray.png'
37 |
38 | // Config
39 | import { Color, normalize } from '../../global'
40 |
41 | class Menu extends React.Component {
42 |
43 | constructor(props) {
44 | super(props)
45 | this.state = {
46 | offsetY: 0,
47 | direction: -1,
48 | offsetAfterScrollEnd: 0,
49 | scrollY: new Animated.Value(0.01),
50 | };
51 | }
52 |
53 | render() {
54 | return (
55 |
56 | {/* Header Section */}
57 |
60 |
69 | Settings
74 |
75 |
76 |
77 |
78 | {
83 | alert('Do something')
84 | }}
85 | onPressVarifyAccount={() => {
86 | alert('Go to varification page')
87 | }}
88 | />
89 |
90 |
98 | }
99 | onPress={() => {
100 | alert('Do Something')
101 | }}
102 | text="My business"
103 | />
104 |
114 | }
115 | onPress={() => {
116 | alert('Do Something')
117 | }}
118 | text="My work areas"
119 | />
120 |
121 |
122 |
130 | }
131 | onPress={() => {
132 | alert('Do Something')
133 | }}
134 | text="Financial & Packages"
135 | />
136 |
144 | }
145 | onPress={() => {
146 | alert('Do Something')
147 | }}
148 | text="Withdraw funds"
149 | />
150 |
158 | }
159 | onPress={() => {
160 | alert('Do Something')
161 | }}
162 | text="Deposit funds"
163 | />
164 |
165 |
166 |
175 | }
176 | onPress={() => {
177 | alert('Do Something')
178 | }}
179 | text="Settings"
180 | />
181 |
190 | }
191 | style={{
192 | height: 62
193 | }}
194 | text="Language"
195 | rightComponent={
198 |
202 | this.setState({ language: itemValue })
203 | }>
204 |
205 |
206 |
207 |
208 |
209 | }
210 | />
211 |
212 |
213 |
222 | }
223 | onPress={() => {
224 | alert('Do Something')
225 | }}
226 | text="Help"
227 | />
228 |
237 | }
238 | onPress={() => {
239 | alert('Do Something')
240 | }}
241 | text="Tell a friend"
242 | />
243 |
244 |
245 |
254 | }
255 | onPress={() => {
256 | AsyncStorage.setItem('LOGGED', "false");
257 | this.props.navigation.navigate('Login');
258 | }}
259 | text="Log out"
260 | />
261 |
262 |
263 | )
264 | }
265 | }
266 |
267 | const styles = StyleSheet.create({
268 | container: {
269 | backgroundColor: '#E3E3E3',
270 | flex: 1
271 | },
272 | searchContainer: {
273 | paddingHorizontal: 15,
274 | },
275 | shadow: Platform.os === "ios" ? {
276 | shadowColor: "#000",
277 | shadowOffset: {
278 | width: 0,
279 | height: 2,
280 | },
281 | shadowOpacity: 0.25,
282 | shadowRadius: 3.84,
283 | } : {
284 | elevation: 5
285 | },
286 | shadow: Platform.OS === "ios" ? {
287 | shadowColor: "#000",
288 | shadowOffset: {
289 | width: 0,
290 | height: 2,
291 | },
292 | shadowOpacity: 0.25,
293 | shadowRadius: 3.84,
294 | } : {
295 | elevation: 5
296 | }
297 | })
298 | export default Menu
--------------------------------------------------------------------------------
/src/screens/chatscreen/chatheader.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | TouchableOpacity,
7 | Image
8 | } from 'react-native'
9 |
10 | // Local components
11 | import { Color } from './../../global'
12 | import Header from '../../components/Header'
13 |
14 | // Icons
15 | import LeftArrow from './../../../assets/left-arrow.png'
16 | import Phone from './../../../assets/phone-icon.png'
17 | import Avatar from './../../../assets/avatar.png'
18 | import Star from './../../../assets/star-icon.png'
19 | import oIcon from './../../../assets/o-icon.png'
20 | import Trust from './../../../assets/trust-icon.png'
21 | import MapIcon from './../../../assets/map.png'
22 |
23 | /**
24 | * ChatHeader Component
25 | *
26 | * @version 1.0.0
27 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
28 | */
29 |
30 | class ChatHeader extends React.Component {
31 | render(){
32 | return(
35 |
36 |
44 |
49 |
55 |
56 |
57 |
58 |
59 |
65 | { this.props.oIcon &&
73 |
79 | }
80 |
81 |
84 |
85 | { this.props.username }
92 | { this.props.varified && }
101 |
102 |
103 | { this.props.status }
112 |
121 | { this.props.rating }
127 |
128 |
129 |
130 |
131 |
134 |
145 |
146 |
152 |
153 |
154 |
155 |
156 |
165 |
170 |
176 |
177 |
178 | Saint Mark St 124f, LA, CA, 0421431
179 | 5.5 km
180 |
181 |
182 | { this.props.jobStatus === "BID_NOT_PLACED" &&
187 | Open for
192 | bidding
198 | }
199 | { this.props.jobStatus === "BID_PLACED" &&
204 | My payment
208 |
213 | ${this.props.bid?.acceptedPrice}
214 |
215 | Out of ${this.props.bid?.proposedPrice}
221 | }
222 | { this.props.jobStatus === "BID_ACCEPTED" &&
227 | My payment
231 |
236 | ${this.props.bid?.acceptedPrice}
237 |
238 | Out of ${this.props.bid?.proposedPrice}
244 | }
245 | { this.props.jobStatus === "BID_REJECTED" &&
250 |
255 | rejected
256 |
257 | }
258 |
259 |
260 | )
261 | }
262 | }
263 |
264 | ChatHeader.defaultProps = {
265 | username:'',
266 | status: 'online',
267 | rating: '0',
268 | avatar: null,
269 | oIcon : false,
270 | varified: false,
271 | bid: {
272 | acceptedPrice: 0,
273 | proposedPrice: 0,
274 | },
275 | jobStatus: 'BID_NOT_PLACED'
276 | }
277 | const styles = StyleSheet.create({
278 | container : {
279 | paddingHorizontal: 15
280 | },
281 | shadow : Platform.OS === "ios" ? {
282 | shadowColor: "#000",
283 | shadowOffset: {
284 | width: 0,
285 | height: 1,
286 | },
287 | shadowOpacity: 0.22,
288 | shadowRadius: 2.22,
289 | } : {
290 | elevation: 3
291 | }
292 | })
293 | export default ChatHeader
--------------------------------------------------------------------------------
/src/screens/jobs/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { FileSystem, Asset } from 'expo';
3 | import {
4 | View,
5 | StyleSheet,
6 | Animated,
7 | } from 'react-native'
8 | import { getStatusBarHeight } from 'react-native-status-bar-height';
9 | import * as Device from 'expo-device';
10 | // import { Thread } from 'react-native-threads';
11 | // import { Worker } from 'react-native-workers';
12 |
13 | // Local components
14 | import Header from './../../components/Header'
15 | import Search from './../../components/Search'
16 | import Card from './../../components/Card'
17 | import NoOpenJobAlert from './NoOpenJobAlert'
18 | import WorkAreaNotSet from './WorkAreaNotSet'
19 | import CutomButton from './../../components/Button'
20 |
21 | // Images
22 | import BackgroundImage from './../../components/BackgroundImage'
23 | // Config
24 | import { Color } from './../../global'
25 | import configs from '@utils/configs';
26 |
27 | import Database from '../../Database.js';
28 |
29 | const DB = new Database();
30 | let db = DB.openDatabase(db);
31 |
32 | class Jobs extends React.Component {
33 |
34 | constructor(props) {
35 | super(props)
36 |
37 | const scrollAnim = new Animated.Value(0)
38 | const offsetAnim = new Animated.Value(0)
39 |
40 | this.state = {
41 | jobs: [],
42 |
43 | entityId: 0,
44 | username: '',
45 | password: '',
46 | listKind: 0,
47 | jobId: 0,
48 | jobCategoryId: true,
49 | jobStatus: 0,
50 | searchText: '',
51 | limitForm: 0,
52 | limitCount: 0,
53 | searchBudgetMin: 0,
54 | SearchBudgetMax: 0,
55 | searchSkillId: true,
56 | searchCountryISO: true,
57 | searchStateISO: true,
58 | searchCityId: true,
59 | searchVerificationArray: true,
60 | searchEmploymentType: true,
61 | searchEntityId: 0,
62 | sortByDestination: '',
63 | languageISO: '',
64 |
65 | scrollAnim,
66 | offsetAnim,
67 | clampedScroll: Animated.diffClamp(
68 | Animated.add(
69 | scrollAnim.interpolate({
70 | inputRange: [0, 1],
71 | outputRange: [0, 1],
72 | extrapolateLeft: 'clamp'
73 | }),
74 | offsetAnim
75 | ), 0, 112
76 | )
77 | };
78 | }
79 |
80 | componentDidMount() {
81 | DB.initDatabase(db);
82 | // this.addCategories();
83 | this.addJobs();
84 | }
85 |
86 | addCategories() {
87 | const xmlHeader = '';
88 | const xmlRequest = '00';
89 | fetch(configs.jobURL, {
90 | method: 'POST',
91 | headers: {
92 | 'Authorization': 'Basic YWRtaW53ZWJzaXRlOk5mbjM5Zm5BQWQyMw==',
93 | 'Content-Type': 'text/xml',
94 | },
95 | body: xmlHeader + xmlRequest,
96 | }).then((response) => response.text())
97 | .then((responseText) => {
98 | const responseJson = JSON.parse(responseText.split('')[1].split('')[0]);
99 | DB.addCategories(db, responseJson);
100 | }).catch((error) => {
101 | return
102 | });
103 | }
104 |
105 | addJobs() {
106 | const { entityId, username, password, listKind, jobId, jobCategoryId, jobStatus, searchText, limitForm, limitCount, searchBudgetMin, SearchBudgetMax, searchSkillId, searchCountryISO, searchStateISO, searchCityId, searchVerificationArray, searchEmploymentType, searchEntityId, sortByDestination, languageISO } = this.state;
107 | const xmlHeader = '';
108 | const xmlRequest = '' + entityId + '' + username + '' + password + '' + listKind + '' + jobId + '' + jobCategoryId + '' + jobStatus + '' + searchText + '' + limitForm + '' + limitCount + '' + searchBudgetMin + '' + SearchBudgetMax + '' + searchSkillId + '' + searchCountryISO + '' + searchStateISO + '' + searchCityId + '' + searchVerificationArray + '' + searchEmploymentType + '' + searchEntityId + '' + sortByDestination + '' + languageISO + '';
109 | fetch(configs.jobURL, {
110 | method: 'POST',
111 | headers: {
112 | 'Authorization': 'Basic YWRtaW53ZWJzaXRlOk5mbjM5Zm5BQWQyMw==',
113 | 'Content-Type': 'text/xml',
114 | },
115 | body: xmlHeader + xmlRequest,
116 | }).then((response) => response.text())
117 | .then((responseText) => {
118 | const responseJson = JSON.parse(responseText.split('')[1].split('')[0]);
119 | DB.addJobs(db, responseJson);
120 | }).catch((error) => {
121 | return
122 | });
123 | }
124 |
125 | renderJobCards = () => {
126 | return
127 | {
128 | this.state.jobs.map((item, key) => {
129 | return (
130 | 0 ? true : false}
145 | timestamp='2 min'
146 | distance={item.Distance + ' Km'}
147 |
148 | onPress={() => {
149 | this.props.navigation.navigate('ChatScreen', {
150 | jobState: "BID_NOT_PLACED",
151 | varified: false
152 | })
153 | }}
154 | />
155 | );
156 | })
157 | }
158 |
159 | }
160 |
161 | render() {
162 | let changeTop = undefined;
163 | // To animate top header
164 | return (
165 |
166 |
167 | }
170 | mainText="Jobs"
171 | />
172 | {!this.state.noOpenJobs && !this.state.noWorkArea &&
173 | {
189 |
190 | }}
191 | >
192 | {this.renderJobCards()}
193 | {
199 | this.setState({ noWorkArea: true })
200 | }} />
201 | {
207 | this.setState({ noOpenJobs: true })
208 | }} />
209 |
210 | }
211 | {this.state.noOpenJobs &&
212 |
217 | {
223 | this.setState({ noOpenJobs: false })
224 | }} />
225 |
226 |
227 | }
228 | {this.state.noWorkArea &&
234 | {
240 | this.setState({ noWorkArea: false })
241 | }} />
242 | { alert('hello') }}
244 | />
245 |
246 | }
247 |
248 | )
249 | }
250 | }
251 |
252 | const styles = StyleSheet.create({
253 | container: {
254 | backgroundColor: '#E3E3E3',
255 | position: 'relative',
256 | flex: 1
257 | },
258 | searchContainer: {
259 | paddingHorizontal: 15,
260 | backgroundColor: '#FAFAFA'
261 | },
262 | shadow: Platform.OS === "ios" ? {
263 | shadowColor: "#000",
264 | shadowOffset: {
265 | width: 0,
266 | height: 2,
267 | },
268 | shadowOpacity: 0.25,
269 | shadowRadius: 3.84,
270 | } : {
271 | elevation: 5
272 | }
273 | })
274 | export default Jobs
275 |
--------------------------------------------------------------------------------
/src/screens/login/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | TextInput,
8 | KeyboardAvoidingView,
9 | Dimensions,
10 | Linking,
11 | AsyncStorage
12 | } from 'react-native'
13 | import { TouchableOpacity } from 'react-native-gesture-handler'
14 |
15 | // Redux
16 | import { connect } from 'react-redux';
17 | import { setUser } from '@modules/account/actions';
18 |
19 | // Icons or Images
20 | import Logo from './../../../assets/logo.png'
21 | import LoginIcon from './../../../assets/login.png'
22 | import FacebookIcon from './../../../assets/facebook_icon.png'
23 | import SignIn from './../../../assets/sign-in.png'
24 |
25 | // Components
26 | import CutomButton from './../../components/Button'
27 |
28 | // Functions
29 | import { verifyEmail, verifyPhone, verifyLength } from '@utils/Functions';
30 |
31 | // Globals
32 | import { Color } from './../../global'
33 | import { Platform } from '@unimodules/core';
34 | import configs from '@utils/configs';
35 |
36 | class Login extends React.Component {
37 |
38 | constructor(props) {
39 | super(props);
40 |
41 | this.state = {
42 | email: '',
43 | password: '',
44 | errorMessage: null
45 | }
46 | }
47 |
48 | onPressAlert = () => {
49 | alert("I am a button")
50 | }
51 | async componentDidMount() {
52 | if (await AsyncStorage.getItem('LOGGED') === "true") {
53 | this.props.navigation.navigate('Screen')
54 | }
55 | }
56 |
57 | onForgotPassword = () => {
58 | const { email } = this.state;
59 | if (!email) {
60 | this.setState({ errorMessage: 'Should not be empty' })
61 | } else {
62 | if (verifyEmail(email)) {
63 | this.setState({ errorMessage: '' });
64 | alert("Password reset instruction have been sent to " + email);
65 | } else {
66 | this.setState({ errorMessage: 'Email is invailed' });
67 | }
68 | }
69 | }
70 |
71 | onLogin = () => {
72 | const { email, password } = this.state;
73 | if (!email) {
74 | this.setState({ errorMessage: 'Enter your email address' })
75 | } else {
76 | if (verifyEmail(email)) {
77 | this.setState({ errorMessage: '' });
78 | if (!password) {
79 | this.setState({ errorMessage: 'Enter your password' })
80 | } else {
81 | if (verifyLength(password, 6)) {
82 | this.setState({ errorMessage: '' });
83 | this.onSubmit();
84 | } else {
85 | this.setState({ errorMessage: 'Enter more 6 charactors' });
86 | }
87 | }
88 | } else {
89 | this.setState({ errorMessage: 'Email is invailed' });
90 | }
91 | }
92 | }
93 |
94 | onSubmit() {
95 | const { email, password, errorMessage } = this.state;
96 | const xmlHeader = '';
97 | const xmlRequest = '' +
98 | '' + email + '' +
99 | '' + password + '' +
100 | // '209.95.60.92' +
101 | // 'EN' +
102 | ''
103 |
104 | fetch(configs.generalURL, {
105 | method: 'POST',
106 | headers: {
107 | 'Authorization': 'Basic YWRtaW53ZWJzaXRlOk5mbjM5Zm5BQWQyMw==',
108 | 'Content-Type': 'text/xml',
109 | },
110 | body: xmlHeader + xmlRequest,
111 | }).then((response) => response.text())
112 | .then((responseText) => {
113 | const responseJson = JSON.parse(responseText.split('')[1].split('')[0]);
114 | const ResultCode = responseJson.ResultCode;
115 | if(ResultCode == -1){
116 | alert(responseJson.ResultMessage);
117 | }
118 | else if(ResultCode == -2){
119 | alert("Description of database error");
120 | }
121 | else if(ResultCode > 0){
122 | AsyncStorage.setItem('LOGGED', "true");
123 | this.props.navigation.navigate('Screen');
124 | }
125 | }).catch((error) => {
126 | return
127 | });
128 |
129 | }
130 |
131 | render() {
132 | const { email, password, errorMessage } = this.state;
133 | return (
134 |
135 |
136 |
137 |
141 |
142 | Start
143 | A
144 | Job
145 |
146 |
147 |
148 |
149 |
150 | Please enter your login credentials
151 |
152 |
153 | this.setState({ email })}
162 | />
163 | this.setState({ password })}
171 | />
172 | {errorMessage ? {errorMessage} : null}
173 |
174 |
175 | this.onLogin()}
180 | logo={LoginIcon}
181 | fontWidth={'100'}
182 | fontSize={17}
183 | backgroundColor={Color.primary}
184 | title={'Login'} />
185 |
186 |
187 |
188 |
189 | this.onForgotPassword()}
191 | style={{ justifyContent: 'center' }}>
192 | Forgot your password?
196 |
197 |
198 |
206 | |
212 |
219 | Login via
224 | {/* Facebook login button */}
225 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
236 |
237 |
238 | New Here?
244 |
245 |
246 |
247 |
248 | Linking.openURL('https://www.startajob.com/signin?t=1&vt=0')}>
251 | Create an Account
258 |
259 |
260 |
261 |
262 |
263 |
264 | )
265 | }
266 | }
267 |
268 | // Props Types
269 | Login.propTypes = {
270 |
271 | }
272 |
273 | // Default Props
274 | Login.defaultProps = {
275 | title: 'No name'
276 | }
277 |
278 | const styles = StyleSheet.create({
279 | container: {
280 | flex: 1,
281 | backgroundColor: 'white'
282 | },
283 | top: {
284 | flex: 2,
285 | justifyContent: 'center',
286 | alignItems: 'center'
287 | },
288 | middle: {
289 | flex: 3,
290 | paddingHorizontal: 15
291 | },
292 | bottom: {
293 | alignItems: 'center',
294 | justifyContent: 'center'
295 | },
296 | logoImage: {
297 | height: 84,
298 | width: 84
299 | },
300 | textInput: {
301 | borderWidth: 2,
302 | borderColor: '#E3E3E3',
303 | borderRadius: 4,
304 | paddingHorizontal: 15,
305 | paddingVertical: Platform.OS === "ios" ? 12 : 8,
306 | fontSize: 13,
307 | color: '#121212',
308 | marginBottom: 10,
309 | backgroundColor: '#E3E3E3'
310 | },
311 | signinContainer: {
312 | marginTop: Dimensions.get("window").height > 600 ? 40 : 10,
313 | alignItems: 'center',
314 | justifyContent: 'center'
315 | }
316 | });
317 |
318 | export default Login
--------------------------------------------------------------------------------
/src/screens/chatscreen/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | ScrollView,
7 | Animated,
8 | Image,
9 | TouchableOpacity,
10 | KeyboardAvoidingView,
11 | SafeAreaView
12 | } from 'react-native'
13 |
14 | // Local components
15 | import Chat from './../../components/ChatComponents/Chat'
16 | import ChatAlert from '../../components/ChatComponents/ChatAlert'
17 | import ChatJobDescription from './../../components/ChatComponents/ChatJobDescription'
18 | import Label from './../../components/ChatComponents/label'
19 | import ChatInput from './../../components/ChatComponents/ChatInput'
20 | import ChatHeader from './chatheader'
21 |
22 | // Icons
23 | import SandWatch from './../../../assets/sand-watch-blue.png'
24 | import HandShake from './../../../assets/hand-shake-green.png'
25 | import Block from './../../../assets/block.png'
26 |
27 | // Images
28 | import Background from './../../../assets/background-pattern.png'
29 |
30 | // Config
31 | import { Color, normalize } from '../../global'
32 |
33 | /**
34 | * ChatScreen Component
35 | *
36 | * @version 1.0.0
37 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
38 | */
39 |
40 | class ChatScreen extends React.Component {
41 |
42 | constructor(props) {
43 | super(props)
44 | this.state = {
45 | value: '',
46 | offsetY: 0,
47 | inputDays: '',
48 | inputPrice: '',
49 | direction:-1 ,
50 | offsetAfterScrollEnd: 0,
51 | scrollY: new Animated.Value(0.01),
52 | };
53 | }
54 |
55 | render(){
56 | return(
58 | {
70 | alert('Call me')
71 | }}
72 | onPressBack = {() => {
73 | this.props.navigation.goBack()
74 | }}
75 | />
76 | {/* Background */}
77 |
84 |
97 |
98 | Need a professional WordPress developer to create a stunning website based on existing theme. Currently we use the “Z-Power” theme - search it in the WP store. HTML/CSS/PHP changes will be necessary. Write your experience with portfolio samples when applying.}
101 | additionalInfo={[
102 | {
103 | question: 'What WordPress version is used?',
104 | answer: '7.0.5'
105 | },
106 | {
107 | question: 'PHP knowledge required?',
108 | answer: 'Yes'
109 | }
110 | ]}
111 | timestamp = "15 min"
112 | document = {
113 | {
114 | type: 'pdf',
115 | uri: 'https://media.wired.com/photos/5dae0207c96358000859e5a9/master/pass/Gear-Google-Pixel-4-Front-and-Back-SOURCE-Google.jpg',
116 | previewImage: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/A_dictionary_of_the_Book_of_Mormon.pdf/page170-739px-A_dictionary_of_the_Book_of_Mormon.pdf.jpg',
117 | pages: 1,
118 | size: 2,
119 | name: 'Brand guidelines - 201',
120 | downloaded: false
121 | }
122 | }
123 | onPressDownload={()=>{
124 | alert("Download")
125 | }}
126 | />
127 |
138 | {
146 | alert('Change Price')
147 | }}
148 | onChangePrice={(text)=>{
149 | this.setState({ inputPrice: text })
150 | }}
151 | />
152 | {
160 | alert('Change date')
161 | }}
162 | onChangeDays={(text)=>{
163 | this.setState({ inputDays: text })
164 | }}
165 | />
166 | {
173 | alert('Yes')
174 | }}
175 | onPressNo = {() => {
176 | alert('No')
177 | }}
178 | />
179 | {
190 | alert('Download this file')
191 | }}
192 | onPress = {()=>{
193 | alert('Chat Pressed once')
194 | }}
195 | selected = {false}
196 | />
197 | {
210 | alert('Download this file')
211 | }}
212 | onPress = {()=>{
213 | alert('Chat Pressed once')
214 | }}
215 | selected = {false}
216 | isRead= {true}
217 | />
218 | {
229 | alert('Download this file')
230 | }}
231 | onPress = {()=>{
232 | alert('Chat Pressed once')
233 | }}
234 | selected = {false}
235 | type ='NORMAL'
236 | />
237 | {
242 | alert('Download this file')
243 | }}
244 | onPress = {()=>{
245 | alert('Chat Pressed once')
246 | }}
247 | selected = {false}
248 | document = {
249 | {
250 | type: 'pdf',
251 | uri: 'https://media.wired.com/photos/5dae0207c96358000859e5a9/master/pass/Gear-Google-Pixel-4-Front-and-Back-SOURCE-Google.jpg',
252 | previewImage: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/A_dictionary_of_the_Book_of_Mormon.pdf/page170-739px-A_dictionary_of_the_Book_of_Mormon.pdf.jpg',
253 | pages: 1,
254 | size: 2,
255 | name: 'Check this document',
256 | downloaded: false
257 | }
258 | }
259 | type ='NORMAL'
260 |
261 | />
262 |
269 | {
274 | alert('Chat Pressed once')
275 | }}
276 | type ='NORMAL'
277 | />
278 |
284 |
294 | }
295 | type='warn'
296 | title="Offer placed for $1500 in 14 days"
297 | body = {
298 | Waiting for other side to approve...
299 | }
300 | />
301 |
311 | }
312 | type='success'
313 | title="Offer placed for $1500 in 14 days"
314 | body = {
315 | The employer has accepted your offer.
320 | Ask your employer to deposit funds in this job
328 | }
329 | />
330 | {/* Diffrent Chat alerts */}
331 |
341 | }
342 | type='error'
343 | title="Your offer was rejected :("
344 | body = {
345 | You are welcome to set a new price for the job
351 | }
352 | />
353 |
354 |
355 | {/* Chat input */}
356 |
357 |
361 |
362 | )
363 | }
364 | }
365 |
366 | const styles = StyleSheet.create({
367 | container: {
368 | backgroundColor: Color.color4,
369 | flex: 1
370 | },
371 | searchContainer : {
372 | paddingHorizontal: 15
373 | }
374 | })
375 | export default ChatScreen
--------------------------------------------------------------------------------
/src/Database.js:
--------------------------------------------------------------------------------
1 | import * as SQLite from 'expo-sqlite';
2 |
3 | const database_name = "StartAJob.db";
4 | const database_version = "1.0";
5 | const database_description = "SQLite React Offline Database";
6 | const database_size = 200000;
7 |
8 |
9 |
10 |
11 | export default class Database {
12 | openDatabase() {
13 | return SQLite.openDatabase(
14 | database_name,
15 | database_version,
16 | database_description,
17 | database_size
18 | );
19 | }
20 | initDatabase(db) {
21 | if (db) {
22 | db.transaction((tx) => {
23 | tx.executeSql(`DROP TABLE IF EXISTS categories`, []);
24 | tx.executeSql(`CREATE TABLE IF NOT EXISTS categories (` +
25 | `JobCategoryID INTEGER NOT NULL, ` +
26 | `ParentID INTEGER DEFAULT NULL, ` +
27 | `Level INTEGER DEFAULT NULL, ` +
28 | `JobCategoryName TEXT DEFAULT NULL, ` +
29 | `JobCategoryName_he TEXT DEFAULT NULL, ` +
30 | `JobCategoryName_ru TEXT DEFAULT NULL, ` +
31 | `JobsCount INTEGER DEFAULT 0, ` +
32 | `proCount INTEGER DEFAULT 0, ` +
33 | `isLocal INTEGER DEFAULT 0, ` +
34 | `TabIndex INTEGER NOT NULL DEFAULT 0, ` +
35 | `isDeleted INTEGER DEFAULT 0, ` +
36 | `CostToBid NUMERIC DEFAULT 0.00, ` +
37 | `CostPerNotification NUMERIC DEFAULT 2.00, ` +
38 | `LastUsed NUMERIC DEFAULT NULL, ` +
39 | `classified INTEGER NOT NULL DEFAULT 0, ` +
40 | `SEO_title TEXT DEFAULT NULL, ` +
41 | `SEO_title_he TEXT DEFAULT NULL, ` +
42 | `SEO_title_ru TEXT DEFAULT NULL, ` +
43 | `SEO_Description TEXT DEFAULT NULL, ` +
44 | `SEO_description_he TEXT DEFAULT NULL, ` +
45 | `SEO_description_ru TEXT DEFAULT NULL, ` +
46 | `UpdateDate TEXT DEFAULT NULL` +
47 | `);`);
48 | // tx.executeSql(`CREATE TABLE IF NOT EXISTS categories_skills (` +
49 | // `JobCategoryID INTEGER DEFAULT NULL, ` +
50 | // `SkillID INTEGER DEFAULT NULL, ` +
51 | // `CreatedDate TEXT, ` +
52 | // `status INTEGER DEFAULT 1, ` +
53 | // `SuggestedCount INTEGER DEFAULT 0, ` +
54 | // `SuggestedEntityID TEXT DEFAULT NULL, ` +
55 | // `last_used_date NUMERIC DEFAULT NULL, ` +
56 | // `selected_count INTEGER NOT NULL DEFAULT 0` +
57 | // ');');
58 | // tx.executeSql(`CREATE TABLE IF NOT EXISTS entities_skills (` +
59 | // `ratingType INTEGER DEFAULT 1, ` +
60 | // `skillID INTEGER DEFAULT NULL, ` +
61 | // `entityID INTEGER DEFAULT NULL, ` +
62 | // `jobID INTEGER DEFAULT 0, ` +
63 | // `experienceID INTEGER DEFAULT 0, ` +
64 | // `createdDate TEXT, ` +
65 | // `completedjobs INTEGER DEFAULT 0, ` +
66 | // `ratingLevel INTEGER DEFAULT 0` +
67 | // `);`);
68 | tx.executeSql(`DROP TABLE IF EXISTS jobs`, []);
69 | tx.executeSql(`CREATE TABLE IF NOT EXISTS jobs (` +
70 | `JobID INTEGER NOT NULL, ` +
71 | `MainJobCategoryID INTEGER NOT NULL, ` +
72 | `JobCategoryID INTEGER NOT NULL, ` +
73 | `classified INTEGER DEFAULT 0, ` +
74 | `EntityID INTEGER NOT NULL, ` +
75 | `EntityFirstName TEXT DEFAULT NULL, ` +
76 | `EntityLastName TEXT DEFAULT NULL, ` +
77 | `EntityCity TEXT DEFAULT NULL, ` +
78 | `EntityCountry TEXT DEFAULT NULL, ` +
79 | `ISO3166 TEXT DEFAULT NULL, ` +
80 | `Title TEXT DEFAULT NULL, ` +
81 | `Description TEXT DEFAULT NULL, ` +
82 | `Budget NUMERIC DEFAULT NULL, ` +
83 | `CurrencyID INTEGER DEFAULT NULL, ` +
84 | `EmploymentType INTEGER DEFAULT NULL, ` +
85 | `PrefferedCountryISO3166 TEXT DEFAULT NULL, ` +
86 | `PrefferedStateISO TEXT DEFAULT NULL, ` +
87 | `PrefferedCityId INTEGER DEFAULT NULL, ` +
88 | `HiredEntityID INTEGER DEFAULT 0, ` +
89 | `isShowPhone INTEGER NOT NULL DEFAULT 0, ` +
90 | `MinOffer INTEGER DEFAULT 0, ` +
91 | `MaxOffer INTEGER DEFAULT 0, ` +
92 | `BidsCount INTEGER DEFAULT 0, ` +
93 | `JobLocation_altitude REAL DEFAULT 0, ` +
94 | `JobLocation_latitude REAL DEFAULT 0, ` +
95 | `CostToBidUSD REAL NOT NULL DEFAULT 0.00, ` +
96 | `CostToBidLocal REAL NOT NULL DEFAULT 0.00, ` +
97 | `CostToBidSymbol TEXT DEFAULT NULL, ` +
98 | `NewMessages INTEGER DEFAULT 0, ` +
99 | `CreateDate TEXT DEFAULT NULL, ` +
100 | `UpdateDate NUMERIC DEFAULT NULL, ` +
101 | `JobStatus INTEGER NOT NULL DEFAULT 0, ` +
102 | `JobLocation_address TEXT DEFAULT NULL, ` +
103 | `JobLocation_cityID INTEGER DEFAULT NULL, ` +
104 | `cityname TEXT DEFAULT NULL, ` +
105 | `JobLocation_districtID INTEGER DEFAULT NULL, ` +
106 | `JobLocation_districtID2 INTEGER DEFAULT NULL, ` +
107 | `JobLocation_stateISO TEXT DEFAULT NULL, ` +
108 | `JobLocation_countryISO3166 TEXT DEFAULT NULL, ` +
109 | `CountryId INTEGER DEFAULT NULL, ` +
110 | `CountryName TEXT DEFAULT '', ` +
111 | `ExpiredDate NUMERIC DEFAULT NULL, ` +
112 | `WorkingHour_Start NUMERIC DEFAULT NULL, ` +
113 | `WorkingHour_HoursPerDay INTEGER DEFAULT NULL, ` +
114 | `WorkingHour_DayPerWeek INTEGER DEFAULT NULL, ` +
115 | `CancelDate NUMERIC DEFAULT NULL, ` +
116 | `CancelReason INTEGER unsigned DEFAULT NULL, ` +
117 | `CancelReasonRemark TEXT DEFAULT NULL, ` +
118 | `DisputeExpiryDate NUMERIC DEFAULT NULL, ` +
119 | `employerEscrowId INTEGER DEFAULT NULL, ` +
120 | `employeeEscrowId INTEGER DEFAULT NULL, ` +
121 | `RequestedEntityId INTEGER DEFAULT NULL, ` +
122 | `Distance INTEGER DEFAULT NULL, ` +
123 | `Company TEXT DEFAULT NULL, ` +
124 | `PlacedBid INTEGER DEFAULT NULL,` +
125 | `Phone TEXT DEFAULT NULL, ` +
126 | `Rating REAL DEFAULT NULL` +
127 | `);`);
128 |
129 | // tx.executeSql(`CREATE TABLE IF NOT EXISTS jobs (` +
130 | // `JobID INTEGER NOT NULL, ` +
131 | // `JobCategoryID INTEGER NOT NULL, ` +
132 | // `EntityID INTEGER NOT NULL, ` +
133 | // `HiredEntityID INTEGER DEFAULT 0, ` +
134 | // `JobStatus INTEGER NOT NULL DEFAULT 0, ` +
135 | // `Title TEXT DEFAULT NULL, ` +
136 | // `Description TEXT DEFAULT NULL, ` +
137 | // `Budget NUMERIC DEFAULT NULL, ` +
138 | // `CurrencyID INTEGER DEFAULT NULL, ` +
139 | // `EmploymentType INTEGER DEFAULT NULL, ` +
140 | // `JobLocation_address TEXT DEFAULT NULL, ` +
141 | // `JobLocation_cityID INTEGER DEFAULT NULL, ` +
142 | // `JobLocation_districtID INTEGER DEFAULT NULL, ` +
143 | // `JobLocation_districtID2 INTEGER DEFAULT NULL, ` +
144 | // `JobLocation_stateISO TEXT DEFAULT NULL, ` +
145 | // `JobLocation_countryISO3166 TEXT DEFAULT NULL, ` +
146 | // `JobLocation_altitude REAL DEFAULT 0, ` +
147 | // `JobLocation_latitude REAL DEFAULT 0, ` +
148 | // `WorkingHour_Start NUMERIC DEFAULT NULL, ` +
149 | // `WorkingHour_HoursPerDay INTEGER DEFAULT NULL, ` +
150 | // `WorkingHour_DayPerWeek INTEGER DEFAULT NULL, ` +
151 | // `PrefferedRegionID TEXT DEFAULT NULL, ` +
152 | // `PrefferedCityId INTEGER DEFAULT NULL, ` +
153 | // `PrefferedCountryISO3166 TEXT DEFAULT NULL, ` +
154 | // `PrefferedStateISO TEXT DEFAULT NULL, ` +
155 | // `CreateDate TEXT, ` +
156 | // `HiredDate NUMERIC DEFAULT NULL, ` +
157 | // `UpdateDate NUMERIC DEFAULT NULL, ` +
158 | // `ExpiredDate NUMERIC DEFAULT NULL, ` +
159 | // `CancelDate NUMERIC DEFAULT NULL, ` +
160 | // `CancelReason INTEGER unsigned DEFAULT NULL, ` +
161 | // `CancelReasonRemark TEXT DEFAULT NULL, ` +
162 | // `NewMessages INTEGER DEFAULT 0, ` +
163 | // `MinBid INTEGER DEFAULT 0, ` +
164 | // `MaxBid INTEGER DEFAULT 0, ` +
165 | // `TotalBids INTEGER DEFAULT 0, ` +
166 | // `costtobidUSD REAL NOT NULL DEFAULT 0.00, ` +
167 | // `isMailed INTEGER NOT NULL DEFAULT 0, ` +
168 | // `isShowPhone INTEGER NOT NULL DEFAULT 0, ` +
169 | // `PrivateJob INTEGER NOT NULL DEFAULT 0, ` +
170 | // `isDonation INTEGER NOT NULL DEFAULT 0, ` +
171 | // `DonationDonners INTEGER NOT NULL DEFAULT 0, ` +
172 | // `DonationAmountCollected REAL NOT NULL DEFAULT 0.00, ` +
173 | // `Published_on_FB INTEGER NOT NULL DEFAULT 0, ` +
174 | // `Published_on_twttr INTEGER NOT NULL DEFAULT 0, ` +
175 | // `Published_on_Ig INTEGER NOT NULL DEFAULT 0` +
176 | // `);`);
177 | // tx.executeSql(`CREATE TABLE IF NOT EXISTS jobs_bids (` +
178 | // `BidID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ` +
179 | // `EntityID INTEGER DEFAULT NULL, ` +
180 | // `JobID INTEGER DEFAULT NULL, ` +
181 | // `DesiredSalaryREAL DEFAULT 0.00, ` +
182 | // `CurrencyID INTEGER DEFAULT NULL, ` +
183 | // `ComplateWithin INTEGER DEFAULT 0, ` +
184 | // `BidStatus INTEGER DEFAULT 0, ` +
185 | // `CreateDate TEXT DEFAULT NULL, ` +
186 | // `UpdateDate NUMERIC DEFAULT NULL, ` +
187 | // `deadline NUMERIC DEFAULT NULL, ` +
188 | // `BidOwnerNewMessages INTEGER DEFAULT 0, ` +
189 | // `JobOwnerNewMessages INTEGER DEFAULT 0, ` +
190 | // `UncoverPhoneDate NUMERIC DEFAULT NULL` +
191 | // `);`);
192 | // tx.executeSql(`CREATE TABLE IF NOT EXISTS jobs_bids_messages (` +
193 | // `MessageID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ` +
194 | // `EntityID INTEGER DEFAULT NULL, ` +
195 | // `BidID INTEGER DEFAULT NULL, ` +
196 | // `JobID INTEGER DEFAULT NULL, ` +
197 | // `MessageText TEXT DEFAULT NULL, ` +
198 | // `CreateDate TEXT NULL DEFAULT NULL, ` +
199 | // `Status INTEGER DEFAULT 0, ` +
200 | // `type INTEGER DEFAULT 0` +
201 | // `);`);
202 | // tx.executeSql(`CREATE TABLE IF NOT EXISTS jobs_bids_terms (` +
203 | // `termID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ` +
204 | // `jobID INTEGER NOT NULL, ` +
205 | // `bidID INTEGER DEFAULT NULL, ` +
206 | // `requestedDate TEXT DEFAULT NULL, ` +
207 | // `requestedEntityID INTEGER NOT NULL, ` +
208 | // `salary REAL DEFAULT NULL, ` +
209 | // `deadline NUMERIC DEFAULT NULL, ` +
210 | // `employerApprove INTEGER DEFAULT 0, ` +
211 | // `employeeApprove INTEGER DEFAULT 0, ` +
212 | // `ExpiryDate NUMERIC DEFAULT NULL` +
213 | // `);`);
214 | // tx.executeSql(`CREATE TABLE IF NOT EXISTS jobs_complete_request (` +
215 | // `requestsID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ` +
216 | // `CreatedDate TEXT NOT NULL DEFAULT NULL, ` +
217 | // `statusID INTEGER NOT NULL DEFAULT 0, ` +
218 | // `StatusDate NUMERIC NOT NULL, ` +
219 | // `jobID INTEGER NOT NULL, ` +
220 | // `bidID INTEGER NOT NULL, ` +
221 | // `entityID INTEGER NOT NULL, ` +
222 | // `salary REAL NOT NULL` +
223 | // `);`);
224 | // tx.executeSql(`CREATE TABLE IF NOT EXISTS jobs_skills (` +
225 | // `JobSkillID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ` +
226 | // `OwnerEntityID INTEGER DEFAULT 0, ` +
227 | // `JobID INTEGER DEFAULT 0, ` +
228 | // `SkillID INTEGER NOT NULL, ` +
229 | // `RatingLevel INTEGER DEFAULT 0, ` +
230 | // `HiredEntityID INTEGER DEFAULT 0` +
231 | // `);`);
232 | tx.executeSql(`CREATE TABLE IF NOT EXISTS skills (` +
233 | `SkillID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ` +
234 | `SkillName TEXT DEFAULT NULL, ` +
235 | `SkillName_he TEXT DEFAULT NULL, ` +
236 | `SkillName_ru TEXT DEFAULT NULL, ` +
237 | `status INTEGER DEFAULT 0, ` +
238 | `costToBidUSD REAL DEFAULT 0, ` +
239 | `SEO_title TEXT DEFAULT NULL, ` +
240 | `SEO_title_he TEXT DEFAULT NULL, ` +
241 | `SEO_title_ru TEXT DEFAULT NULL, ` +
242 | `SEO_description TEXT DEFAULT NULL, ` +
243 | `SEO_description_he TEXT DEFAULT NULL, ` +
244 | `SEO_description_ru TEXT DEFAULT NULL, ` +
245 | `UpdateDate TEXT DEFAULT NULL, ` +
246 | `allow_photo_upload INTEGER DEFAULT 1` +
247 | `);`);
248 | });
249 | } else {
250 | console.log("None Database in InitDatabase");
251 | }
252 | };
253 |
254 | addCategories(db, categories) {
255 | if (db) {
256 | db.transaction((tx) => {
257 | categories.map((category) => {
258 | tx.executeSql(`INSERT INTO categories ( JobCategoryID, ParentID, Level, JobCategoryName, JobsCount, proCount, isLocal, classified, SEO_title, SEO_description) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );`, [ category.JobCategoryID, category.ParentID, category.Level, category.JobCategoryName, category.JobsCount, category.proCount, category.isLocal, category.classified, category.SEO_title, category.SEO_description ]);
259 | });
260 | });
261 | this.getCategories(db);
262 | } else {
263 | console.log("None Database in InitDatabase");
264 | }
265 | }
266 |
267 | getCategories(db) {
268 | if (db) {
269 | db.transaction((tx) => {
270 | tx.executeSql(`SELECT * FROM categories;`, [], (trans, { rows }) => {
271 | console.log(rows);
272 | });
273 | });
274 | } else {
275 | console.log("None Database in InitDatabase");
276 | }
277 | }
278 |
279 | addJobs(db, jobs) {
280 | if (db) {
281 | db.transaction((tx) => {
282 | jobs.map((job) => {
283 | tx.executeSql(`INSERT INTO categories ( JobID, JobCategoryID, EntityID, JobCategoryName, JobsCount, proCount, isLocal, classified, SEO_title, SEO_description) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );`, [ category.JobCategoryID, category.ParentID, category.Level, category.JobCategoryName, category.JobsCount, category.proCount, category.isLocal, category.classified, category.SEO_title, category.SEO_description ]);
284 | });
285 | });
286 | // this.getJobs(db);
287 | } else {
288 | console.log("None Database in InitDatabase");
289 | }
290 | }
291 | }
--------------------------------------------------------------------------------
/src/components/ChatComponents/Chat/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import {
3 | View,
4 | Text,
5 | Image,
6 | StyleSheet,
7 | Platform,
8 | Dimensions,
9 | TouchableOpacity,
10 | TouchableHighlight
11 | } from 'react-native'
12 | import PropTypes from 'prop-types'
13 | import Autolink from 'react-native-autolink'
14 |
15 | // local components
16 | import Header from './../../Header'
17 | import Input from './../../Input'
18 | import PriceAsk from './priceask'
19 | import DaysAsk from './daysask'
20 | import TermsChanged from './termschanged'
21 |
22 |
23 | // Icons
24 | import BlueDoubleTick from './../../../../assets/blue-double-tick.png'
25 | import DoubleTick from './../../../../assets/double-tick.png'
26 | import DocxIcon from './../../../../assets/docx.png'
27 | import Download from './../../../../assets/download.png'
28 | import Camera from './../../../../assets/camera-icon.png'
29 | import Clock from './../../../../assets/clock.png'
30 | import Wallet from './../../../../assets/wallet.png'
31 | import SandWatch from './../../../../assets/sand-watch.png'
32 |
33 | // Config
34 | import { normalize, Color } from '../../../global'
35 |
36 | /**
37 | * Chat Component
38 | *
39 | * @version 1.0.0
40 | * @author [Ashwani Arya](https://github.com/ashwaniarya)
41 | */
42 |
43 | class Chat extends Component {
44 |
45 | state = {
46 | imgWidth: 0,
47 | imgHeight: 0,
48 | }
49 | componentDidMount() {
50 |
51 | if(this.props.image )
52 | Image.getSize(this.props.image, (width, height) => {
53 | // calculate image width and height
54 | const screenWidth = Dimensions.get('window').width
55 | const scaleFactor = width / screenWidth
56 | const imageHeight = height / scaleFactor
57 | this.setState({imgWidth: screenWidth, imgHeight: imageHeight})
58 | })
59 | }
60 |
61 | render(){
62 |
63 | return({
65 |
66 | }}
67 | style={[
68 | styles.container,
69 | styles.shadow,
70 | this.props.context === "outgoing" && { alignItems: 'flex-end' },
71 | this.props.tail && { marginBottom: 5 },
72 | this.props.selected && { backgroundColor: Color.color7, opacity: 0.6 }
73 | ]}>
74 |
77 | { this.props.type === "NORMAL" &&
82 |
83 | {/* Reply Segment */}
84 | {/* Reply on image */}
85 | { this.props.reply.type === "CHAT_IMAGE" &&
91 |
104 |
105 | { this.props.reply.title }
106 |
107 |
108 |
117 | { this.props.reply.description }
124 |
125 |
126 | { this.props.reply.previewImage &&
127 |
138 | }
139 | }
140 | {/* Reply on Chat_Bid */}
141 | { this.props.reply.type === "CHAT_BID" &&
147 |
161 |
167 |
168 | { this.props.reply.title }
169 |
170 |
175 |
181 |
188 |
189 | { this.props.reply.bidStatus }
190 |
191 |
192 |
197 |
198 |
203 |
210 |
211 | { this.props.reply.duration }
218 |
219 |
220 |
226 |
233 |
234 | ${ this.props.reply.proposedPrice }
241 |
242 |
243 |
244 | { this.props.reply.previewImage &&
245 |
256 | }
257 | }
258 | {/* To display link info based on props */}
259 | { this.props.link.url &&
267 |
268 |
276 |
277 |
282 | Dribbble
288 | dribbble.com
294 |
295 | }
296 | {/* To display image */}
297 | { this.props.image &&
298 |
308 | }
309 | {/* To display document */}
310 | { this.props.document.type &&
312 | { this.props.document.previewImage && }
320 |
326 |
327 |
334 |
335 |
336 | { this.props.document.name }
342 |
343 |
344 |
351 |
352 |
353 | }
354 | {/* To display chat text */}
355 | {this.props.text !== '' &&
358 |
361 | }
362 | {/* To display timesamp and doc information */}
363 |
364 |
365 | {this.props.document.type &&
366 | {this.props.document.pages} page{this.props.document.pages > 1 && 's'} • { this.props.document.type.toUpperCase() } • { this.props.document.size } mb
367 | }
368 |
369 | { this.props.timestamp }
370 | {this.props.isRead === false || this.props.isRead === true ?
371 |
378 | : null }
379 |
380 |
381 |
382 | }
383 | { this.props.type === "PRICE_ASK" && }
389 | { this.props.type === "DAYS_ASK" && }
395 | { this.props.type === "TERMS_CHANGED" && }
401 |
402 | )
403 | }
404 | }
405 |
406 | // Default Props
407 | Chat.defaultProps = {
408 | context: 'outgoing',
409 | reply: {
410 | // Can be CHAT_IMAGE, CHAT_BID, CHAT_NORMAL or null
411 | type: null,
412 | title: '',
413 | bidStatus: '',
414 | proposedPrice : 0,
415 | description: '',
416 | days: 0,
417 | previewImage : null
418 | },
419 | text: '',
420 | timestamp: '',
421 | image : null,
422 | link: {
423 | previewImage: null,
424 | title: '',
425 | domain: '',
426 | url: null
427 | },
428 | document: {
429 | type: null,
430 | uri: '',
431 | previewImage: null,
432 | pages: 0,
433 | size: 0,
434 | name: ''
435 | },
436 | tail: false,
437 | isRead: null,
438 | inputPrice: '',
439 | inputDays: '',
440 | newPrice: 0,
441 | newDuration: 0,
442 | // Will take 'NORMAL', 'PRICE_ASK', 'DAYS_ASK', 'TERMS_CHANGED' as value
443 | type: 'NORMAL',
444 | onPressDone: null,
445 | onChangePrice: null,
446 | onChangeDays: null,
447 | onPressYes: null,
448 | onPressNo: null
449 | }
450 |
451 | // Prop types
452 | Chat.propTypes = {
453 | /**
454 | * Make chat component left or right based on context
455 | */
456 | context: PropTypes.oneOf([ 'outgoing', 'incoming' ]),
457 | /** Message to be rendered */
458 | text: PropTypes.string,
459 | /** To show time
460 | * You must pass the time as string like 12 min, 5h
461 | */
462 | timestamp: PropTypes.string,
463 | /** Used when image is attached */
464 | image: PropTypes.string,
465 | /** Used to replay a message. Check default Props for more info
466 | */
467 | reply: PropTypes.object,
468 | /** Whether to show tail or not */
469 | tail: PropTypes.bool,
470 | /** What to do when download button is pressed */
471 | onPressDownload : PropTypes.func,
472 | isRead: PropTypes.oneOf([ true, false, null ]),
473 | type: PropTypes.oneOf([ 'NORMAL', 'PRICE_ASK', 'DAYS_ASK', 'TERMS_CHANGED' ])
474 | }
475 |
476 | const styles = StyleSheet.create({
477 | container: {
478 | marginBottom: 0,
479 | paddingHorizontal: 10
480 | },
481 | messageContainer: {
482 | padding: 5,
483 | marginVertical: 5,
484 | width: Dimensions.get('window').width-50,
485 | },
486 | outgoing: {
487 | borderTopLeftRadius: 10,
488 | borderTopRightRadius: 10,
489 | borderBottomLeftRadius: 10,
490 | backgroundColor: '#D5FFCE'
491 | },
492 | incoming: {
493 | borderTopLeftRadius: 10,
494 | borderTopRightRadius: 10,
495 | borderBottomRightRadius: 10,
496 | backgroundColor: 'white'
497 | },
498 | shadow : Platform.os === "ios" ? {
499 | shadowColor: "#000",
500 | shadowOffset: {
501 | width: 0,
502 | height: 2,
503 | },
504 | shadowOpacity: 0.25,
505 | shadowRadius: 3.84,
506 | } : {
507 | elevation: 5
508 | },
509 | chatboxText: {
510 | fontSize: 16,
511 | color: "#3D3D3D",
512 | lineHeight: 21
513 | },
514 | chatboxFooterAbsolute: {
515 | position: 'absolute',
516 | bottom: 10,
517 | right: 10
518 | },
519 | chatboxFooterTimeStamp : {
520 | fontSize: 12,
521 | flexDirection: 'row'
522 | }
523 | });
524 |
525 | export default Chat
--------------------------------------------------------------------------------