Showing
10 changed files
with
208 additions
and
247 deletions
... | @@ -12,8 +12,8 @@ | ... | @@ -12,8 +12,8 @@ |
12 | <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> | 12 | <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> |
13 | <title>Weather Chatbot</title> | 13 | <title>Weather Chatbot</title> |
14 | </head> | 14 | </head> |
15 | - <body> | 15 | + <body style="width: 100vw"> |
16 | <noscript>You need to enable JavaScript to run this app.</noscript> | 16 | <noscript>You need to enable JavaScript to run this app.</noscript> |
17 | - <div id="root"></div> | 17 | + <div id="root" style="width: 100vw; margin: 0; padding: 0"></div> |
18 | </body> | 18 | </body> |
19 | </html> | 19 | </html> | ... | ... |
... | @@ -8,11 +8,13 @@ import Topbar from "./components/Topbar"; | ... | @@ -8,11 +8,13 @@ import Topbar from "./components/Topbar"; |
8 | 8 | ||
9 | function App() { | 9 | function App() { |
10 | const token = sessionStorage.getItem("user-token"); | 10 | const token = sessionStorage.getItem("user-token"); |
11 | + const [visited, setVisited] = useState(0); | ||
11 | const [weather, setWeather] = useState(); | 12 | const [weather, setWeather] = useState(); |
12 | const [forecast, setForecast] = useState(); | 13 | const [forecast, setForecast] = useState(); |
13 | const [air, setAir] = useState(); | 14 | const [air, setAir] = useState(); |
14 | 15 | ||
15 | const handleData = async (e) => { | 16 | const handleData = async (e) => { |
17 | + setVisited(1); | ||
16 | setWeather(null); | 18 | setWeather(null); |
17 | setForecast(null); | 19 | setForecast(null); |
18 | setAir(null); | 20 | setAir(null); |
... | @@ -36,85 +38,95 @@ function App() { | ... | @@ -36,85 +38,95 @@ function App() { |
36 | return ( | 38 | return ( |
37 | <div> | 39 | <div> |
38 | <Topbar /> | 40 | <Topbar /> |
39 | - <div className="weather-buttons"> | 41 | + <div className="mainBox"> |
40 | - <b>Types : </b> | 42 | + <div className="weather-buttons"> |
41 | - <button id="weather" onClick={(e) => handleData(e)}> | 43 | + <b>Types {"-> "} </b> |
42 | - Weather | 44 | + <button id="weather" onClick={(e) => handleData(e)}> |
43 | - </button> | 45 | + Weather |
44 | - <button id="forecast" onClick={(e) => handleData(e)}> | 46 | + </button> |
45 | - Forecast | 47 | + <button id="forecast" onClick={(e) => handleData(e)}> |
46 | - </button> | 48 | + Forecast |
47 | - <button id="air" onClick={(e) => handleData(e)}> | 49 | + </button> |
48 | - Air Pollution | 50 | + <button id="air" onClick={(e) => handleData(e)}> |
49 | - </button> | 51 | + Air Pollution |
50 | - </div> | 52 | + </button> |
53 | + </div> | ||
51 | 54 | ||
52 | - <hr></hr> | 55 | + <hr></hr> |
53 | 56 | ||
54 | - {!weather ? ( | 57 | + {!visited && !weather && !forecast && !air ? ( |
55 | - "" | 58 | + <h2>Click a button for weather service!</h2> |
56 | - ) : ( | 59 | + ) : ( |
57 | - <div> | 60 | + "" |
58 | - <h2> | 61 | + )} |
59 | - {weather.meta.city} ({weather.meta.country}){" "} | ||
60 | - <small>UTC {weather.meta.timezone}</small> | ||
61 | - </h2> | ||
62 | - <h3>* {weather.description} *</h3> | ||
63 | - <p> | ||
64 | - 🌡 : {weather.temp.realCelcius} ℃ / feels like{" "} | ||
65 | - {weather.temp.feelCelcius} C | ||
66 | - </p> | ||
67 | - <p>🌬 : {weather.types.wind} m/s</p> | ||
68 | - <p>☁️ : {weather.types.clouds} %</p> | ||
69 | - <p>{weather.rain ? "☔️ : Yes" : "☔️ : No"}</p> | ||
70 | - <p>{weather.snow ? "❄️ : Yes" : "❄️ : No"}</p> | ||
71 | - </div> | ||
72 | - )} | ||
73 | 62 | ||
74 | - {!forecast ? ( | 63 | + {visited && !weather && !forecast && !air ? <h2>Loading...</h2> : ""} |
75 | - "" | ||
76 | - ) : ( | ||
77 | - <div> | ||
78 | - <h2> | ||
79 | - {forecast.meta.city} ({forecast.meta.country}){" "} | ||
80 | - <small>UTC {forecast.meta.timezone}</small> | ||
81 | - </h2> | ||
82 | 64 | ||
83 | - {forecast.forecast.map((item, index) => ( | 65 | + {!weather ? ( |
84 | - <div key={index} className="forecastItemBox"> | 66 | + "" |
85 | - <h3> | 67 | + ) : ( |
86 | - {item.description} <small>{item.dateTime}</small> | 68 | + <div> |
87 | - </h3> | 69 | + <h2> |
88 | - <p> | 70 | + {weather.meta.city} ({weather.meta.country}){" "} |
89 | - Temperature : {item.temp.realCelcius} ℃ / feels like{" "} | 71 | + <small>UTC {weather.meta.timezone}</small> |
90 | - {item.temp.feelCelcius} ℃ | 72 | + </h2> |
91 | - </p> | 73 | + <h3>* {weather.description} *</h3> |
92 | - <p>Wind : {item.types.wind} m/s</p> | 74 | + <p> |
93 | - <p>Cloud : {item.types.clouds} %</p> | 75 | + 🌡 : {weather.temp.realCelcius} ℃ / feels like{" "} |
94 | - </div> | 76 | + {weather.temp.feelCelcius} C |
95 | - ))} | 77 | + </p> |
96 | - </div> | 78 | + <p>🌬 : {weather.types.wind} m/s</p> |
97 | - )} | 79 | + <p>☁️ : {weather.types.clouds} %</p> |
80 | + <p>{weather.rain ? "☔️ : Yes" : "☔️ : No"}</p> | ||
81 | + <p>{weather.snow ? "❄️ : Yes" : "❄️ : No"}</p> | ||
82 | + </div> | ||
83 | + )} | ||
98 | 84 | ||
99 | - {!air ? ( | 85 | + {!forecast ? ( |
100 | - "" | 86 | + "" |
101 | - ) : ( | 87 | + ) : ( |
102 | - <div> | 88 | + <div> |
103 | - <h2> | 89 | + <h2> |
104 | - {air.meta.state ? air.meta.state : ""} {air.meta.country} | 90 | + {forecast.meta.city} ({forecast.meta.country}){" "} |
105 | - </h2> | 91 | + <small>UTC {forecast.meta.timezone}</small> |
106 | - <p>CO : {air.airData.co} μg/m3</p> | 92 | + </h2> |
107 | - <p>NH3 : {air.airData.nh3} μg/m3</p> | 93 | + |
108 | - <p>NO : {air.airData.no} μg/m3</p> | 94 | + {forecast.forecast.map((item, index) => ( |
109 | - <p>NO2 : {air.airData.no2} μg/m3</p> | 95 | + <div key={index} className="forecastItemBox"> |
110 | - <p>O3 : {air.airData.o3} μg/m3</p> | 96 | + <h3> |
111 | - <p>SO2 : {air.airData.so2} μg/m3</p> | 97 | + {item.description} <small>{item.dateTime}</small> |
112 | - <p> | 98 | + </h3> |
113 | - {"pm2.5"} : {air.airData.pm2_5} μg/m3 | 99 | + <p> |
114 | - </p> | 100 | + Temperature : {item.temp.realCelcius} ℃ / feels like{" "} |
115 | - <p>pm10 : {air.airData.pm10} μg/m3</p> | 101 | + {item.temp.feelCelcius} ℃ |
116 | - </div> | 102 | + </p> |
117 | - )} | 103 | + <p>Wind : {item.types.wind} m/s</p> |
104 | + <p>Cloud : {item.types.clouds} %</p> | ||
105 | + </div> | ||
106 | + ))} | ||
107 | + </div> | ||
108 | + )} | ||
109 | + | ||
110 | + {!air ? ( | ||
111 | + "" | ||
112 | + ) : ( | ||
113 | + <div> | ||
114 | + <h2> | ||
115 | + {air.meta.state ? air.meta.state : ""} {air.meta.country} | ||
116 | + </h2> | ||
117 | + <p>CO : {air.airData.co} μg/m3</p> | ||
118 | + <p>NH3 : {air.airData.nh3} μg/m3</p> | ||
119 | + <p>NO : {air.airData.no} μg/m3</p> | ||
120 | + <p>NO2 : {air.airData.no2} μg/m3</p> | ||
121 | + <p>O3 : {air.airData.o3} μg/m3</p> | ||
122 | + <p>SO2 : {air.airData.so2} μg/m3</p> | ||
123 | + <p> | ||
124 | + {"pm2.5"} : {air.airData.pm2_5} μg/m3 | ||
125 | + </p> | ||
126 | + <p>pm10 : {air.airData.pm10} μg/m3</p> | ||
127 | + </div> | ||
128 | + )} | ||
129 | + </div> | ||
118 | 130 | ||
119 | <Bottombar /> | 131 | <Bottombar /> |
120 | </div> | 132 | </div> | ... | ... |
... | @@ -10,6 +10,7 @@ function Topbar() { | ... | @@ -10,6 +10,7 @@ function Topbar() { |
10 | <Link to="/" className="logo"> | 10 | <Link to="/" className="logo"> |
11 | <FcHome /> | 11 | <FcHome /> |
12 | </Link> | 12 | </Link> |
13 | + <div className="title">🤖 Weather Chatbot</div> | ||
13 | <Link to="/settings" className="settings"> | 14 | <Link to="/settings" className="settings"> |
14 | <AiFillSetting /> | 15 | <AiFillSetting /> |
15 | </Link> | 16 | </Link> | ... | ... |
... | @@ -38,14 +38,16 @@ function Login() { | ... | @@ -38,14 +38,16 @@ function Login() { |
38 | }; | 38 | }; |
39 | 39 | ||
40 | return ( | 40 | return ( |
41 | - <div className="container"> | 41 | + <div className="mainBox"> |
42 | <h1>Welcome back!</h1> | 42 | <h1>Welcome back!</h1> |
43 | <h2>Stay connected to weather*stories*friends</h2> | 43 | <h2>Stay connected to weather*stories*friends</h2> |
44 | 44 | ||
45 | <button>Login with Google</button> | 45 | <button>Login with Google</button> |
46 | + <br /> | ||
46 | <button>Login with GitHub</button> | 47 | <button>Login with GitHub</button> |
47 | 48 | ||
48 | <br /> | 49 | <br /> |
50 | + <br /> | ||
49 | 51 | ||
50 | <form className="authForm" onSubmit={(e) => handleSubmit(e)}> | 52 | <form className="authForm" onSubmit={(e) => handleSubmit(e)}> |
51 | <label htmlFor="email"> | 53 | <label htmlFor="email"> |
... | @@ -66,7 +68,7 @@ function Login() { | ... | @@ -66,7 +68,7 @@ function Login() { |
66 | id="password" | 68 | id="password" |
67 | /> | 69 | /> |
68 | </label> | 70 | </label> |
69 | - <label htmlFor="submit"> | 71 | + <label className="submitBtn" htmlFor="submit"> |
70 | <input type="submit" id="submit" /> | 72 | <input type="submit" id="submit" /> |
71 | </label> | 73 | </label> |
72 | </form> | 74 | </form> | ... | ... |
... | @@ -4,6 +4,8 @@ import authService from "../service/auth"; | ... | @@ -4,6 +4,8 @@ import authService from "../service/auth"; |
4 | // components | 4 | // components |
5 | import Topbar from "../components/Topbar"; | 5 | import Topbar from "../components/Topbar"; |
6 | import Bottombar from "../components/Bottombar"; | 6 | import Bottombar from "../components/Bottombar"; |
7 | +// styles | ||
8 | +import "../styles/layout.scss"; | ||
7 | 9 | ||
8 | function Settings() { | 10 | function Settings() { |
9 | const token = sessionStorage.getItem("user-token"); | 11 | const token = sessionStorage.getItem("user-token"); |
... | @@ -49,56 +51,63 @@ function Settings() { | ... | @@ -49,56 +51,63 @@ function Settings() { |
49 | return ( | 51 | return ( |
50 | <div> | 52 | <div> |
51 | <Topbar /> | 53 | <Topbar /> |
52 | - <h3>Edit Your information</h3> | 54 | + <div className="mainBox"> |
53 | - <form className="authForm" onSubmit={(e) => handleSubmit(e)}> | 55 | + <h3>Edit Your information</h3> |
54 | - <label htmlFor="username"> | 56 | + <form className="authForm" onSubmit={(e) => handleSubmit(e)}> |
55 | - <input | 57 | + <label htmlFor="username"> |
56 | - placeholder="username" | 58 | + <input |
57 | - onChange={(e) => onChange(e)} | 59 | + placeholder="username" |
58 | - value={userinfo.username} | 60 | + onChange={(e) => onChange(e)} |
59 | - type="text" | 61 | + value={userinfo.username} |
60 | - id="username" | 62 | + type="text" |
61 | - /> | 63 | + id="username" |
62 | - </label> | 64 | + /> |
63 | - <label htmlFor="country"> | 65 | + </label> |
64 | - <input | 66 | + <label htmlFor="country"> |
65 | - placeholder="Please use Alpha-2 Country Code" | 67 | + <input |
66 | - onChange={(e) => onChange(e)} | 68 | + placeholder="Please use Alpha-2 Country Code" |
67 | - value={userinfo.country.toUpperCase()} | 69 | + onChange={(e) => onChange(e)} |
68 | - type="text" | 70 | + value={userinfo.country.toUpperCase()} |
69 | - id="country" | 71 | + type="text" |
70 | - /> | 72 | + id="country" |
71 | - </label> | 73 | + /> |
72 | - <label htmlFor="city"> | 74 | + </label> |
73 | - <input | 75 | + <label htmlFor="city"> |
74 | - placeholder="City Name (lower case)" | 76 | + <input |
75 | - onChange={(e) => onChange(e)} | 77 | + placeholder="City Name (lower case)" |
76 | - value={userinfo.city.toLowerCase()} | 78 | + onChange={(e) => onChange(e)} |
77 | - type="text" | 79 | + value={userinfo.city.toLowerCase()} |
78 | - id="city" | 80 | + type="text" |
79 | - /> | 81 | + id="city" |
80 | - </label> | 82 | + /> |
81 | - <label htmlFor="email"> | 83 | + </label> |
82 | - <input | 84 | + <label htmlFor="email"> |
83 | - placeholder="Change email" | 85 | + <input |
84 | - onChange={(e) => onChange(e)} | 86 | + placeholder="Change email" |
85 | - value={userinfo.email} | 87 | + onChange={(e) => onChange(e)} |
86 | - type="email" | 88 | + value={userinfo.email} |
87 | - id="email" | 89 | + type="email" |
88 | - /> | 90 | + id="email" |
89 | - </label> | 91 | + /> |
90 | - <label htmlFor="submit"> | 92 | + </label> |
91 | - <input type="submit" id="submit" /> | 93 | + <label className="submitBtn" htmlFor="submit"> |
92 | - </label> | 94 | + <input type="submit" id="submit" /> |
93 | - </form> | 95 | + </label> |
96 | + </form> | ||
94 | 97 | ||
95 | - <br /> | 98 | + <br /> |
96 | 99 | ||
97 | - <div> | 100 | + <div> |
98 | - Want to logout?{" "} | 101 | + Want to logout?{" "} |
99 | - <button onClick={() => setLogoutSuccess("logout")}>Logout</button> | 102 | + <button |
103 | + className="logoutBtn" | ||
104 | + onClick={() => setLogoutSuccess("logout")} | ||
105 | + > | ||
106 | + Logout | ||
107 | + </button> | ||
108 | + </div> | ||
109 | + <Bottombar /> | ||
100 | </div> | 110 | </div> |
101 | - <Bottombar /> | ||
102 | </div> | 111 | </div> |
103 | ); | 112 | ); |
104 | } | 113 | } | ... | ... |
... | @@ -36,14 +36,16 @@ function Signup() { | ... | @@ -36,14 +36,16 @@ function Signup() { |
36 | }; | 36 | }; |
37 | 37 | ||
38 | return ( | 38 | return ( |
39 | - <div className="container"> | 39 | + <div className="mainBox"> |
40 | <h1>Welcome to WeatherAPP/twitter/Messanger!</h1> | 40 | <h1>Welcome to WeatherAPP/twitter/Messanger!</h1> |
41 | <h2>Stay connected to weather*stories*friends</h2> | 41 | <h2>Stay connected to weather*stories*friends</h2> |
42 | 42 | ||
43 | <button>Create account with Google</button> | 43 | <button>Create account with Google</button> |
44 | + <br /> | ||
44 | <button>Create account with GitHub</button> | 45 | <button>Create account with GitHub</button> |
45 | 46 | ||
46 | <br /> | 47 | <br /> |
48 | + <br /> | ||
47 | 49 | ||
48 | <p> | 50 | <p> |
49 | <b>Country Code</b> and <b>City Name</b> is required for Weather | 51 | <b>Country Code</b> and <b>City Name</b> is required for Weather |
... | @@ -97,7 +99,7 @@ function Signup() { | ... | @@ -97,7 +99,7 @@ function Signup() { |
97 | /> | 99 | /> |
98 | </label> | 100 | </label> |
99 | 101 | ||
100 | - <label htmlFor="submit"> | 102 | + <label className="submitBtn" htmlFor="submit"> |
101 | <input type="submit" id="submit" /> | 103 | <input type="submit" id="submit" /> |
102 | </label> | 104 | </label> |
103 | </form> | 105 | </form> | ... | ... |
... | @@ -6,7 +6,10 @@ | ... | @@ -6,7 +6,10 @@ |
6 | align-items: center; | 6 | align-items: center; |
7 | text-align: center; | 7 | text-align: center; |
8 | padding: 10px; | 8 | padding: 10px; |
9 | - | 9 | + height: 9vh; |
10 | + position: fixed; | ||
11 | + font-size: 3rem; | ||
12 | + width: 100%; | ||
10 | a { | 13 | a { |
11 | width: 45%; | 14 | width: 45%; |
12 | height: 90%; | 15 | height: 90%; |
... | @@ -18,6 +21,7 @@ | ... | @@ -18,6 +21,7 @@ |
18 | } | 21 | } |
19 | .logo { | 22 | .logo { |
20 | color: #008080; | 23 | color: #008080; |
24 | + font-size: 4rem; | ||
21 | } | 25 | } |
22 | 26 | ||
23 | * { | 27 | * { |
... | @@ -28,26 +32,31 @@ | ... | @@ -28,26 +32,31 @@ |
28 | .topbar { | 32 | .topbar { |
29 | margin-bottom: 0.5rem; | 33 | margin-bottom: 0.5rem; |
30 | justify-content: space-between; | 34 | justify-content: space-between; |
31 | - border-bottom: 2px gray solid; | 35 | + border-bottom: 4px gray solid; |
36 | + top: 0; | ||
32 | a { | 37 | a { |
33 | - font-size: 2.9rem; | 38 | + height: 5rem; |
34 | - height: 3rem; | ||
35 | } | 39 | } |
36 | .logo { | 40 | .logo { |
41 | + font-size: 5rem; | ||
37 | text-align: left; | 42 | text-align: left; |
38 | } | 43 | } |
39 | .settings { | 44 | .settings { |
45 | + font-size: 4.5rem; | ||
40 | text-align: right; | 46 | text-align: right; |
41 | } | 47 | } |
48 | + .title { | ||
49 | + width: 40vw; | ||
50 | + } | ||
42 | } | 51 | } |
43 | .bottombar { | 52 | .bottombar { |
44 | margin-top: 0.5rem; | 53 | margin-top: 0.5rem; |
45 | - border-top: 2px gray solid; | 54 | + border-top: 4px gray solid; |
46 | - font-size: 1.5rem; | 55 | + bottom: 0; |
47 | - height: 2.8rem; | 56 | + height: 4rem; |
48 | .bottomBtn { | 57 | .bottomBtn { |
49 | - margin-right: 0.2rem; | 58 | + margin-right: 0.4rem; |
50 | - margin-left: 0.2rem; | 59 | + margin-left: 0.4rem; |
51 | border: 1px solid gray; | 60 | border: 1px solid gray; |
52 | border-radius: 3px; | 61 | border-radius: 3px; |
53 | box-shadow: 3px 3px 3px 0px gray; | 62 | box-shadow: 3px 3px 3px 0px gray; | ... | ... |
1 | +html { | ||
2 | + height: 100vh; | ||
3 | +} | ||
1 | * { | 4 | * { |
2 | margin: 0; | 5 | margin: 0; |
3 | padding: 0; | 6 | padding: 0; |
4 | - background-color: #FFDEAD; | 7 | + background-color: #ffdead; |
5 | } | 8 | } |
6 | 9 | ||
7 | .container { | 10 | .container { |
8 | display: flex; | 11 | display: flex; |
9 | flex-direction: column; | 12 | flex-direction: column; |
10 | - margin-left: 0.5rem; | 13 | +} |
11 | - margin-right: 0.5rem; | 14 | + |
15 | +.mainBox { | ||
16 | + min-height: 82vh; | ||
17 | + margin-top: 13vh; | ||
18 | + padding-left: 1rem; | ||
19 | + padding-right: 1rem; | ||
20 | + font-size: 2rem; | ||
21 | + * { | ||
22 | + font-size: 2rem; | ||
23 | + } | ||
24 | + h2 { | ||
25 | + font-size: 2.5rem; | ||
26 | + } | ||
12 | } | 27 | } |
13 | 28 | ||
14 | .authForm { | 29 | .authForm { |
... | @@ -25,12 +40,30 @@ | ... | @@ -25,12 +40,30 @@ |
25 | } | 40 | } |
26 | } | 41 | } |
27 | 42 | ||
43 | +.submitBtn { | ||
44 | + width: 40%; | ||
45 | + color: green; | ||
46 | + border: green 2px solid; | ||
47 | + border-radius: 4px; | ||
48 | + input { | ||
49 | + background-color: green; | ||
50 | + } | ||
51 | +} | ||
52 | + | ||
53 | +.logoutBtn { | ||
54 | + width: 20%; | ||
55 | + border-radius: 4px; | ||
56 | + background-color: red; | ||
57 | +} | ||
58 | + | ||
28 | .weather-buttons { | 59 | .weather-buttons { |
29 | display: flex; | 60 | display: flex; |
30 | flex-direction: row; | 61 | flex-direction: row; |
31 | button { | 62 | button { |
32 | margin-left: 0.2rem; | 63 | margin-left: 0.2rem; |
33 | margin-right: 0.2rem; | 64 | margin-right: 0.2rem; |
65 | + padding: 0.2rem; | ||
66 | + border-radius: 6px; | ||
34 | } | 67 | } |
35 | } | 68 | } |
36 | 69 | ... | ... |
server/'
deleted
100644 → 0
1 | -const bcrypt = require("bcryptjs"); | ||
2 | -// handles "exception" inside of async express routes | ||
3 | -const asyncHandler = require("express-async-handler"); | ||
4 | -const User = require("../models/userModel"); | ||
5 | -const { jwtGenerator } = require("../config/jwt"); | ||
6 | - | ||
7 | -// @desc Signup new user | ||
8 | -// @route POST /api/users | ||
9 | -// @access Public | ||
10 | -const signupUser = asyncHandler(async (req, res) => { | ||
11 | - const { username, country, city, email, password } = req.body; | ||
12 | - if (!username || !country || !city || !email || !password) { | ||
13 | - res.status(400); | ||
14 | - throw new Error("Please fill in all fields"); | ||
15 | - } | ||
16 | - | ||
17 | - // Check if user already exists | ||
18 | - const userExists = await User.findOne({ email }); | ||
19 | - if (userExists) { | ||
20 | - res.status(400); | ||
21 | - throw new Error("User with the email already exists"); | ||
22 | - } | ||
23 | - | ||
24 | - // Hash password (bcrypt) | ||
25 | - const salt = await bcrypt.genSalt(10); | ||
26 | - const hashedPassword = await bcrypt.hash(password, salt); | ||
27 | - | ||
28 | - // Create/Build user | ||
29 | - const user = await User.create({ | ||
30 | - username, | ||
31 | - country, | ||
32 | - city, | ||
33 | - email, | ||
34 | - password: hashedPassword, | ||
35 | - }); | ||
36 | - | ||
37 | - // Send response | ||
38 | - if (user) { | ||
39 | - // 201: Resource successfully created | ||
40 | - res.status(201).json({ | ||
41 | - _id: user.id, | ||
42 | - username: user.username, | ||
43 | - country: user.country, | ||
44 | - city: user.city, | ||
45 | - email: user.email, | ||
46 | - token: jwtGenerator(user._id), | ||
47 | - }); | ||
48 | - } else { | ||
49 | - res.status(400); | ||
50 | - throw new Error("Invalid user data"); | ||
51 | - } | ||
52 | -}); | ||
53 | - | ||
54 | -// @desc Login user | ||
55 | -// @route POST /api/users/login | ||
56 | -// @access Public | ||
57 | -const loginUser = asyncHandler(async (req, res) => { | ||
58 | - const { email, password } = req.body; | ||
59 | - | ||
60 | - // Check email & password | ||
61 | - const userInDB = await User.findOne({ email }); | ||
62 | - const validPassword = await bcrypt.compare(password, userInDB.password); | ||
63 | - if (userInDB && validPassword) { | ||
64 | - res.status(200).json({ | ||
65 | - token: jwtGenerator(userInDB._id), | ||
66 | - }); | ||
67 | - } else { | ||
68 | - res.status(400); | ||
69 | - throw new Error("Invalid credentials"); | ||
70 | - } | ||
71 | -}); | ||
72 | - | ||
73 | -// @desc Get all users | ||
74 | -// @route GET /api/users/all | ||
75 | -// @access Public | ||
76 | -const getAllusers = asyncHandler(async (req, res) => { | ||
77 | - const users = await User.find() | ||
78 | - .select("-password") | ||
79 | - .select("-createdAt") | ||
80 | - .select("-email"); | ||
81 | - | ||
82 | - res.status(200).json(users); | ||
83 | -}); | ||
84 | - | ||
85 | -// @desc Get user | ||
86 | -// @route GET /api/users/self | ||
87 | -// @access Private | ||
88 | -const getSelf = asyncHandler(async (req, res) => { | ||
89 | - res.status(200).json(req.user); | ||
90 | -}); | ||
91 | - | ||
92 | -// @desc Edit user | ||
93 | -// @route PUT /api/users/edit | ||
94 | -// @access Private | ||
95 | -const editUser = asyncHandler(async (req, res) => { | ||
96 | - const {username, country, city, email} = req.body; | ||
97 | - console.log(username); | ||
98 | - res.json({}); | ||
99 | -}); | ||
100 | - | ||
101 | -module.exports = { | ||
102 | - signupUser, | ||
103 | - loginUser, | ||
104 | - getAllusers, | ||
105 | - getSelf, | ||
106 | - editUser, | ||
107 | -}; |
-
Please register or login to post a comment