Compare commits

..

42 Commits
main ... server

Author SHA1 Message Date
Priyatham Sai Chand 577a94715f add env variables 2021-04-11 14:47:28 +05:30
Priyatham Sai Chand 891d3ea216 package-lock modify 2021-04-02 23:37:26 +05:30
Priyatham Sai Chand 0c341e2c81 merge mismatch delete 2021-04-02 19:26:17 +05:30
Priyatham-sai-chand 012dc763e4 merge change 2021-04-01 21:31:18 +05:30
Priyatham-sai-chand 13263e7abc ignore server modules 2021-04-01 20:35:12 +05:30
Priyatham-sai-chand 3a31fda96a Revert "migrate heroku env"
This reverts commit 069000dc9a.
2021-04-01 20:30:09 +05:30
Priyatham Sai Chand b07ec34ee6 Update Procfile 2021-04-01 20:30:09 +05:30
Priyatham Sai Chand b97ba8f216 migrate heroku env 2021-04-01 20:30:09 +05:30
Priyatham-sai-chand 8f74ca70d6 clean up update route 2021-04-01 20:30:09 +05:30
Priyatham-sai-chand 1c986d7417 git ignore node modules 2021-04-01 20:30:08 +05:30
Priyatham Sai Chand 5e956ab5a1 Update Procfile 2021-04-01 20:29:10 +05:30
Priyatham Sai Chand dcf0e059c8 create git ignore 2021-04-01 20:29:10 +05:30
Priyatham-sai-chand 42598d6f20 pricing update to db 2021-04-01 20:28:11 +05:30
Priyatham Sai Chand 5aae9ee8e0 pricing confirm 2021-04-01 20:28:11 +05:30
Priyatham-sai-chand 2e52230d32 homepage and pricing fix 2021-04-01 20:28:11 +05:30
Priyatham Sai Chand 98fc91e797 pricing update backend 2021-04-01 20:25:25 +05:30
Priyatham-sai-chand 6d0e02cbb4 navbar styled finish 2021-04-01 20:25:25 +05:30
Priyatham Sai Chand 24f93a997f procfile change 2021-04-01 20:25:25 +05:30
Priyatham Sai Chand b88e897cf0 GET / fix 2 2021-04-01 20:25:25 +05:30
Priyatham Sai Chand 1e252a8cde server GET / fix 2021-04-01 20:25:24 +05:30
Priyatham Sai Chand 0ac4a8b200 heroku server deploy 2021-04-01 20:25:24 +05:30
Priyatham-sai-chand 581b1bf7aa seperate folders for client and server 2021-04-01 20:24:36 +05:30
Priyatham-sai-chand 5cf48269df ignore server modules 2021-03-24 23:33:00 +05:30
Priyatham-sai-chand 833fd11d51 Revert "migrate heroku env"
This reverts commit 069000dc9a.
2021-03-24 23:32:18 +05:30
Priyatham-sai-chand 58f43356fa Merge branch 'server' of github.com:Priyatham-sai-chand/locaft into server 2021-03-24 23:17:57 +05:30
Priyatham Sai Chand 069000dc9a migrate heroku env 2021-03-24 23:17:28 +05:30
Priyatham Sai Chand a6eb6eab96
Update Procfile 2021-03-24 22:51:47 +05:30
Priyatham-sai-chand 14562bca3c clean up update route 2021-03-24 21:43:49 +05:30
Priyatham-sai-chand a4c35407d9 git ignore node modules 2021-03-24 13:17:47 +05:30
Priyatham-sai-chand 6ac108769d Merge branch 'server' of github.com:Priyatham-sai-chand/locaft into server 2021-03-24 13:16:05 +05:30
Priyatham Sai Chand 4d8b73a27d create git ignore 2021-03-24 13:15:31 +05:30
Priyatham Sai Chand e8e8ea33b6
Update Procfile 2021-03-24 11:22:02 +05:30
Priyatham-sai-chand 9e90363f4c pricing update to db 2021-03-24 08:35:53 +05:30
Priyatham Sai Chand 58602feaef pricing confirm 2021-03-23 23:31:06 +05:30
Priyatham-sai-chand 222f5fe6bf homepage and pricing fix 2021-03-21 22:58:11 +05:30
Priyatham Sai Chand ced7d230e9 pricing update backend 2021-03-20 16:56:05 +05:30
Priyatham-sai-chand d933dd2256 navbar styled finish 2021-03-18 18:59:48 +05:30
Priyatham Sai Chand 6d47e0919e procfile change 2021-03-18 10:10:01 +05:30
Priyatham Sai Chand 85e08ae734 GET / fix 2 2021-03-18 07:50:44 +05:30
Priyatham Sai Chand 2b97262ff4 server GET / fix 2021-03-18 07:39:41 +05:30
Priyatham Sai Chand 1442f55c2d heroku server deploy 2021-03-18 07:35:30 +05:30
Priyatham-sai-chand afd61b2517 seperate folders for client and server 2021-03-18 07:14:15 +05:30
63 changed files with 965 additions and 20244 deletions

5
.gitignore vendored
View File

@ -1,4 +1,3 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies # dependencies
client/node_modules client/node_modules
@ -7,6 +6,7 @@ client/.env
/client.pnp.js /client.pnp.js
server/node_modules server/node_modules
node_modules node_modules
# testing # testing
/coverage /coverage
@ -14,13 +14,12 @@ node_modules
/build /build
# misc # misc
.env
.DS_Store .DS_Store
.env.local .env.local
.env.development.local .env.development.local
.env.test.local .env.test.local
.env.production.local .env.production.local
.env
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*

1
Procfile Normal file
View File

@ -0,0 +1 @@
web: node server.js

24
middleware/auth.js Normal file
View File

@ -0,0 +1,24 @@
const jwt = require("jsonwebtoken");
const auth = (req, res, next) => {
try {
const token = req.header("x-auth-token");
if (!token)
return res
.status(401)
.json({ msg: "No authentication token, authorization denied." });
const verified = jwt.verify(token, process.env.jwtSecret);
if (!verified)
return res
.status(401)
.json({ msg: "Token verification failed, authorization denied." });
req.user = verified.id;
next();
} catch (err) {
res.status(500).json({ error: err.message });
}
};
module.exports = auth;

18215
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +1,28 @@
{ {
"name": "locaft", "name": "auth",
"version": "0.1.0", "version": "1.0.0",
"private": true, "description": "sign up and sign in auth",
"dependencies": { "main": "server.js",
"@fortawesome/fontawesome-svg-core": "^1.2.32",
"@fortawesome/free-brands-svg-icons": "^5.15.1",
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.13",
"@testing-library/jest-dom": "^5.11.5",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"axios": "^0.21.1",
"bootstrap": "^4.6.0",
"install": "^0.13.0",
"react": "^17.0.1",
"react-bootstrap": "^1.5.2",
"react-dom": "^17.0.1",
"react-google-login": "^5.2.2",
"react-lottie": "^1.2.3",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.3",
"styled-components": "^5.2.1",
"styled-icons": "^10.22.0",
"web-vitals": "^0.2.4"
},
"scripts": { "scripts": {
"start": "react-scripts start", "start": "node server.js",
"build": "react-scripts build", "app": "nodemon server.js"
"test": "react-scripts test",
"eject": "react-scripts eject",
"dev": "npm run start && nodemon index.js"
}, },
"eslintConfig": { "author": "B. Priyatham Sai chand",
"extends": [ "license": "ISC",
"react-app", "dependencies": {
"react-app/jest" "bcryptjs": "^2.4.3",
] "config": "^3.3.2",
"context": "^1.1.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-validator": "^6.6.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.10.13",
"nodemon": "^2.0.7"
}, },
"browserslist": { "engines": {
"production": [ "node": "14.x",
">0.2%", "npm": "6.14.8"
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
} }
} }

View File

@ -1 +0,0 @@
/* /index.html 200

View File

@ -1,46 +0,0 @@
<svg id="livetype" xmlns="http://www.w3.org/2000/svg" width="119.66407" height="40" viewBox="0 0 119.66407 40">
<title>Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917</title>
<g>
<g>
<g>
<path d="M110.13477,0H9.53468c-.3667,0-.729,0-1.09473.002-.30615.002-.60986.00781-.91895.0127A13.21476,13.21476,0,0,0,5.5171.19141a6.66509,6.66509,0,0,0-1.90088.627A6.43779,6.43779,0,0,0,1.99757,1.99707,6.25844,6.25844,0,0,0,.81935,3.61816a6.60119,6.60119,0,0,0-.625,1.90332,12.993,12.993,0,0,0-.1792,2.002C.00587,7.83008.00489,8.1377,0,8.44434V31.5586c.00489.3105.00587.6113.01515.9219a12.99232,12.99232,0,0,0,.1792,2.0019,6.58756,6.58756,0,0,0,.625,1.9043A6.20778,6.20778,0,0,0,1.99757,38.001a6.27445,6.27445,0,0,0,1.61865,1.1787,6.70082,6.70082,0,0,0,1.90088.6308,13.45514,13.45514,0,0,0,2.0039.1768c.30909.0068.6128.0107.91895.0107C8.80567,40,9.168,40,9.53468,40H110.13477c.3594,0,.7246,0,1.084-.002.3047,0,.6172-.0039.9219-.0107a13.279,13.279,0,0,0,2-.1768,6.80432,6.80432,0,0,0,1.9082-.6308,6.27742,6.27742,0,0,0,1.6172-1.1787,6.39482,6.39482,0,0,0,1.1816-1.6143,6.60413,6.60413,0,0,0,.6191-1.9043,13.50643,13.50643,0,0,0,.1856-2.0019c.0039-.3106.0039-.6114.0039-.9219.0078-.3633.0078-.7246.0078-1.0938V9.53613c0-.36621,0-.72949-.0078-1.09179,0-.30664,0-.61426-.0039-.9209a13.5071,13.5071,0,0,0-.1856-2.002,6.6177,6.6177,0,0,0-.6191-1.90332,6.46619,6.46619,0,0,0-2.7988-2.7998,6.76754,6.76754,0,0,0-1.9082-.627,13.04394,13.04394,0,0,0-2-.17676c-.3047-.00488-.6172-.01074-.9219-.01269-.3594-.002-.7246-.002-1.084-.002Z" style="fill: #a6a6a6"/>
<path d="M8.44483,39.125c-.30468,0-.602-.0039-.90429-.0107a12.68714,12.68714,0,0,1-1.86914-.1631,5.88381,5.88381,0,0,1-1.65674-.5479,5.40573,5.40573,0,0,1-1.397-1.0166,5.32082,5.32082,0,0,1-1.02051-1.3965,5.72186,5.72186,0,0,1-.543-1.6572,12.41351,12.41351,0,0,1-.1665-1.875c-.00634-.2109-.01464-.9131-.01464-.9131V8.44434S.88185,7.75293.8877,7.5498a12.37039,12.37039,0,0,1,.16553-1.87207,5.7555,5.7555,0,0,1,.54346-1.6621A5.37349,5.37349,0,0,1,2.61183,2.61768,5.56543,5.56543,0,0,1,4.01417,1.59521a5.82309,5.82309,0,0,1,1.65332-.54394A12.58589,12.58589,0,0,1,7.543.88721L8.44532.875H111.21387l.9131.0127a12.38493,12.38493,0,0,1,1.8584.16259,5.93833,5.93833,0,0,1,1.6709.54785,5.59374,5.59374,0,0,1,2.415,2.41993,5.76267,5.76267,0,0,1,.5352,1.64892,12.995,12.995,0,0,1,.1738,1.88721c.0029.2832.0029.5874.0029.89014.0079.375.0079.73193.0079,1.09179V30.4648c0,.3633,0,.7178-.0079,1.0752,0,.3252,0,.6231-.0039.9297a12.73126,12.73126,0,0,1-.1709,1.8535,5.739,5.739,0,0,1-.54,1.67,5.48029,5.48029,0,0,1-1.0156,1.3857,5.4129,5.4129,0,0,1-1.3994,1.0225,5.86168,5.86168,0,0,1-1.668.5498,12.54218,12.54218,0,0,1-1.8692.1631c-.2929.0068-.5996.0107-.8974.0107l-1.084.002Z"/>
</g>
<g id="_Group_" data-name="&lt;Group&gt;">
<g id="_Group_2" data-name="&lt;Group&gt;">
<g id="_Group_3" data-name="&lt;Group&gt;">
<path id="_Path_" data-name="&lt;Path&gt;" d="M24.76888,20.30068a4.94881,4.94881,0,0,1,2.35656-4.15206,5.06566,5.06566,0,0,0-3.99116-2.15768c-1.67924-.17626-3.30719,1.00483-4.1629,1.00483-.87227,0-2.18977-.98733-3.6085-.95814a5.31529,5.31529,0,0,0-4.47292,2.72787c-1.934,3.34842-.49141,8.26947,1.3612,10.97608.9269,1.32535,2.01018,2.8058,3.42763,2.7533,1.38706-.05753,1.9051-.88448,3.5794-.88448,1.65876,0,2.14479.88448,3.591.8511,1.48838-.02416,2.42613-1.33124,3.32051-2.66914a10.962,10.962,0,0,0,1.51842-3.09251A4.78205,4.78205,0,0,1,24.76888,20.30068Z" style="fill: #fff"/>
<path id="_Path_2" data-name="&lt;Path&gt;" d="M22.03725,12.21089a4.87248,4.87248,0,0,0,1.11452-3.49062,4.95746,4.95746,0,0,0-3.20758,1.65961,4.63634,4.63634,0,0,0-1.14371,3.36139A4.09905,4.09905,0,0,0,22.03725,12.21089Z" style="fill: #fff"/>
</g>
</g>
<g>
<path d="M42.30227,27.13965h-4.7334l-1.13672,3.35645H34.42727l4.4834-12.418h2.083l4.4834,12.418H43.438ZM38.0591,25.59082h3.752l-1.84961-5.44727h-.05176Z" style="fill: #fff"/>
<path d="M55.15969,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H48.4302v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C53.645,21.34766,55.15969,23.16406,55.15969,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C52.30227,29.01563,53.24953,27.81934,53.24953,25.96973Z" style="fill: #fff"/>
<path d="M65.12453,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H58.395v1.50586h.03418A3.21162,3.21162,0,0,1,61.312,21.34766C63.60988,21.34766,65.12453,23.16406,65.12453,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C62.26711,29.01563,63.21438,27.81934,63.21438,25.96973Z" style="fill: #fff"/>
<path d="M71.71047,27.03613c.1377,1.23145,1.334,2.04,2.96875,2.04,1.56641,0,2.69336-.80859,2.69336-1.91895,0-.96387-.67969-1.541-2.28906-1.93652l-1.60937-.3877c-2.28027-.55078-3.33887-1.61719-3.33887-3.34766,0-2.14258,1.86719-3.61426,4.51855-3.61426,2.624,0,4.42285,1.47168,4.4834,3.61426h-1.876c-.1123-1.23926-1.13672-1.9873-2.63379-1.9873s-2.52148.75684-2.52148,1.8584c0,.87793.6543,1.39453,2.25488,1.79l1.36816.33594c2.54785.60254,3.60645,1.626,3.60645,3.44238,0,2.32324-1.85059,3.77832-4.79395,3.77832-2.75391,0-4.61328-1.4209-4.7334-3.667Z" style="fill: #fff"/>
<path d="M83.34621,19.2998v2.14258h1.72168v1.47168H83.34621v4.99121c0,.77539.34473,1.13672,1.10156,1.13672a5.80752,5.80752,0,0,0,.61133-.043v1.46289a5.10351,5.10351,0,0,1-1.03223.08594c-1.833,0-2.54785-.68848-2.54785-2.44434V22.91406H80.16262V21.44238H81.479V19.2998Z" style="fill: #fff"/>
<path d="M86.065,25.96973c0-2.84863,1.67773-4.63867,4.29395-4.63867,2.625,0,4.29492,1.79,4.29492,4.63867,0,2.85645-1.66113,4.63867-4.29492,4.63867C87.72609,30.6084,86.065,28.82617,86.065,25.96973Zm6.69531,0c0-1.9541-.89551-3.10742-2.40137-3.10742s-2.40039,1.16211-2.40039,3.10742c0,1.96191.89453,3.10645,2.40039,3.10645S92.76027,27.93164,92.76027,25.96973Z" style="fill: #fff"/>
<path d="M96.18606,21.44238h1.77246v1.541h.043a2.1594,2.1594,0,0,1,2.17773-1.63574,2.86616,2.86616,0,0,1,.63672.06934v1.73828a2.59794,2.59794,0,0,0-.835-.1123,1.87264,1.87264,0,0,0-1.93652,2.083v5.37012h-1.8584Z" style="fill: #fff"/>
<path d="M109.3843,27.83691c-.25,1.64355-1.85059,2.77148-3.89844,2.77148-2.63379,0-4.26855-1.76465-4.26855-4.5957,0-2.83984,1.64355-4.68164,4.19043-4.68164,2.50488,0,4.08008,1.7207,4.08008,4.46582v.63672h-6.39453v.1123a2.358,2.358,0,0,0,2.43555,2.56445,2.04834,2.04834,0,0,0,2.09082-1.27344Zm-6.28223-2.70215h4.52637a2.1773,2.1773,0,0,0-2.2207-2.29785A2.292,2.292,0,0,0,103.10207,25.13477Z" style="fill: #fff"/>
</g>
</g>
</g>
<g id="_Group_4" data-name="&lt;Group&gt;">
<g>
<path d="M37.82619,8.731a2.63964,2.63964,0,0,1,2.80762,2.96484c0,1.90625-1.03027,3.002-2.80762,3.002H35.67092V8.731Zm-1.22852,5.123h1.125a1.87588,1.87588,0,0,0,1.96777-2.146,1.881,1.881,0,0,0-1.96777-2.13379h-1.125Z" style="fill: #fff"/>
<path d="M41.68068,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C44.57522,13.99463,45.01369,13.42432,45.01369,12.44434Z" style="fill: #fff"/>
<path d="M51.57326,14.69775h-.92187l-.93066-3.31641h-.07031l-.92676,3.31641h-.91309l-1.24121-4.50293h.90137l.80664,3.436h.06641l.92578-3.436h.85254l.92578,3.436h.07031l.80273-3.436h.88867Z" style="fill: #fff"/>
<path d="M53.85354,10.19482H54.709v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915h-.88867V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
<path d="M59.09377,8.437h.88867v6.26074h-.88867Z" style="fill: #fff"/>
<path d="M61.21779,12.44434a2.13346,2.13346,0,1,1,4.24756,0,2.1338,2.1338,0,1,1-4.24756,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C64.11232,13.99463,64.5508,13.42432,64.5508,12.44434Z" style="fill: #fff"/>
<path d="M66.4009,13.42432c0-.81055.60352-1.27783,1.6748-1.34424l1.21973-.07031v-.38867c0-.47559-.31445-.74414-.92187-.74414-.49609,0-.83984.18213-.93848.50049h-.86035c.09082-.77344.81836-1.26953,1.83984-1.26953,1.12891,0,1.76563.562,1.76563,1.51318v3.07666h-.85547v-.63281h-.07031a1.515,1.515,0,0,1-1.35254.707A1.36026,1.36026,0,0,1,66.4009,13.42432Zm2.89453-.38477v-.37646l-1.09961.07031c-.62012.0415-.90137.25244-.90137.64941,0,.40527.35156.64111.835.64111A1.0615,1.0615,0,0,0,69.29543,13.03955Z" style="fill: #fff"/>
<path d="M71.34816,12.44434c0-1.42285.73145-2.32422,1.86914-2.32422a1.484,1.484,0,0,1,1.38086.79h.06641V8.437h.88867v6.26074h-.85156v-.71143h-.07031a1.56284,1.56284,0,0,1-1.41406.78564C72.0718,14.772,71.34816,13.87061,71.34816,12.44434Zm.918,0c0,.95508.4502,1.52979,1.20313,1.52979.749,0,1.21191-.583,1.21191-1.52588,0-.93848-.46777-1.52979-1.21191-1.52979C72.72121,10.91846,72.26613,11.49707,72.26613,12.44434Z" style="fill: #fff"/>
<path d="M79.23,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C82.12453,13.99463,82.563,13.42432,82.563,12.44434Z" style="fill: #fff"/>
<path d="M84.66945,10.19482h.85547v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915H87.605V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
<path d="M93.51516,9.07373v1.1416h.97559v.74854h-.97559V13.2793c0,.47168.19434.67822.63672.67822a2.96657,2.96657,0,0,0,.33887-.02051v.74023a2.9155,2.9155,0,0,1-.4834.04541c-.98828,0-1.38184-.34766-1.38184-1.21582v-2.543h-.71484v-.74854h.71484V9.07373Z" style="fill: #fff"/>
<path d="M95.70461,8.437h.88086v2.48145h.07031a1.3856,1.3856,0,0,1,1.373-.80664,1.48339,1.48339,0,0,1,1.55078,1.67871v2.90723H98.69v-2.688c0-.71924-.335-1.0835-.96289-1.0835a1.05194,1.05194,0,0,0-1.13379,1.1416v2.62988h-.88867Z" style="fill: #fff"/>
<path d="M104.76125,13.48193a1.828,1.828,0,0,1-1.95117,1.30273A2.04531,2.04531,0,0,1,100.73,12.46045a2.07685,2.07685,0,0,1,2.07617-2.35254c1.25293,0,2.00879.856,2.00879,2.27V12.688h-3.17969v.0498a1.1902,1.1902,0,0,0,1.19922,1.29,1.07934,1.07934,0,0,0,1.07129-.5459Zm-3.126-1.45117h2.27441a1.08647,1.08647,0,0,0-1.1084-1.1665A1.15162,1.15162,0,0,0,101.63527,12.03076Z" style="fill: #fff"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,51 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link href="../src/index.css" rel="stylesheet"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.jpg" />
<script src="https://apis.google.com/js/platform.js" async defer></script>
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- CSS Styles-->
<title>Locaft</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

View File

@ -1,15 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -1,3 +0,0 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

130
routes/users.js Normal file
View File

@ -0,0 +1,130 @@
const router = require("express").Router();
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const auth = require("../middleware/auth");
const User = require("../schemas/User");
const config = require("config");
router.post("/register", async (req, res) => {
try {
let { username,email,phonenumber,password} = req.body;
if (!email || !password )
return res.status(400).json({ msg: "Not all fields have been entered." });
if (password.length < 5)
return res
.status(400)
.json({ msg: "The password needs to be at least 5 characters long." });
const existingUser = await User.findOne({ email: email });
if (existingUser)
return res
.status(400)
.json({ msg: "An account with this email already exists." });
if (!username) username = email;
const salt = await bcrypt.genSalt();
const passwordHash = await bcrypt.hash(password, salt);
const newUser = new User({
username,
email,
phonenumber,
password: passwordHash,
});
const savedUser = await newUser.save();
res.json(savedUser);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
// validate
if (!email || !password)
return res.status(400).json({ msg: "Not all fields have been entered." });
const user = await User.findOne({ email: email });
if (!user)
return res
.status(400)
.json({ msg: "No account with this email has been registered." });
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ msg: "Invalid credentials." });
const token = jwt.sign({ id: user._id },process.env.jwtSecret);
if(token) return res
.json({
token,
user: {
id: user._id,
username: user.username,
pricing: user.pricing
},
});
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.delete("/delete", auth, async (req, res) => {
try {
const deletedUser = await User.findByIdAndDelete(req.user);
res.json(deletedUser);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.post("/tokenIsValid", async (req, res) => {
try {
const token = req.header("x-auth-token");
if (!token) return res.json({error: message});
const verified = jwt.verify(token,process.env.jwtSecret);
if (!verified) return res.json({error: message});
const user = await User.findById(verified.id);
if (!user) return res.json({error: message});
return res.json(true);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.get("/", auth, async (req, res) => {
const user = await User.findById(req.user);
console.log(user);
res.json({
username: user.username,
id: user._id,
});
});
router.put("/update", async (req, res) => {
const { id,pricing } = req.body;
if (!id) {
return res.status(400).json({ Msg: "Not all fields have been entered." });
}
User.findByIdAndUpdate(id, { pricing: pricing }).then(() => {
User.findOne({ _id: id }).then((user) => {
res.send(user);
console.log(user)
})
})
})
;
module.exports = router;

33
schemas/User.js Normal file
View File

@ -0,0 +1,33 @@
const mongoose = require('mongoose');
const UserSchema = mongoose.Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required:true,
unique: true
},
phonenumber: {
type: Number,
required: true
},
password: {
type:String,
required:true,
minlength: 5
},
pricing: {
type:String,
enum: ['free','basic','intermediate','luxury'],
default:'free',
required:false
}
});
module.exports = User = mongoose.model('user',UserSchema);

34
server.js Normal file
View File

@ -0,0 +1,34 @@
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
require('dotenv').config()
// set up express
const app = express();
app.use(express.json());
app.use(cors());
app.get('/', (req, res) => { res.send('Hello from Express!')});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`The server has started on port: ${PORT}`));
// set up mongoose
mongoose.connect(
process.env.mongoURI,
{
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
},
(err) => {
if (err) throw err;
console.log("MongoDB connection established");
}
);
// set up routes
app.use("/users", require("./routes/users"));

View File

@ -1,77 +0,0 @@
import React, { useEffect, useState } from 'react';
import Axios from 'axios';
import HomePage from "./components/HomePage";
import PricingPlan from "./components/PricingPlan";
import LogInContainer from "./components/LogInContainer";
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import UserContext from "./context/UserContext";
import Options from "./components/Options";
import Stepper from './components/Stepper';
import NavBar from "./components/NavBar";
import FillingDetails from "./components/FillingDetails";
import Error404 from './components/Error404';
import Payment from './components/Payment'
import 'bootstrap/dist/css/bootstrap.min.css';
export default function App() {
const [userData, setUserData ] = useState({
token: undefined,
user: undefined
});
useEffect(() => {
const checkLoggedIn = async () => {
let token = localStorage.getItem("auth-token");
console.log("app js " + token);
if (token == null) {
localStorage.setItem("auth-token","");
token ="";
}
const tokenRes = await Axios.post(
"https://server-locaft.herokuapp.com/users/tokenIsValid",
null,
{headers: {"x-auth-token": token }}
);
if (tokenRes.data) {
const userRes = await Axios.get("https://server-locaft.herokuapp.com/users/",
{headers:{"x-auth-token":token},
});
setUserData({
token,
user: userRes.data,
});
}
};
checkLoggedIn();
},[])
return (
<>
<div className="App">
<BrowserRouter>
<UserContext.Provider value= {{userData, setUserData}}>
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="asdf" component={NavBar} />
<Route path="/user" component={LogInContainer} />
<Route path="/pricing" component={PricingPlan} />
<Route path="/track" component={Stepper} />
<Route path="/options" component={Options} />
<Route path="/details" component={FillingDetails} />
<Route path="/payment" component={Payment} />
<Route path="/" component={Error404} />
</Switch>
</UserContext.Provider>
</BrowserRouter>
</div>
</>
);
}

View File

@ -1,8 +0,0 @@
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@ -1,58 +0,0 @@
import React from 'react';
import styled from 'styled-components';
import Lottie from 'react-lottie';
import animationData from '../lottie/box_error';
const Body = styled.div`
@import url('https://fonts.googleapis.com/css?family=Roboto:400,100,300,500');
font-size: 100%;
line-height: 1.5;
font-family: "Roboto", sans-serif;
display:flex;
justify-content: center;
align-items: center;
`;
const Container = styled.div`
position: relative;
background-color: #66bfbf;
text-align: center;
`;
const Heading = styled.h1`
padding-top: 15%;
color: white;
font-size: 4rem;
margin: 0px;
`;
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: "xMidYMid slice"
}
};
const Error404 = () => {
return (
<Body>
<Container>
<Heading>Error </Heading>
<br />
<Lottie height={500} width={500} options={defaultOptions} />
</Container>
</Body>
);
}
export default Error404;

View File

@ -1,53 +0,0 @@
import React from "react";
import styled from 'styled-components';
export default function ErrorNotice(props) {
const ErrorNotice = styled.div`
margin: 1rem 0;
border: 1px solid #e07c7c;
border-radius: 8px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f8d6d6;
padding: 10px;
`;
const ErrorMessage = styled.div`
color: #000000;
`;
const ErrorButton = styled.a
`
color: red;
position: relative;
width: 20px;
height: 20px;
opacity: 0.3;
&:hover {
opacity: 1;
}
&:before, &:after {
position: absolute;
left: 15px;
content: ' ';
height: 19px;
width: 2px;
background-color: red;
}
&:before {
transform: rotate(45deg);
}
&:after {
transform: rotate(-45deg);
}
`;
return (
<ErrorNotice>
<ErrorMessage>{props.message}</ErrorMessage>
<ErrorButton onClick={props.clearError}></ErrorButton>
</ErrorNotice>
);
}

View File

@ -1,75 +0,0 @@
import React,{useState} from 'react';
import styled from 'styled-components';
import Footer from './Footer';
import NavBar from './NavBar';
const Selector = styled.select`
width: 25%;
`;
const Container = styled.div`
padding: 50px;
`;
const Heading = styled.h1`
color: #66bfbf !important;
`;
const FillingDetails = () => {
const [foodState, setFoodState] = useState(null);
return (
<Container>
<NavBar></NavBar>
<br></br>
<br></br>
<Heading>Details</Heading>
<br></br>
<div>
Source:&nbsp;&nbsp;
<Selector
className="custom-select"
value={foodState}
onChange={(e) => {
const selectedFood = e.target.value;
setFoodState(selectedFood);
}}
>
<option value="source1" >source12</option>
<option value="source2">source2</option>
<option value="source3">source3</option>
</Selector>
<br></br>
{foodState}
<br></br>
<br></br>
<br></br>
Destination: &nbsp;&nbsp;
<Selector
className="custom-select"
value={foodState}
onChange={(e) => {
const selectedFood = e.target.value;
setFoodState(selectedFood);
}}
>
<option value="dest1" >dest1</option>
<option value="dest2">dest2</option>
<option value="dest3">dest3</option>
</Selector>
<br></br>
{foodState}
</div>
<Footer />
</Container>
);
}
export default FillingDetails;

View File

@ -1,62 +0,0 @@
import React from 'react';
import styled from 'styled-components';
import { Facebook, Twitter, Instagram } from "@styled-icons/fa-brands";
import { Envelope } from "@styled-icons/fa-solid";
import { StyledIconBase } from '@styled-icons/styled-icon'
import {
Container
} from 'react-bootstrap';
const ContainerPadded = styled(Container)`
padding: 7% 15%;
text-align: center;
`;
const WhiteSection = styled.footer`
background: ${props => props.background || "white"};
`;
const ContainerCentered = styled.div`
display:flex;
flex-direction: row;
justify-content: center;
`;
const IconStyler = styled.div`
${StyledIconBase} {
width: ${props => props.width ? props.width : 26}px;
height: ${props => props.height ? props.height : 26};
color: ${props => props.color ? props.color : "white"};
}
margin: 20px 10px;
`;
const Footer = () => {
return (
<WhiteSection>
<ContainerPadded fluid>
<ContainerCentered>
<IconStyler color="#000" width={20} height={20}><Facebook /></IconStyler>
<IconStyler color="#000" width={20} height={20}><Twitter /></IconStyler>
<IconStyler color="#000" width={20} height={20}><Instagram /></IconStyler>
<IconStyler color="#000" width={20} height={20}><Envelope /></IconStyler >
</ContainerCentered>
<p>© Copyright 2020 Locaft</p>
<p><a href="/tc">Terms and Conditions</a></p>
<p><a href="/pp">Privacy Policy</a></p>
</ContainerPadded >
</WhiteSection >
)
}
export default Footer;

View File

@ -1,249 +0,0 @@
import React from 'react';
import NavBar from './NavBar';
import Footer from './Footer';
import { useHistory } from "react-router-dom";
import Lottie from 'react-lottie';
import animationData from '../lottie/plane_gif';
import {Container,Row,Col,Carousel, Button} from "react-bootstrap";
import styled from 'styled-components';
import { CheckCircle, Heart, AddressCard, ChartLine } from '@styled-icons/fa-solid';
import { Bullseye } from "@styled-icons/fa-solid";
import { StyledIconBase } from '@styled-icons/styled-icon'
import Sidebar from './Sidebar';
const Body = styled.div`
`;
const IconStyler = styled.div`
${StyledIconBase} {
width: ${props => props.width ? props.width : 26}px;
height: ${props => props.height ? props.height : 26};
color: ${ props => props.color ? props.color: "white"};
}
`;
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: "xMidYMid slice"
}
};
const ColoredSection = styled.section`
background-color:#66bfbf;
color: #fff;
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
`;
const WhiteSection = styled.section`
background:#fff;
`;
const PressSection = styled(ColoredSection)`
padding-bottom: 3%;
align-items:center;
`;
const PressLogo = styled.img`
width: 18%;
height: 18%;
margin: 20px 20px 50px;
`;
const RowFix = styled(Row)`
margin: 0 0px;
`;
const FeatureCol = styled(Col)`
padding: 4.5%;
`;
const ContainerPadded = styled(Container)`
padding: 5% 5%;
text-align: center;
`;
const BigHeading = styled.h1`
font-size: 5rem;
line-height: 1.5;
font-family: "Ubuntu";
color: white;
font-weight: bold;
`;
const FeatureTitle = styled.h3`
font-size: 1.5rem;
color:#8f8f8f;
align-self: center;
`;
const TestimonalTitle = styled.h2`
font-size: 3rem;
color:#fff;
line-height: 1.5;
align-content: center;
padding: 10px 50px;
font-style: italic;
`;
export default function HomePage() {
const history = useHistory();
return (
<Body>
<ColoredSection >
<ContainerPadded fluid>
<Row>
<FeatureCol lg="6">
<BigHeading>Adapt to a new place easy peasy.</BigHeading>
<Button variant="info" onClick={() => {
history.push("/user/login")
}} >Log In</Button> &nbsp;
<Button variant="info" onClick={() => history.push("/user/register")} >Sign Up</Button>
</FeatureCol>
<FeatureCol lg="6">
<Lottie options= { defaultOptions } />
</FeatureCol>
</Row>
</ContainerPadded>
</ColoredSection>
<WhiteSection id="services">
<ContainerPadded fluid>
<Row>
<FeatureCol lg="4">
<IconStyler color="#66bfbf" width={50} height={50}><CheckCircle /></IconStyler>
<br/>
<FeatureTitle>Easy to use.</FeatureTitle>
<p>Get relocated.We'll take care of everything.</p>
</FeatureCol>
<FeatureCol lg="4">
<IconStyler color="#66bfbf" width={50} height={50}><Bullseye /></IconStyler>
<br />
<FeatureTitle>Efficient</FeatureTitle>
<p>Get highest number of services for lowest cost possible.</p>
</FeatureCol>
<FeatureCol lg="4">
<IconStyler color="#66bfbf" width={50} height={50}><Heart /></IconStyler>
<br />
<FeatureTitle>Relax</FeatureTitle>
<p>Sit back , we'll do the dirty work.</p>
</FeatureCol>
</Row>
</ContainerPadded>
</WhiteSection>
<ColoredSection>
<br/>
<br/>
<Carousel>
<Carousel.Item>
<Carousel.Caption>
</Carousel.Caption>
<TestimonalTitle>"I had to shift from Bangalore to Hyderabad. Thanks to Locaft , it was easy to know about this place."</TestimonalTitle>
<p style={{'text-align':'center'}}>Nishant, Pune</p>
</Carousel.Item>
<Carousel.Item >
<Carousel.Caption>
</Carousel.Caption>
<TestimonalTitle>"Relocation took me 3 months previously , but thanks to Locaft , everything was done within 3 days."</TestimonalTitle>
<p style={{'text-align': 'center'}}>Mani, Hyderabad</p>
</Carousel.Item>
</Carousel>
</ColoredSection>
<PressSection>
<ContainerPadded fluid>
<BigHeading>Our Partners</BigHeading>
<PressLogo src="/indigo_optimized.jpg" alt="indigo-brand" />
<PressLogo src="/avasa_optmized.jpg" alt="avassa-brand" />
<PressLogo src="/vrl_optmized.jpg" alt="vrl-brand" />
</ContainerPadded>
</PressSection>
<WhiteSection id="about-us">
<ContainerPadded fluid>
<Row>
<FeatureCol lg="4">
<IconStyler color="#66bfbf" width={50} height={50}><AddressCard /></IconStyler>
<br />
<FeatureTitle>About Us</FeatureTitle>
<p>Adapting to a new place is always hard in any phase of life. We aim to make it easy. </p>
</FeatureCol>
<FeatureCol lg="4">
<IconStyler color="#66bfbf" width={50} height={50}><Bullseye /></IconStyler>
<br />
<FeatureTitle>Vision</FeatureTitle>
<p>Bringing all the basic amenities to the new place before your arrival.</p>
</FeatureCol>
<FeatureCol lg="4">
<IconStyler color="#66bfbf" width={50} height={50}><ChartLine /></IconStyler>
< br/>
<FeatureTitle>Mission</FeatureTitle>
<p>Getting adapted and familiar to the new place made easy.</p>
</FeatureCol>
</Row>
</ContainerPadded>
</WhiteSection>
<ColoredSection>
<ContainerPadded fluid>
<Row>
<FeatureCol lg="12">
<BigHeading>check us out</BigHeading>
<img width="200px" src="google-play-badge.png"></img>
&nbsp;
<img width="160px" src="apple_badge.svg" ></img>
</FeatureCol>
</Row>
</ContainerPadded>
</ColoredSection>
<Sidebar logout="{logout}" />
<NavBar />
<div id="footer">
<Footer />
</div>
</Body>
);
}

View File

@ -1,103 +0,0 @@
import React from 'react';
import styled from 'styled-components';
const Image = styled.img`
display:block;
width: inherit;
height: inherit;
border-radius: 40px;
box-shadow: none;
object-fit:cover;
`;
const Tick = styled.input.attrs(props => ({
type: "radio",
name: "radiobtn"
}))`
`;
const Hover = styled.div`
height: inherit;
width: inherit;
opacity: 0;
transition: opacity 350ms ease;
position: absolute;
`;
const Overlay = styled.div`
height: inherit;
width: inherit;
transition: black 350ms ease;
background-color: transparent;
border-radius: 40px;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
`;
const CardTitle = styled.h2`
margin-top: 10px;
margin-left: 10px;
font-family: sans-serif;
box-shadow: none;
color: #fff;
`;
const Paragraph = styled.p`
margin-top: 10px;
margin-left: 10px;
color: #fff;
`;
const Card = styled.div`
width: 200px;
height: 200px;
border-radius: 40px;
box-shadow: 4px 4px 5px 5px rgba(0,0,0,0.01), -2px -2px 5px 5px rgba(0,0,0,0.22);
cursor: pointer;
transition: 0.4s;
position: relative;
background-image: url("${props => props.img ? props.img : "vrl.jpg"}");
background-size: cover;
&:hover ${Overlay} {
background-color: rgba(0,0,0,0.5);
}
&:hover ${CardTitle}, :hover ${Paragraph}{
transform: translate3d(0,0,0);
}
&:hover ${Hover}{
opacity: 1;
}
`;
const HouseCard = (props) => {
return (
<Card img = {props.img}>
<Overlay>
<Hover>
<CardTitle>{props.title ? props.title : "asdf"}</CardTitle>
<Paragraph>{props.desc ? props.desc: "zxcv"}</Paragraph>
</Hover>
</Overlay>
</Card>
);
}
export default HouseCard;

View File

@ -1,16 +0,0 @@
import React from 'react';
const HouseDetails = (props) => {
const contin = e => {
e.preventDefault();
this.props.nextStep();
};
const back = e => {
e.preventDefault();
this.props.prevStep();
};
const {values, handleChange} = props;
}

View File

@ -1,288 +0,0 @@
import React, {useState, useContext} from 'react';
import { useHistory,BrowserRouter, Route, NavLink, Switch,withRouter } from 'react-router-dom';
import Register from './Register';
import Login from './Login';
import Footer from './Footer';
import styled, {css} from 'styled-components';
import {Button} from './miscellaneous/Styles';
import UserContext from "../context/UserContext";
import {logout} from "./NavBar"
import { GoogleLogin } from 'react-google-login';
import Axios from "axios";
import { Device} from './miscellaneous/Responsive';
const BaseApp = styled.div`
display: flex;
color: white;
height:100vh;
flex-direction: column;
@media ${Device.laptop} {
flex-direction: row;
}
`;
const AppSide = styled.div`
background-color: #66bfbf;
display: grid;
grid-template-columns: repeat(auto-fit, 300px);
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
@media ${Device.laptop} {
width: 50%;
}
`;
const AppForm = styled.div`
background-color: #ffffff;
padding: 25px 40px;
height: 100vh;
width: 100vw;
@media ${Device.laptop} {
width: 50%;
overflow:auto
}
`;
const PageSwitcherContainer = styled.div`
display: flex;
justify-content: flex-end;
margin-bottom: 10%;
`;
const BannerHeading = styled.h1`
position: relative;
text-align: center;
font-family: Ubuntu;
font-size: 5rem;
font-weight: bold;
color: #ffffff;
text-decoration: none;
text-transform: lowercase;
`;
const PlaneContainer = styled.div`
width:100px;
display:flex;
margin-bottom: 50px;
align-content: flex-start;
justify-content: flex-start;
`;
const TextContainer = styled.p`
width: 50%;
background-color: #66bfbf;
display:flex;
flex-direction: column;
justify-content: flex-end;
`;
const BannerText = styled.p`
color:${props => props.colour ? props.colour : "white"};
font-size: 1.25em;
font-style:italic;
`;
const SkyContainer = styled.div`
margin-top: 600px;
width: 100%;
background-size: 100%;
`;
const PageSwitcher = styled(NavLink)`
background-color: #4C5D72;
color: white;
padding: 10px 25px;
cursor: pointer;
font-size: .9em;
border: none;
outline: none;
display: inline-block;
text-decoration: none !important;
&.active{
background-color: #66bfbf;
color: white;
}
&:first-child {
border-top-left-radius: 25px;
border-bottom-left-radius: 25px;
}
&:last-child {
border-top-right-radius: 25px;
border-bottom-right-radius: 25px;
}
`;
const FormLink = styled(NavLink)`
color: #707C8B;
text-decoration: none !important;
display: inline-block;
font-size: 1.7em;
margin: 0 10px;
padding-bottom: 5px;
border: none;
&:first-child {
margin-left: 0;
}
&:last-child{
color: #707c8b;
}
&.active{
border-bottom: 1px solid #199087;
}
`;
const FormTitle = styled.div`
color: #000000;
font-weight: 300;
margin-bottom: 50px;
`;
const responseSuccessGoogle = (response) => {
Axios({
method: 'POST',
url: "http://localhost:5000/users/googlelogin",
data: { idToken: response.tokenId }
}).then(response => {
console.log(response);
})
}
const responseFailGoogle = (response) => {
console.log(response)
}
const LogInContainer = () => {
const { userData, setUserData } = useContext(UserContext);
const [error, setError] = useState();
const [hasLogged, setHasLogged] = useState(false);
const history = useHistory();
const responsePassGoogle = async (response) => {
try{
const idToken = response.tokenId;
console.log("id token" + idToken);
const googleres = await Axios.post(
"https://server-locaft.herokuapp.com/users/googlelogin",{
idToken: idToken
}
);
setUserData({
token: googleres.data.token,
user: googleres.data.user
});
localStorage.setItem("auth-token",googleres.data.token);
setHasLogged(true);
} catch (err) {
err.response.data.msg && setError(err.response.data.msg);
}
}
return (
<BaseApp>
<meta name="google-signin-client_id"
content={`${process.env.REACT_APP_CLIENT_ID}.apps.googleusercontent.com`} />
<AppSide>
{!hasLogged ? (
<GoogleLogin
clientId= {process.env.REACT_APP_CLIENT_ID}
buttonText="Login with Google"
onSuccess={responsePassGoogle}
onFailure={responseFailGoogle}
cookiePolicy={'single_host_origin'}
/>
): (
<React.Fragment>
<p> username: {userData.user.username}</p>
<p> email: {userData.user.email}</p>
<p> pricing: {userData.user.pricing}</p>
</React.Fragment>
) }
</AppSide>
<AppForm>
{!userData.user ? (
<BrowserRouter basename="user">
<PageSwitcherContainer>
<PageSwitcher to="/login" >Sign In</PageSwitcher>
<PageSwitcher to="/register" >Sign Up</PageSwitcher>
</PageSwitcherContainer>
<FormTitle>
<FormLink to="/login" >Sign In</FormLink> or <FormLink to="/register">Sign Up</FormLink>
</FormTitle>
<Switch>
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
</Switch>
</BrowserRouter>
) : (
<React.Fragment>
<BannerText colour="black">Log in successful.</BannerText>
<Button
type="submit"
radiuscolor="#009578"
textcolor="#009578"
hovercolor="#009578"
hovertextcolor="white"
onClick={() => { history.push("/")}}
>home</Button>
&nbsp;
<Button
type="submit"
radiuscolor="#009578"
textcolor="#009578"
hovercolor="#009578"
hovertextcolor="white"
onClick={() => {logout(setUserData); history.push("/")}}
>Logout</Button>
</React.Fragment>
)}
</AppForm>
</BaseApp>
);
}
export default withRouter(LogInContainer);

View File

@ -1,70 +0,0 @@
import React, { useState, useContext } from "react";
import UserContext from "../context/UserContext";
import Axios from "axios";
import ErrorNotice from "./ErrorNotice";
import { Link, useHistory, withRouter } from "react-router-dom";
import {Button, FormCenter, FormField, FormLabel, FormInput, FormLink } from './miscellaneous/Styles'
const Login = () => {
const [email, setEmail] = useState();
const [password, setPassword] = useState();
const [error, setError] = useState();
const { userData,setUserData } = useContext(UserContext);
const history = useHistory();
const submit = async (e) => {
e.preventDefault();
try {
const loginUser = { email, password };
const loginRes = await Axios.post(
"https://server-locaft.herokuapp.com/users/login",
loginUser
);
console.dir("login res " + loginRes.data.user);
setUserData({
token: loginRes.data.token,
user: loginRes.data.user,
});
localStorage.setItem("auth-token", loginRes.data.token);
history.push("/");
} catch (err) {
err.response.data.msg && setError(err.response.data.msg);
}
};
return (
<FormCenter>
{error && (
<ErrorNotice message={error} clearError={() => setError(undefined)} />
)}
<form className="FormFields" onSubmit={submit}>
<FormField>
<FormLabel htmlFor="email">E-Mail Address</FormLabel>
<FormInput type="email" id="email" value={ email } placeholder="enter your email" name="email" onChange={(e) => setEmail(e.target.value)} />
</FormField>
<FormField>
<FormLabel htmlFor="password">Password</FormLabel>
<FormInput type="password" id="password" value={ password } placeholder="Enter your password" name="password" onChange={(e) => setPassword(e.target.value)} />
</FormField>
<FormField>
<Button
type="submit"
radiuscolor="#009578"
textcolor="#009578"
hovercolor="#009578"
hovertextcolor="white"
>Sign In</Button> <FormLink exact to="/register" className="FormField__Link">Not a member?</FormLink>
</FormField>
</form>
</FormCenter>
);
}
export default withRouter(Login);

View File

@ -1,146 +0,0 @@
import React, { useState,useContext,useEffect } from 'react';
import { Link } from "react-router-dom";
import UserContext from "../context/UserContext";
import styled,{ css } from 'styled-components';
const Header = styled.header`
@import url('https://fonts.googleapis.com/css?family=Montserrat|Ubuntu');
background: #66bfbf;
position: fixed;
top: 0;
left: 0;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
transition: 0.6s;
padding: 5px 15px;
z-index: 100000;
font-family: Ubuntu;
${ props => props.sticky ? css`
${Header};
padding: 3px 45px;
min-height: 3vh;
opacity: 0.85;
display: fixed;
`:css``};
& .logo {
font-family: "Ubuntu";
font-size: 2rem;
font-weight: bold;
position: relative;
color: #fff;
text-decoration: none;
text-transform: lowercase;
transition: 0.6s;
}
@media (max-width: 768px) {
display:none;
}
`;
const List = styled.ul`
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
margin-bottom: 0px !important;
`;
const ListElement = styled.li`
color: #fff;
text-decoration: none;
text-transform: uppercase;
position:relative;
padding:3px 50px;
`;
const Anchor = styled.a`
color: #fff;
text-transform: uppercase;
color: inherit;
letter-spacing: 2px;
font-size: 1.2em;
padding: 3px ;
transition: 0.6s;
white-space: nowrap;
`;
const Linker = styled(Link)`
color:#fff;
text-transform: uppercase;
color: inherit;
letter-spacing: 2px;
font-size: 1.2em;
padding: 3px 0;
transition: 0.6s;
`;
export const logout = (setUserData) => {
setUserData({
token: undefined,
user: undefined,
});
localStorage.setItem("auth-token", "");
};
export default function NavBar() {
const [scrolled, setScrolled] = useState();
const { userData, setUserData } = useContext(UserContext);
const handleScroll=() => {
const offset=window.scrollY;
if(offset > 200 ){
setScrolled(true);
}
else{
setScrolled(false);
}
}
useEffect(() => {
window.addEventListener('scroll',handleScroll)
})
return (
<div className="navbar">
<Header sticky = {scrolled} >
<Anchor href="/" className="logo">locaft</Anchor>
<List>
<ListElement><Anchor href="/">Home</Anchor></ListElement>
<ListElement><Anchor href="/#about-us">About</Anchor></ListElement>
<ListElement><Anchor href="/pricing">Pricing</Anchor></ListElement>
<ListElement><Anchor href="/#footer">Contact us</Anchor></ListElement>
{userData.user ? (
<React.Fragment>
<ListElement><Linker onClick={() => logout(setUserData)}>{userData.user.username}</Linker></ListElement>
</React.Fragment>
) : (
<React.Fragment>
<ListElement><Linker to="/user/register">Register</Linker></ListElement>
<ListElement><Linker to="/user/login">login</Linker></ListElement>
</React.Fragment>
)}
</List>
</Header>
</div>
)
}

View File

@ -1,111 +0,0 @@
import React from 'react';
import '../options.css';
import Card from './HouseCard';
import Footer from "./Footer";
import styled from 'styled-components';
const CardList = styled.div`
display: grid;
position: relative;
margin: 15px;
grid-template-rows: repeat(auto-fill,minmax(200px,1fr));
grid-template-columns: repeat(auto-fill,minmax(200px,1fr));
grid-gap: 30px;
align-items: center;
justify-items: center;
`;
export default function Options() {
document.addEventListener('DOMContentLoaded', () => {
const previousBtn = document.getElementById('previousBtn');
const nextBtn = document.getElementById('nextBtn');
const finishBtn = document.getElementById('finishBtn');
const content = document.getElementById('content');
const bullets = [...document.querySelectorAll('.bullet')];
const MAX_STEPS = 4;
let currentStep = 1;
nextBtn.addEventListener('click', () => {
bullets[currentStep - 1].classList.add('completed');
currentStep += 1;
previousBtn.disabled = false;
if (currentStep === MAX_STEPS) {
nextBtn.disabled = true;
finishBtn.disabled = false;
}
content.innerText = `Step Number ${currentStep}`;
});
previousBtn.addEventListener('click', () => {
bullets[currentStep - 2].classList.remove('completed');
currentStep -= 1;
nextBtn.disabled = false;
finishBtn.disabled = true;
if (currentStep === 1) {
previousBtn.disabled = true;
}
content.innerText = `Step Number ${currentStep}`;
});
finishBtn.addEventListener('click', () => {
window.location.reload();
});
})
return (
<div className="container">
<div id="stepProgressBar">
<div className="step">
<p className="step-text">About</p>
<div className="bullet">1</div>
</div>
<div className="step">
<p className="step-text">Contact</p>
<div className="bullet">2</div>
</div>
<div className="step">
<p className="step-text">Step 3</p>
<div className="bullet">3</div>
</div>
<div className="step">
<p className="step-text">Step 4</p>
<div className="bullet ">4</div>
</div>
</div>
<p id="content" className="text-center">Step Number 1</p>
<div id="main">
<button id="previousBtn" >Previous</button>
<button id="nextBtn">Next</button>
<button id="finishBtn" >Finish</button>
</div>
<CardList>
<Card img="skyscraper.png" title="cardtitle" desc="description"/>
<Card img="skyscraper.png"/>
<Card img="skyscraper.png"/>
<Card img="skyscraper.png"/>
<Card img="indigo.jpg"/>
<Card img="locaft.png"/>
<Card img="skyscraper.png"/>
<Card img="skyscraper.png"/>
<Card img="skyscraper.png"/>
</CardList>
<Footer />
</div>
)
}

View File

@ -1,21 +0,0 @@
import React,{ useContext } from 'react';
import NavBar from './NavBar';
import Footer from './Footer';
import UserContext from '../context/UserContext'
const Payment = (props) => {
const { userData, setUserData } = useContext(UserContext);
return (
<div>
<h1>{userData.user.username}</h1>
<h2>{props.pricing}</h2>
</div>
);
}
export default Payment;

View File

@ -1,304 +0,0 @@
import React, { useState,useContext } from 'react';
import NavBar from './NavBar';
import Footer from './Footer';
import styled,{css} from 'styled-components';
import UserContext from "../context/UserContext";
import { useHistory } from "react-router-dom";
import Axios from 'axios';
import { Button } from './miscellaneous/Styles';
import { Device} from './miscellaneous/Responsive';
const PricingPlanContainer = styled.div`
display:flex;
align-items: center;
justify-content: center;
padding: 10px;
flex-direction: column;
@media ${Device.laptop} {
flex-direction: row;
}
`;
const Radio = styled.input`
display:none;
`;
const Label = styled.label`
display: relative;
cursor:pointer;
`;
const Pricing = styled.section`
background: white;
border-radius: 25px;
box-shadow: 0 0 5px rgba(0,0,0,0.2);
overflow: hidden;
font-family: sans-serif;
font-size: 16px;
line-height: 1.5;
color: #555555;
margin: 15px;
&:hover {
cursor: pointer;
box-shadow: 0 0 15px rgba(0,0,0,0.4);
transform: scale(1.05);
}
${props => props.pricing_id === props.pricing_plan ? css`
box-shadow: 0 0 15px rgba(0,0,0,0.4);
transform: scale(1.05);
`:css``};
`;
const Text = styled.p`
font-size: 0.9em;
text-align: center;
margin: 0 0 10px 0;
`;
const Currency = styled.p`
margin: 0;
text-align: center;
font-size: 2em;
color:#000000;
`;
const Title = styled.h1`
font-size:1.5em;
font-weight: 400;
`;
const Header = styled.div`
padding:25px;
background: #009578;
color: #ffffff;
`;
const Summary = styled.h2`
font-size: 1em;
font-weight: 300;
`;
const SpecialText = styled.div`
padding: 10px;
text-align: center;
font-weight: bold;
color: #ffffff;
background: #007c64;
box-shadow: 0 0 10px rgba(0,0,0,0.2) inset;
&, ${Title}{
margin: 0;
text-align: center;
font-family: sans-serif;
}
`;
const Description = styled.div`
display:block;
padding: 25px;
`;
const List = styled.ul`
padding: 0;
margin: 0;
text-align: left;
`;
const Feature = styled.li`
margin: 0 0 25px 0;
padding-left: 25px;
position: relative;
font-size: 0.9 em;
&:not(:last-child) {
margin-bottom: 2em;
}
&::before {
content: "✓ ";
color: green;
}
`;
const Actions = styled.div`
padding: 25px;
border-top: 1px solid #eeeeee;
display: flex;
flex-direction: column;
`;
const Heading = styled.h1`
color: #309975;
margin-left: 20px;
margin-top: 100px;
font-weight: bold;
`;
const PricingPlan = () => {
const { userData, setUserData } = useContext(UserContext);
const [ purchased, setPurchased ] = useState(false);
const [ pricing, setPricing ] = useState();
const history = useHistory();
const submit = async (props) => {
props.preventDefault();
try {
const id = userData.user.id;
console.log("Id " + id)
const pricingRes = await Axios.put(
"https://server-locaft.herokuapp.com/users/update", {
id,
pricing
}
);
} catch (err) {
console.log(err);
}
}
return (
<div className="body">
<NavBar />
{ !purchased ? (
<React.Fragment>
<Heading>Pricing Plan</Heading>
<PricingPlanContainer onChange={event => setPricing(event.target.value)}>
<Pricing pricing_plan={pricing} pricing_id="basic">
<Radio type ="radio" value="basic" name="pricing" id = "basic"/>
<Label for="basic">
<Header>
<Title>Basic Package</Title>
<Summary>For those getting started</Summary>
</Header>
<Description>
<List>
<Feature>Feature #1</Feature>
<Feature>Feature #2</Feature>
<Feature>Feature #3</Feature>
<Feature>Feature #4</Feature>
</List>
</Description>
<Actions>
<Currency>$10</Currency>
<Text>per month</Text>
<Text>Minimum sped over 12 months</Text>
</Actions>
</Label>
</Pricing>
<Pricing pricing_plan={pricing} pricing_id="intermediate">
<Radio type="radio" value="intermediate" name="pricing" id="intermediate" />
<Label for="intermediate" >
<SpecialText>Recommended</SpecialText>
<Header>
<Title>Intermediate Package</Title>
<Summary>For those getting started</Summary>
</Header>
<Description>
<List>
<Feature>Feature #1</Feature>
<Feature>Feature #2</Feature>
<Feature>Feature #3</Feature>
<Feature>Feature #4</Feature>
</List>
</Description>
<Actions>
<Currency>$50</Currency>
<Text>per month</Text>
<Text>Minimum spend over 12 months</Text>
</Actions>
</Label>
</Pricing>
<Pricing pricing_plan={pricing} pricing_id="luxury">
<Radio type="radio" value="luxury" name="pricing" id="luxury" />
<Label for="luxury">
<Header>
<Title>Luxury Package</Title>
<Summary>For those getting started</Summary>
</Header>
<Description>
<List>
<Feature>Feature #1</Feature>
<Feature>Feature #2</Feature>
<Feature>Feature #3</Feature>
<Feature>Feature #4</Feature>
</List>
</Description>
<Actions>
<Currency>$100</Currency>
<Text>per month</Text>
<Text>Minimum spend over 12 months</Text>
</Actions>
</Label>
</Pricing>
</PricingPlanContainer>
<PricingPlanContainer>
<Button
radiuscolor="#009578"
textcolor="#009578"
hovercolor="#009578"
hovertextcolor="white"
onClick={() => setPurchased(true)}
>Purchase</Button>
</PricingPlanContainer>
</React.Fragment>
): (
<React.Fragment>
<PricingPlanContainer styles = "{'flex-direction':'column'}">
<Heading>user name: {userData.user.username}</Heading>
<Heading>Plan selected : {pricing}</Heading>
<Button onClick={submit}>Confirm and Pay</Button>
</PricingPlanContainer>
</React.Fragment>
)
}
<Footer />
</div>
)
}
export default PricingPlan;

View File

@ -1,67 +0,0 @@
import React from "react";
import styled from "styled-components";
const RadioWrapper = styled.div`
`;
const Mark = styled.span`
position: relative;
border: 1px solid #777777;
width: 14px;
height: 14px;
left: 0;
border-radius: 50%;
margin-right: 5px;
vertical-align: middle;
&::after {
content: "";
display: block;
width: 0;
height: 0;
border-radius: 50%;
background-color: #03a9f4;
opacity: 0;
left: 50%;
top: 50%;
position: absolute;
transition: all 110ms;
}
`;
const Input = styled.input`
position: absolute;
visibility: hidden;
display: none;
&:checked + ${Mark} {
&::after {
width: 10px;
height: 10px;
opacity: 1;
left: 12%;
top: 12%;
}
}
`;
const Label = styled.label`
cursor: pointer;
position: relative;
${props =>
props.disabled &&
`
cursor: not-allowed;
opacity: 0.4;
`}
`;
const Radio = ({ name, children }) => (
<RadioWrapper>
<Label>
<Input name={name} type="radio" />
<Mark />
{children}
</Label>
</RadioWrapper>
);
export default Radio;

View File

@ -1,148 +0,0 @@
import React, { useState, useContext } from "react";
import { useHistory, withRouter } from "react-router-dom";
import UserContext from "../context/UserContext";
import Axios from "axios";
import { Link } from "react-router-dom";
import ErrorNotice from "./ErrorNotice";
import styled from 'styled-components';
import {Button, FormCenter, FormField, FormLabel, FormInput, FormLink } from './miscellaneous/Styles'
const CheckBoxLabel = styled.label`
color: #646F7D;
font-size: .9em;
`;
const CheckBox = styled.input`
position: relative;
top: 1.5px;
`;
const TermsLink = styled.a`
color: #646F7D;
border-bottom: 1px solid #199087;
text-decoration: none;
display: inline-block;
padding-bottom: 2px;
margin-left: 5px;
`;
const Register = () => {
const [email, setEmail] = useState();
const [password, setPassword] = useState();
const [phonenumber, setPhonenumber] = useState();
const [username, setUsername] = useState();
const [error, setError] = useState();
const [contains8C, setContains8C] = useState(false);
const { setUserData } = useContext(UserContext);
const history = useHistory();
const submit = async (e) => {
e.preventDefault();
try {
const newUser = { username,email,phonenumber,password};
const isEmpty = !Object.values(newUser).some(x => (x !== null && x !== ''));
console.log("isempty: " + isEmpty )
if(isEmpty){
setError("Not all Fields are entered")
return;
}
await Axios.post("https://server-locaft.herokuapp.com/users/register", newUser);
const loginRes = await Axios.post("https://server-locaft.herokuapp.com/users/login", {
email,
password,
});
setUserData({
token: loginRes.data.token,
user: loginRes.data.user,
});
localStorage.setItem("auth-token", loginRes.data.token);
history.push("/");
} catch (err) {
return err.response.data.msg && setError(err.response.data.msg);
}
};
const validatePassword = () => {
if(password.length >= 8) {
setContains8C(true)
setError(null)
}
else { setContains8C(false); setError("The Password needs to be atleast 8 characters") };
}
return (
<FormCenter>
{error && (
<ErrorNotice message={error} clearError={() => setError(undefined)} />
)}
<form className="FormFields" onSubmit={submit}>
<FormField>
<FormLabel htmlFor="name">UserName</FormLabel>
<FormInput
type="text"
id="name"
placeholder="Enter your full name"
onChange={(e) => setUsername(e.target.value)}
/>
</FormField>
<FormField>
<FormLabel htmlFor="password">Password</FormLabel>
<FormInput
type="password"
id="password"
className="FormField__Input"
placeholder="Enter your password"
onChange={(e) => setPassword(e.target.value)}
onKeyUp={validatePassword}
/>
</FormField>
<FormField>
<FormLabel htmlFor="email">E-Mail Address</FormLabel>
<FormInput
type="email"
id="email"
className="FormField__Input"
placeholder="Enter your email"
onChange= { (e) => setEmail(e.target.value)}
/>
</FormField>
<FormField>
<FormLabel htmlFor="phone">Phone number</FormLabel>
<FormInput
type="number"
id="phonenumber"
className="FormField__Input"
placeholder="Enter your Phone no. (+91)"
onChange={(e) => setPhonenumber(parseInt(e.target.value, 10))}
/>
</FormField>
<FormField>
<CheckBoxLabel>
<CheckBox type="checkbox" name="hasAgreed" /> I agree all statements in <a href="/" className="FormField__TermsLink">terms of service</a>
</CheckBoxLabel>
</FormField>
<FormField>
<Button
type="submit"
radiuscolor="#009578"
textcolor="#009578"
hovercolor="#009578"
hovertextcolor="white"
>Sign Up</Button>
<FormLink to="/login">already a member?</FormLink>
</FormField>
</form>
</FormCenter>
);
}
export default withRouter( Register );

View File

@ -1,179 +0,0 @@
import React, {useState, useContext} from 'react';
import { Link } from 'react-router-dom'
import styled from 'styled-components';
import UserContext from '../context/UserContext';
const StyledMenu = styled.nav`
display: flex;
flex-direction: column;
position:fixed !important;
justify-content: center;
background: #EFFFFA;
transform: ${({ open }) => open ? 'translateX(0)' : 'translateX(-100%)'};
height: 100vh;
text-align: left;
padding: 2rem;
top: 0;
left: 0;
transition: transform 0.3s ease-in-out;
@media (max-width: 576px) {
width: 100%;
}
a {
font-size: 2rem;
text-transform: uppercase;
padding: 2rem 0;
font-weight: bold;
letter-spacing: 0.5rem;
color: #0D0C1D;
text-decoration: none;
transition: color 0.3s linear;
@media (max-width: 576px) {
font-size: 1.5rem;
text-align: center;
}
&:hover {
color: #343078;
}
}
`
const Menu = ({open, setOpen}) => {
const { userData, setUserData } = useContext(UserContext);
return (
<StyledMenu open={open} >
<a href="/#about-us"onClick={() => setOpen(false)}>
<span role="img" aria-label="about us">💁🏻</span>
About us
</a>
<a href="/pricing">
<span role="img" aria-label="pricing">💸</span>
Pricing
</a>
<a href="/#footer"onClick={() => setOpen(false)}>
<span role="img" aria-label="contact us">📩</span>
Contact
</a>
{userData.user ? (
<Link >
<span role="img" aria-label="{userData.user.username}">📩</span>
{userData.user.username}
</Link>
):(
<React.Fragment>
<a href="/user/register">
<span role="img" aria-label="Register">📩</span>
Register
</a>
<a href="/user/login">
<span role="img" aria-label="Login">📩</span>
Login
</a>
</React.Fragment>
)
}
</StyledMenu>
)
}
const StyledBurger = styled.button`
position: fixed;
top: 5%;
left: 2rem;
display: flex;
flex-direction: column;
justify-content: space-around;
width: 2rem;
height: 2rem;
background: transparent;
border: none;
cursor: pointer;
padding: 0;
z-index: 10;
&:focus {
outline: none;
}
&:hover{
background: transparent;
}
div {
width: 2rem;
height: 0.25rem;
background: ${({ open }) => open ? '#0D0C1D' : '#EFFFFA'};
border-radius: 10px;
transition: all 0.3s linear;
position: relative;
transform-origin: 1px;
:first-child {
transform: ${({ open }) => open ? 'rotate(45deg)' : 'rotate(0)'};
}
:nth-child(2) {
opacity: ${({ open }) => open ? '0' : '1'};
transform: ${({ open }) => open ? 'translateX(20px)' : 'translateX(0)'};
}
:nth-child(3) {
transform: ${({ open }) => open ? 'rotate(-45deg)' : 'rotate(0)'};
}
}
@media(min-width:768px){
display:none;
}
`
const Burger = ({ open, setOpen }) => {
return (
<StyledBurger open={open} onClick={() => setOpen(!open)}>
<div />
<div />
<div />
</StyledBurger>
)
}
const Sidebar = (props) => {
const [open, setOpen] = useState(false);
const node = React.useRef();
return (
<div>
<div ref={node}>
<Burger open={open} setOpen={setOpen} />
<Menu open={open} setOpen={setOpen} logout={props.logout} />
</div>
</div>
)
}
const useOnClickOutside = (ref, handler) => {
React.useEffect(() => {
const listener = event => {
if (!ref.current || ref.current.contains(event.target)) {
return;
}
handler(event);
};
document.addEventListener('mousedown', listener);
return () => {
document.removeEventListener('mousedown', listener);
};
},
[ref, handler],
);
};
export default Sidebar;

View File

@ -1,70 +0,0 @@
import React from 'react';
import Footer from './Footer';
import '../stepper.css';
import NavBar from './NavBar';
export default function Stepper() {
document.addEventListener('DOMContentLoaded', () => {
var list = document.getElementById('progress'),
next = document.getElementById('next'),
clear = document.getElementById('clear'),
children = list.children,
completed = 0;
// activating a node button
next.addEventListener('click', function() {
// count the number of completed nodes.
completed = (completed === 0) ? 1 : completed + 2;
if (completed > children.length) return;
// for each node that is completed, reflect the status
// and show a green color!
for (var i = 0; i < completed; i++) {
children[i].children[0].classList.remove('grey');
children[i].children[0].classList.add('green');
// if this child is a node and not divider,
// make it shine a little more
if (i % 2 === 0) {
children[i].children[0].classList.add('activated');
}
}
}, false);
// clear the activated state of the markers
clear.addEventListener('click', function() {
for (var i = 0; i < children.length; i++) {
children[i].children[0].classList.remove('green');
children[i].children[0].classList.remove('activated');
children[i].children[0].classList.add('grey');
}
completed = 0;
}, false);
});
return (
<div className="container">
< NavBar />
<h1 className ="relocheading">Relocation Status</h1>
<br />
<br />
<br />
<ul id="progress">
<li className="ele"><div className="node grey"></div><p>Transport tickets confirmed</p></li>
<li className="ele" ><div className="divider grey"></div></li>
<li className="ele" ><div className="node grey"></div><p>Packers & movers due to come in a day</p></li>
<li className="ele"><div className="divider grey"></div></li>
<li className="ele"><div className="node grey"></div><p>school admission being confirmed</p></li>
<li className = "ele"><div className="divider grey"></div></li>
<li className = "ele"><div className="node grey"></div><p>House is empty</p></li>
</ul>
<input type="button" value="Next" id="next" />
<input type="button" value="Clear" id="clear" />
<Footer />
</div>
)
}

View File

@ -1,103 +0,0 @@
import React from 'react';
import Footer from './Footer';
import '../tracking.css';
export default function Tracking() {
document.addEventListener('DOMContentLoaded', () => {
const previousBtn = document.getElementById('previousBtn');
const nextBtn = document.getElementById('nextBtn');
const finishBtn = document.getElementById('finishBtn');
const content = document.getElementById('content');
const nodes = [...document.querySelectorAll('.node')];
const dividers = [...document.querySelectorAll('.divider')];
const MAX_STEPS = 4;
let currentStep = 1;
if (nextBtn) {
nextBtn.addEventListener('click', () => {
nodes[currentStep - 1].classList.add('completed');
currentStep += 1;
previousBtn.disabled = false;
if (currentStep === MAX_STEPS) {
nextBtn.disabled = true;
finishBtn.disabled = false;
}
content.innerText = `Step Number ${currentStep}`;
dividers[currentStep -1 ].classList.add('completed');
});
}
if (previousBtn) {
previousBtn.addEventListener('click', () => {
nodes[currentStep - 2].classList.remove('completed');
currentStep -= 1;
nextBtn.disabled = false;
finishBtn.disabled = true;
if (currentStep === 1) {
previousBtn.disabled = true;
}
content.innerText = `Step Number ${currentStep}`;
});
}
if (finishBtn) {
finishBtn.addEventListener('click', () => {
window.location.reload();
});
}
})
return (
<div class="wrapper">
<ul class="StepProgressBar">
<li class="step">
<p class="step-text">
</p>
<div class="node">
1
</div>
</li>
<li><div class="divider"></div></li>
<li class="step">
<p class="step-text">
</p>
<div class="node">
2
</div>
</li>
<li><div class="divider"></div></li>
<li class="step">
<p class="step-text">
</p>
<div class="node">
3
</div>
</li>
<li><div class="divider"></div></li>
<li class="step">
<p class="step-text">
</p>
<div class="node">
4
</div>
</li>
<li><div class="divider"></div></li>
</ul>
<div class="main">
<p id="content" class="text-center">Step Number 1</p>
<button id="previousBtn" >Previous</button>
<button id="nextBtn">Next</button>
<button id="finishBtn" >Finish</button>
</div>
<Footer />
</div>
)
}

View File

@ -1,25 +0,0 @@
import {Modal, Button} from 'react-bootstrap';
import React, {useState} from 'react';
export const CustomModal = (props) => {
const handleClose = () => props.setShow(false);
const handleShow = () => props.setShow(true);
return (
<>
<Modal show={props.show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>{props.title}</Modal.Title>
</Modal.Header>
<Modal.Body>{props.desc}</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Log In
</Button>
</Modal.Footer>
</Modal>
</>
);
}

View File

@ -1,19 +0,0 @@
export const size = {
mobileS: '320px',
mobileM: '375px',
mobileL: '425px',
tablet: '768px',
laptop: '1024px',
laptopL: '1440px',
desktop: '2560px'
}
export const Device = {
mobileS: `(min-width: ${size.mobileS})`,
mobileM: `(min-width: ${size.mobileM})`,
mobileL: `(min-width: ${size.mobileL})`,
tablet: `(min-width: ${size.tablet})`,
laptop: `(min-width: ${size.laptop})`,
laptopL: `(min-width: ${size.laptopL})`,
desktop: `(min-width: ${size.desktop})`,
desktopL: `(min-width: ${size.desktop})`
};

View File

@ -1,72 +0,0 @@
import styled from 'styled-components'
import { Link } from 'react-router-dom'
const FormCenter = styled.div`
margin-bottom: 100px;
`;
const FormField = styled.div`
margin-bottom: 40px;
`;
const FormLabel = styled.div`
display: block;
text-transform: uppercase;
font-size: 1.25em;
color: #4C5D72;
text-align: start;
`;
const FormInput = styled.input`
width: 85%;
background-color: transparent;
border: none;
color: #4C5D72;
outline: none;
border-bottom: 1px solid #445366;
font-size: .9em;
font-weight: 300;
padding-bottom: 10px;
margin-top: 10px;
&:placeholder {
color: #616E7F;
}
`;
const FormLink = styled(Link)`
color: #66707D;
text-decoration: none;
display: inline-block;
padding-bottom: 5px;
margin-left: 12px;
`;
const Button = styled.button`
display: inline-block;
margin: 15px auto;
padding: 8px 20px;
color: ${props => props.textcolor ? props.textcolor : "black"} !important;
background: ${props => props.displaycolor ? props.displaycolor : "white"} ;
border-radius: ${props => props.radius ? props.radius: "5"}px;
border: 1px solid;
border-color: ${props => props.radiuscolor ? props.radiuscolor : "black"};
text-transform: uppercase;
letter-spacing: 0.02em;
font-weight: bold;
text-align: center;
cursor: pointer;
&:hover {
background: ${props => props.hovercolor ? props.hovercolor : "white"} ;
color: ${props => props.hovertextcolor ? props.hovertextcolor : "black"}!important;
}
`;
export { Button, FormCenter, FormField, FormLabel, FormInput, FormLink };

View File

@ -1,3 +0,0 @@
import { createContext } from "react";
export default createContext();

View File

@ -1,17 +0,0 @@
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700');
@import url('https://fonts.googleapis.com/css?family=Montserrat|Ubuntu');
* {
box-sizing: border-box;
font-family: "Roboto", sans-serif;
overflow-x: hidden;
}
body {
margin: 0;
padding: 0;
}
.mr-20 {
margin-right: 20px !important;
}

View File

@ -1,7 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />,document.getElementById('root'));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,89 +0,0 @@
#stepProgressBar {
display: flex;
justify-content: space-between;
align-items: flex-end;
width: 300px;
margin: 0 auto;
margin-bottom: 40px;
}
#main {
display:flex;
justify-content: center;
align-items: center;
}
.step {
text-align: center;
}
.step-text {
margin-bottom: 10px;
color: #28a745;
}
.bullet {
border: 1px solid #28a745;
height: 20px;
width: 20px;
border-radius: 100%;
color: #28a745;
display: inline-block;
position: relative;
transition: background-color 500ms;
line-height:20px;
}
.bullet.completed {
color: white;
background-color: #28a745;
}
.bullet.completed::after {
content: '';
position: absolute;
right: -60px;
bottom: 10px;
height: 1px;
width: 54px;
background-color: #28a745;
}
/* Base styles and helper stuff */
.hidden {
display: none;
}
button {
padding: 5px 10px;
border: 1px solid black;
transition: 250ms background-color;
}
button:hover {
cursor: pointer;
background-color: black;
color: white;
}
button:disabled:hover {
opacity: 0.6;
cursor: not-allowed;
}
.text-center {
text-align: center;
}
.container {
max-width: 400px;
margin: 0 auto;
margin-top: 20px;
padding: 40px;
}

View File

@ -1,13 +0,0 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@ -1,5 +0,0 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

View File

@ -1,60 +0,0 @@
*, *:after, *:before { margin:0; padding:0; }
body {
font-family: Helvetica, sans-serif;
}
input[type="button"] {
margin-top: 20px;
}
.container{
margin-left:0px;
max-width: 100vw;
}
.relocheading{
font-family: Ubuntu;
text-align: left;
color: #66bfbf !important;
margin-top: 0px;
}
ul{
text-align: left;
}
.node {
height: 12px;
width: 12px;
border-radius: 100%;
display:inline-block;
transition: all 1000ms ease;
}
.activated {
box-shadow: 0px 0px 0px 0px rgba(194, 255, 194, 0.8);
}
.divider {
height: 86px;
width: 2px;
margin-left: 4px;
transition: all 800ms ease;
}
p {
margin-bottom: 0rem;
}
li p {
display:inline-block;
margin-left: 25px;
}
li {
list-style: none;
line-height: 1px;
}
.blue { background-color: rgba(82, 165, 255, 1); }
.green{ background-color: rgba(92, 184, 92, 1) }
.red { background-color: rgba(255, 148, 148, 1); }
.grey { background-color: rgba(201, 201, 201, 1); }

View File

@ -1,53 +0,0 @@
*, *:after, *:before { margin:0; padding:0; }
.wrapper{
max-width: 400px;
margin: 0 auto;
margin-top: 20px;
padding: 40px;
}
.stepProgressBar {
display: flex;
justify-content: space-between;
align-items: flex-start;
width: 300px;
margin: 0 auto;
margin-bottom: 40px;
}
li{
list-style-type: none;
}
.node {
border: 1px solid #28a745;
height: 20px;
width: 20px;
border-radius: 100%;
color: #28a745;
display: inline-block;
position: relative;
transition: background-color 500ms;
line-height:20px;
}
.node.completed {
content: "";
color: white;
background-color: #28a745;
}
.node.completed::after {
content: "";
position: absolute;
height: 1px;
width: 54px;
background-color: #28a745;
}
.divider.completed::after{
list-style-type: none;
background-color: grey;
position: relative;
height: 80px;
width: 2px;
margin-left: 134px;
transition: all 800ms ease;
}