JungSeungHyun

upstream

...@@ -117,6 +117,6 @@ dist ...@@ -117,6 +117,6 @@ dist
117 .pnp.* 117 .pnp.*
118 118
119 package-lock.json 119 package-lock.json
120 -uploads 120 +/uploads
121 static 121 static
122 build 122 build
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -11,6 +11,7 @@ KHU-Hub repo: [khuhub.khu.ac.kr/2018102216/dev-profile](https://khuhub.khu.ac.kr ...@@ -11,6 +11,7 @@ KHU-Hub repo: [khuhub.khu.ac.kr/2018102216/dev-profile](https://khuhub.khu.ac.kr
11 - [x] random quotes **_for developers_** to motivate you :sparkles: 11 - [x] random quotes **_for developers_** to motivate you :sparkles:
12 - [ ] the amount of commits you've done on [GitHub](https://github.com/) at a glance 12 - [ ] the amount of commits you've done on [GitHub](https://github.com/) at a glance
13 - [ ] your most-contributed project on GitHub 13 - [ ] your most-contributed project on GitHub
14 +- [x] today's trending repositories on GitHub
14 <br> 15 <br>
15 16
16 ### Additional Features 17 ### Additional Features
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
23 "express-session": "^1.17.1", 23 "express-session": "^1.17.1",
24 "mongoose": "^5.12.9", 24 "mongoose": "^5.12.9",
25 "morgan": "^1.10.0", 25 "morgan": "^1.10.0",
26 + "multer": "^1.4.2",
26 "nodemon": "^2.0.7", 27 "nodemon": "^2.0.7",
27 "passport": "^0.4.1", 28 "passport": "^0.4.1",
28 "passport-github2": "^0.1.12", 29 "passport-github2": "^0.1.12",
......
...@@ -2,54 +2,157 @@ import axios from "axios"; ...@@ -2,54 +2,157 @@ import axios from "axios";
2 import passport from "passport"; 2 import passport from "passport";
3 import User from "../models/User"; 3 import User from "../models/User";
4 4
5 -const getQuote = async (req,res) =>{ 5 +const getQuote = async (req, res) => {
6 - const url = "http://quotes.stormconsultancy.co.uk/random.json"; 6 + const url = "http://quotes.stormconsultancy.co.uk/random.json";
7 - const quoteData = await axios.get(url).then(function(response){ 7 + const quoteData = await axios.get(url).then(function (response) {
8 - return response.data; 8 + return response.data;
9 - }); 9 + });
10 - const quote = quoteData.quote; 10 + const quote = quoteData.quote;
11 - const author = quoteData.author; 11 + const author = quoteData.author;
12 - return {quote,author}; 12 + return { quote, author };
13 -} 13 +};
14 14
15 -export const handleHome = async (req,res)=>{ 15 +const gitTrend = async (req, res) => {
16 - const quote = await getQuote(); 16 + const url =
17 - res.render("home",{pageTitle:"Home", quote:quote.quote, author:quote.author}); 17 + "https://api.trending-github.com/github/repositories?period=daily";
18 -} 18 + const trendData = await axios.get(url).then(function (response) {
19 + return response.data;
20 + });
21 + const name0 = trendData[0].name;
22 + const description0 = trendData[0].description;
23 + const Url0 = trendData[0].url;
24 + const stars0 = trendData[0].stars;
25 + const name1 = trendData[1].name;
26 + const description1 = trendData[1].description;
27 + const Url1 = trendData[1].url;
28 + const stars1 = trendData[1].stars;
29 + const name2 = trendData[2].name;
30 + const description2 = trendData[2].description;
31 + const Url2 = trendData[2].url;
32 + const stars2 = trendData[2].stars;
33 +
34 + return {
35 + name0,
36 + description0,
37 + Url0,
38 + stars0,
39 + name1,
40 + description1,
41 + Url1,
42 + stars1,
43 + name2,
44 + description2,
45 + Url2,
46 + stars2,
47 + };
48 +};
19 49
20 50
21 -export const getUserDetail = async (req,res) =>{
22 - const quote = await getQuote();
23 - res.render("userDetail",{pagetTitle:"User Detail", quote:quote.quote, author:quote.author})
24 -}
25 51
26 -export const getEditProfile = (req,res)=> res.render("editProfile",{pageTitle:"Edit Profile"}); 52 +export const handleHome = async (req, res) => {
53 + const quote = await getQuote();
54 + const trend = await gitTrend();
55 + res.render("home", {
56 + pageTitle: "Home",
57 + quote: quote.quote,
58 + author: quote.author,
59 + name0: trend.name0,
60 + description0: trend.description0,
61 + Url0: trend.Url0,
62 + stars0: trend.stars0,
63 + name1: trend.name1,
64 + description1: trend.description1,
65 + Url1: trend.Url1,
66 + stars1: trend.stars1,
67 + name2: trend.name2,
68 + description2: trend.description2,
69 + Url2: trend.Url2,
70 + stars2: trend.stars2,
71 + });
72 +};
27 73
28 -export const postEditProfile = (req,res) =>{ 74 +export const getUserDetail = async (req, res) => {
29 - console.log(req.body); 75 + const quote = await getQuote();
30 - res.redirect("/users/edit-profile"); 76 + res.render("userDetail", {
77 + pagetTitle: "User Detail",
78 + quote: quote.quote,
79 + author: quote.author,
80 + });
31 }; 81 };
32 82
83 +export const getEditProfile = async (req,res)=> {
84 + const{
85 + user:{_id:id}
86 + } = req;
87 + try{
88 + const user = await User.findById(id);
89 + if(user.id !== id){
90 + throw Error();
91 + } else{
92 + res.render("editProfile",{pageTitle:"Edit Profile", user});
93 + }
94 + }catch(error){
95 + console.log(error);
96 + }
97 +};
33 98
34 -export const getJoin = (req,res)=>{ 99 +export const postEditProfile = async (req,res) =>{
35 - res.render("join",{pageTitle: "Join"}); 100 + const {
101 + user:{_id:id},
102 + body: {name, email, school, blogUrl, tech, career, introduction},
103 + file
104 + } = req;
105 + try{
106 + const updatedUser = await User.findByIdAndUpdate(id, {
107 + avatarUrl: file ? file.path : req.session.passport.user.avatarUrl,
108 + name,
109 + email,
110 + school,
111 + blogUrl,
112 + tech: User.formatTech(tech),
113 + career: User.formatCareer(career),
114 + introduction
115 + },
116 + {
117 + new: true
118 + });
119 + req.session.passport.user = updatedUser;
120 + res.redirect("/users/edit-profile");
121 + }catch(error){
122 + console.log(error);
123 + res.redirect("/");
124 + }
36 }; 125 };
37 126
38 -export const getLogin = (req,res)=>{ 127 +export const getJoin = (req, res) => {
39 - res.render("login",{pageTitle: "Login"}); 128 + res.render("join", { pageTitle: "Join" });
40 }; 129 };
41 130
42 -export const handleUsers = (req,res)=>{ 131 +export const getLogin = (req, res) => {
43 - res.render("users",{pageTitle:"Users"}); 132 + res.render("login", { pageTitle: "Login" });
44 -} 133 +};
45 134
46 -export const githubLogin = passport.authenticate("github", {scope: [ "user:email" ]}); 135 +export const handleUsers = (req, res) => {
136 + res.render("users", { pageTitle: "Users" });
137 +};
47 138
48 -export const githubLoginCallback = async (_, __, profile, done) =>{ 139 +export const githubLogin = passport.authenticate("github", {
49 - const {_json: {id:githubId, login:githubName, avatar_url:avatarUrl, name, email}} = profile; 140 + scope: ["user:email"],
141 +});
142 +
143 +export const githubLoginCallback = async (_, __, profile, done) => {
144 + const {
145 + _json: {
146 + id: githubId,
147 + login: githubName,
148 + avatar_url: avatarUrl,
149 + name,
150 + email,
151 + },
152 + } = profile;
50 153
51 try{ 154 try{
52 - const user = await User.findOne({email}); 155 + const user = await User.findOne({githubId});
53 if(user){ 156 if(user){
54 user.githubId = githubId, 157 user.githubId = githubId,
55 user.githubName = githubName 158 user.githubName = githubName
...@@ -70,11 +173,12 @@ export const githubLoginCallback = async (_, __, profile, done) =>{ ...@@ -70,11 +173,12 @@ export const githubLoginCallback = async (_, __, profile, done) =>{
70 } 173 }
71 }; 174 };
72 175
73 -export const postGithubLogin = (req,res)=>{ 176 +export const postGithubLogin = (req, res) => {
74 - const userId = req.user.id; 177 + const userId = req.user.id;
75 - res.redirect(`/users/${userId}`); 178 + res.redirect(`/users/${userId}`);
76 -} 179 +};
77 180
181 +<<<<<<< HEAD
78 export const logout = (req,res)=>{ 182 export const logout = (req,res)=>{
79 req.logout(); 183 req.logout();
80 res.redirect("/"); 184 res.redirect("/");
...@@ -89,4 +193,10 @@ const getRepos = async(req,res) =>{ ...@@ -89,4 +193,10 @@ const getRepos = async(req,res) =>{
89 const secondRepoName = latelyRepos.[1].name; 193 const secondRepoName = latelyRepos.[1].name;
90 const firstRepoUrl = latelyRepos.[0].html_url; 194 const firstRepoUrl = latelyRepos.[0].html_url;
91 const secondRepoUrl = latelyRepos.[1].html_url; 195 const secondRepoUrl = latelyRepos.[1].html_url;
92 -};
...\ No newline at end of file ...\ No newline at end of file
196 +};
197 +=======
198 +export const logout = (req, res) => {
199 + req.logout();
200 + res.redirect("/");
201 +};
202 +>>>>>>> 29aa84017aef7f3207044abc818143e72cf33907
......
1 +import multer from "multer";
2 +
1 export const localsMiddleware = (req,res,next) => { 3 export const localsMiddleware = (req,res,next) => {
2 res.locals.siteName = "Dev Profile"; 4 res.locals.siteName = "Dev Profile";
3 res.locals.loggedUser = req.user || null; 5 res.locals.loggedUser = req.user || null;
...@@ -19,4 +21,11 @@ export const onlyPrivate = (req, res, next) => { ...@@ -19,4 +21,11 @@ export const onlyPrivate = (req, res, next) => {
19 } else { 21 } else {
20 res.redirect("/"); 22 res.redirect("/");
21 } 23 }
22 -};
...\ No newline at end of file ...\ No newline at end of file
24 +};
25 +
26 +export const uploadFiles = multer({
27 + dest:"uploads/",
28 + limits: {
29 + fileSize: 3000000
30 + }
31 +});
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -27,7 +27,7 @@ const UserSchema = new mongoose.Schema({ ...@@ -27,7 +27,7 @@ const UserSchema = new mongoose.Schema({
27 }, 27 },
28 tech: [{ type: String, trim: true }], 28 tech: [{ type: String, trim: true }],
29 career: [{ type: String, trim: true }], 29 career: [{ type: String, trim: true }],
30 - introduction: String, 30 + introduction: { type: String, maxLength: 500},
31 createdAt: { 31 createdAt: {
32 type: Date, 32 type: Date,
33 default: Date.now 33 default: Date.now
......
...@@ -12,9 +12,10 @@ globalRouter.get("/join", onlyPublic, getJoin); ...@@ -12,9 +12,10 @@ globalRouter.get("/join", onlyPublic, getJoin);
12 globalRouter.get("/login", onlyPublic, getLogin); 12 globalRouter.get("/login", onlyPublic, getLogin);
13 globalRouter.get("/logout", onlyPrivate, logout); 13 globalRouter.get("/logout", onlyPrivate, logout);
14 14
15 -globalRouter.get("/auth/github", githubLogin); 15 +globalRouter.get("/auth/github", onlyPublic, githubLogin);
16 globalRouter.get( 16 globalRouter.get(
17 "/auth/github/callback", 17 "/auth/github/callback",
18 + onlyPublic,
18 passport.authenticate("github",{failureRedirect: "/login"}), 19 passport.authenticate("github",{failureRedirect: "/login"}),
19 postGithubLogin 20 postGithubLogin
20 ); 21 );
......
1 import express from "express"; 1 import express from "express";
2 import { getEditProfile, getUserDetail, handleUsers, postEditProfile } from "../controllers/userController"; 2 import { getEditProfile, getUserDetail, handleUsers, postEditProfile } from "../controllers/userController";
3 -import { onlyPrivate } from "../middlewares"; 3 +import { onlyPrivate, uploadFiles } from "../middlewares";
4 -
5 4
6 const userRouter = express.Router(); 5 const userRouter = express.Router();
7 6
8 -userRouter.get("/",handleUsers); 7 +userRouter.get("/", handleUsers);
9 8
10 userRouter.get("/edit-profile", onlyPrivate, getEditProfile); 9 userRouter.get("/edit-profile", onlyPrivate, getEditProfile);
11 -userRouter.post("/edit-profile", onlyPrivate, postEditProfile); 10 +userRouter.post("/edit-profile", onlyPrivate, uploadFiles.single("photo"),postEditProfile);
12 11
13 userRouter.get("/:id", getUserDetail); 12 userRouter.get("/:id", getUserDetail);
14 13
15 -
16 -export default userRouter;
...\ No newline at end of file ...\ No newline at end of file
14 +export default userRouter;
......
...@@ -32,6 +32,7 @@ app.use(passport.initialize()); ...@@ -32,6 +32,7 @@ app.use(passport.initialize());
32 app.use(passport.session()); 32 app.use(passport.session());
33 33
34 app.use(localsMiddleware); 34 app.use(localsMiddleware);
35 +app.use("/uploads", express.static("uploads"));
35 app.use("/", globalRouter); 36 app.use("/", globalRouter);
36 app.use("/users", userRouter); 37 app.use("/users", userRouter);
37 38
......
1 extends layouts/main 1 extends layouts/main
2 2
3 block content 3 block content
4 - .form-container 4 + .form-container
5 - form(action="/users/edit-profile", method="POST", enctype="application/json") 5 + form(action="/users/edit-profile", method="POST", enctype="multipart/form-data")
6 + img(src=`/${loggedUser.avatarUrl}`, width="100", height="120")
6 .fileUpload 7 .fileUpload
7 - label(for="picture") Picture 8 + label(for="photo") Photo
8 - input(type="file", id="picture", name="picture", accept="image/*") 9 + input(type="file", id="photo", name="photo", accept="image/*")
9 - input(type="text", placeholder="Name", name="name") 10 + label(for="name") Name
10 - input(type="text", placeholder="Github Id", name="githubId") 11 + input(type="text", id="name",placeholder="Name", name="name", value=user.name)
11 - input(type="email", placeholder="Email", name="email") 12 + label(for="email") Email
12 - input(type="text", placeholder="School", name="school") 13 + input(type="email", id="email", placeholder="Email", name="email", value=user.email)
13 - textarea(name="tech", placeholder="Add your Tech") 14 + label(for="school") School
14 - textarea(name="career", placeholder="Add your Career") 15 + input(type="text", id="school",placeholder="School", name="school", value=user.school)
15 - textarea(name="introduction", placeholder="Self introduction") 16 + label(for="blogUrl") Blog Url
17 + input(type="text", id="blogUrl", placeholder="Blog url", name="blogUrl", value=user.blogUrl)
18 + label(for="tech") Enter your tech skills seperated by comma. ex)react,node
19 + textarea(name="tech", id="tech", placeholder="Add Tech you can use")=user.tech
20 + label(for="career") Enter your careers seperated by comma. ex)A company, B competition
21 + textarea(name="career", id="career", placeholder="Add your Career")=user.career
22 + label(for="introduction") Self introduction
23 + textarea(name="introduction", id="introduction", placeholder="Self introduction", maxlength=200)=user.introduction
16 input(type="submit", value="Update Profile") 24 input(type="submit", value="Update Profile")
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -7,7 +7,22 @@ block content ...@@ -7,7 +7,22 @@ block content
7 h1 -Developer Profile- 7 h1 -Developer Profile-
8 h2=quote 8 h2=quote
9 h3=author 9 h3=author
10 - .home-link 10 +
11 - a(href="/join") Join 11 + if !loggedUser
12 - |#{' '} 12 + .home-link
13 - a(href="/login") Login 13 + a(href="/join") Join
14 + |#{' '}
15 + a(href="/login") Login
16 + else
17 + a(href=`/users/${loggedUser._id}`) My profile
18 +
19 + .gotoTrend(style="border: 1px solid blue;")
20 + p(style='color: orange;') Trending Repositories:
21 + br
22 + a(href=Url0, style={color:'grey'})
23 + p=name0+": "+description0+" - "+stars0+" stars"
24 + a(href=Url1, style={color:'grey'})
25 + p=name1+": "+description1+" - "+stars1+" stars"
26 + a(href=Url2, style={color:'grey'})
27 + p=name2+": "+description2+" - "+stars2+" stars"
28 +
......
...@@ -3,10 +3,9 @@ extends layouts/main ...@@ -3,10 +3,9 @@ extends layouts/main
3 block content 3 block content
4 i.fas.fa-location-arrow 4 i.fas.fa-location-arrow
5 h3 Start with GitHub! 5 h3 Start with GitHub!
6 - button.login-github 6 + a(href="/auth/github")
7 - a(href="/auth/github") 7 + .login-github
8 - span 8 + i.fab.fa-github
9 - i.fab.fa-github 9 + span Join with GitHub
10 - |Join with GitHub
11 10
12 11
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -3,10 +3,9 @@ extends layouts/main ...@@ -3,10 +3,9 @@ extends layouts/main
3 block content 3 block content
4 i.fas.fa-location-arrow 4 i.fas.fa-location-arrow
5 h3 Login with GitHub! 5 h3 Login with GitHub!
6 - button.login-github 6 + a(href="/auth/github")
7 - a(href="/auth/github") 7 + .login-github
8 - span 8 + i.fab.fa-github
9 - i.fab.fa-github 9 + span Login with GitHub
10 - |Login with GitHub
11 10
12 11
...\ No newline at end of file ...\ No newline at end of file
......
1 -footer.footer 1 +footer.footer
2 + hr
2 .footer__icon 3 .footer__icon
3 i.fas.fa-code-branch 4 i.fas.fa-code-branch
4 span.footer__text &copy; dev-profile #{new Date().getFullYear()} 5 span.footer__text &copy; dev-profile #{new Date().getFullYear()}
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -12,7 +12,9 @@ header.header ...@@ -12,7 +12,9 @@ header.header
12 12
13 else 13 else
14 li 14 li
15 - a(href="/") Home 15 + a(href="/") Home
16 + li
17 + a(href=`/users/${loggedUser._id}`) My Profile
16 li 18 li
17 a(href="/users/edit-profile") Edit Profile 19 a(href="/users/edit-profile") Edit Profile
18 li 20 li
......