diff --git a/package.json b/package.json
index d0ee9436..b0fadbce 100644
--- a/package.json
+++ b/package.json
@@ -3,15 +3,21 @@
"version": "0.1.0",
"private": true,
"dependencies": {
- "@testing-library/jest-dom": "^5.11.4",
- "@testing-library/react": "^11.1.0",
- "@testing-library/user-event": "^12.1.10",
+ "@testing-library/jest-dom": "^5.16.2",
+ "@testing-library/react": "^12.1.3",
+ "@testing-library/user-event": "^13.5.0",
+ "firebase": "^8.6.1",
+ "firebase-tools": "^9.11.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
+ "react-player": "^2.9.0",
+ "react-redux": "^7.2.4",
"react-router-dom": "^5.2.0",
- "react-scripts": "4.0.3",
- "styled-components": "^5.2.3",
- "web-vitals": "^1.0.1"
+ "react-scripts": "^4.0.3",
+ "redux": "^4.1.0",
+ "redux-thunk": "^2.3.0",
+ "styled-components": "^5.3.0",
+ "web-vitals": "^1.1.2"
},
"scripts": {
"start": "react-scripts start",
diff --git a/public/images/article-icon.png b/public/images/article-icon.png
new file mode 100644
index 00000000..863e34df
Binary files /dev/null and b/public/images/article-icon.png differ
diff --git a/public/images/clap-icon.png b/public/images/clap-icon.png
new file mode 100644
index 00000000..d3effaf5
Binary files /dev/null and b/public/images/clap-icon.png differ
diff --git a/public/images/close-icon.png b/public/images/close-icon.png
new file mode 100644
index 00000000..951bf63f
Binary files /dev/null and b/public/images/close-icon.png differ
diff --git a/public/images/comment-icon.png b/public/images/comment-icon.png
new file mode 100644
index 00000000..66ce61ba
Binary files /dev/null and b/public/images/comment-icon.png differ
diff --git a/public/images/ellipsis.png b/public/images/ellipsis.png
new file mode 100644
index 00000000..2abd4e59
Binary files /dev/null and b/public/images/ellipsis.png differ
diff --git a/public/images/event-icon.png b/public/images/event-icon.png
new file mode 100644
index 00000000..8db3ff53
Binary files /dev/null and b/public/images/event-icon.png differ
diff --git a/public/images/like-icon.png b/public/images/like-icon.png
new file mode 100644
index 00000000..d27a55e0
Binary files /dev/null and b/public/images/like-icon.png differ
diff --git a/public/images/linkedin.png b/public/images/linkedin.png
index 496733dd..743d3e62 100644
Binary files a/public/images/linkedin.png and b/public/images/linkedin.png differ
diff --git a/public/images/photo-icon.png b/public/images/photo-icon.png
new file mode 100644
index 00000000..237f3f82
Binary files /dev/null and b/public/images/photo-icon.png differ
diff --git a/public/images/shared-comment.png b/public/images/shared-comment.png
new file mode 100644
index 00000000..6add17d3
Binary files /dev/null and b/public/images/shared-comment.png differ
diff --git a/public/images/shared-img.png b/public/images/shared-img.png
new file mode 100644
index 00000000..ade17228
Binary files /dev/null and b/public/images/shared-img.png differ
diff --git a/public/images/shared-vid.png b/public/images/shared-vid.png
new file mode 100644
index 00000000..ede42953
Binary files /dev/null and b/public/images/shared-vid.png differ
diff --git a/public/images/spin-loading.gif b/public/images/spin-loading.gif
new file mode 100644
index 00000000..941ee559
Binary files /dev/null and b/public/images/spin-loading.gif differ
diff --git a/public/images/video-icon.png b/public/images/video-icon.png
new file mode 100644
index 00000000..91ad70cc
Binary files /dev/null and b/public/images/video-icon.png differ
diff --git a/src/App.css b/src/App.css
index e69de29b..d5d655fd 100644
--- a/src/App.css
+++ b/src/App.css
@@ -0,0 +1,3 @@
+* {
+ scroll-behavior: smooth;
+}
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
index 3058f6f3..068ba716 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,10 +1,17 @@
-import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
-import "./App.css";
-import Header from "./components/Header";
-import Home from "./components/Home";
-import Login from "./components/Login";
+import { connect } from 'react-redux';
+import { useEffect } from 'react';
+import { BrowserRouter as Router, Switch, Route} from 'react-router-dom';
+import './App.css';
+import Login from './components/Login';
+import Home from './components/Home';
+import Header from './components/Header';
+import { getUserAuth } from './actions';
+
+function App(props) {
+useEffect(() => {
+ props.getUserAuth();
+}, []);
-function App() {
return (
@@ -22,4 +29,12 @@ function App() {
);
}
-export default App;
+const mapStateToProps = (state) => {
+ return {};
+};
+
+const mapDispatchToProps = (dispatch) => ({
+ getUserAuth: () => dispatch(getUserAuth()),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(App);
\ No newline at end of file
diff --git a/src/actions/actionType.js b/src/actions/actionType.js
new file mode 100644
index 00000000..0b9f5804
--- /dev/null
+++ b/src/actions/actionType.js
@@ -0,0 +1,3 @@
+export const SET_USER = "SET_USER";
+export const SET_LOADING_STATUS = "SET_LOADING_STATUS";
+export const GET_ARTICLES = "GET_ARTICLES";
\ No newline at end of file
diff --git a/src/actions/index.js b/src/actions/index.js
new file mode 100644
index 00000000..54cd9ebf
--- /dev/null
+++ b/src/actions/index.js
@@ -0,0 +1,117 @@
+import { auth, provider, storage } from '../firebase';
+import db from '../firebase';
+import { SET_USER, SET_LOADING_STATUS, GET_ARTICLES } from './actionType';
+
+export const setUser = (payload) => ({
+ type: SET_USER,
+ user: payload,
+})
+
+export const setLoading = (status) => ({
+ type: SET_LOADING_STATUS,
+ status : status,
+})
+
+export const getArticles = (payload) => ({
+ type: GET_ARTICLES,
+ payload: payload,
+})
+
+export function signInAPI() {
+ return (dispatch) => {
+ auth
+ .signInWithPopup(provider)
+ .then((payload) => {
+ dispatch(setUser(payload.user));
+ })
+ .catch((error) => alert(error.message));
+ };
+}
+
+export function getUserAuth() {
+ return (dispatch) => {
+ auth.onAuthStateChanged(async (user) => {
+ if(user) {
+ dispatch(setUser(user));
+ }
+ })
+ }
+}
+
+export function signOutAPI() {
+ return(dispatch) => {
+ auth
+ .signOut()
+ .then(() => {
+ dispatch(setUser(null));
+ })
+ .catch((error) => {
+ console.log(error.message);
+ });
+ };
+}
+
+export function postArticleAPI(payload) {
+ return (dispatch) => {
+ dispatch(setLoading(true));
+
+ if(payload.image != '') {
+ const upload = storage
+ .ref(`images/${payload.image.name}`)
+ .put(payload.image);
+ upload.on('state-changed', (snapshot) => {
+ const progress =
+ (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
+
+ console.log(`Progress: ${progress}%`);
+ if(snapshot.state === 'RUNNING') {
+ console.log(`Progress: ${progress}%`);
+ }
+ }, error => console.log(error.code),
+ async () => {
+ const downloadURL = await upload.snapshot.ref.getDownloadURL();
+ db.collection("articles").add({
+ actor: {
+ description: payload.user.email,
+ title: payload.user.displayName,
+ date: payload.timestamp,
+ image: payload.user.photoURL
+ },
+ video: payload.video,
+ sharedImg: downloadURL,
+ comments: 0,
+ description: payload.description,
+ });
+ dispatch(setLoading(false));
+ });
+ }
+ else if(payload.video) {
+ db.collection('articles').add({
+ actor: {
+ description: payload.user.email,
+ title: payload.user.displayName,
+ date: payload.timestamp,
+ image: payload.user.photoURL,
+ },
+ video: payload.video,
+ sharedImg: '',
+ comments: 0,
+ description: payload.description,
+ });
+ dispatch(setLoading(false));
+ }
+};
+}
+
+export function getArticlesAPI() {
+ return (dispatch) => {
+ let payload;
+
+ db.collection('articles')
+ .orderBy("actor.date", "desc")
+ .onSnapshot((snapshot) => {
+ payload = snapshot.docs.map((doc) => doc.data());
+ dispatch(getArticles(payload));
+ });
+ };
+}
\ No newline at end of file
diff --git a/src/components/Header.js b/src/components/Header.js
index 1cfcb32f..4b78ee34 100644
--- a/src/components/Header.js
+++ b/src/components/Header.js
@@ -1,260 +1,288 @@
-import styled from "styled-components";
+import styled from 'styled-components';
+import { connect } from 'react-redux';
+import { signOutAPI } from '../actions';
const Header = (props) => {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ );
+}
const Container = styled.div`
- background-color: white;
- border-bottom: 1px solid rgba(0, 0, 0, 0.08);
- left: 0;
- padding: 0 24px;
- position: fixed;
- top: 0;
- width: 100vw;
- z-index: 100;
+ background-color: #ffffff;
+ border-bottom: 1px solid rgba(0,0,0,0.08);
+ left: 0;
+ padding: 0 24px;
+ top: 0;
+ position: fixed;
+ width: 100vw;
+ z-index: 100;
`;
const Content = styled.div`
- display: flex;
- align-items: center;
- margin: 0 auto;
- min-height: 100%;
- max-width: 1128px;
+ display: flex;
+ align-items: center;
+ margin: 0 auto;
+ min-height: 100%;
+ max-width: 1128px;
`;
const Logo = styled.span`
- margin-right: 8px;
- font-size: 0px;
+ margin-right: 8px;
+ font-size: 0px;
`;
const Search = styled.div`
- opacity: 1;
- flex-grow: 1;
- position: relative;
- & > div {
- max-width: 280px;
- input {
- border: none;
- box-shadow: none;
- background-color: #eef3f8;
- border-radius: 2px;
- color: rgba(0, 0, 0, 0.9);
- width: 218px;
- padding: 0 8px 0 40px;
- line-height: 1.75;
- font-weight: 400;
- font-size: 14px;
- height: 34px;
- border-color: #dce6f1;
- vertical-align: text-top;
+ opacity: 1;
+ flex-grow: 1;
+ position: relative;
+
+ & > div {
+ max-width: 280px;
+
+ input {
+ border: none;
+ box-shadow: none;
+ background-color: #eef3f8;
+ border-radius: 2px;
+ color: rgba(0,0,0,0.9);
+ width: 218px;
+ padding: 0 8px 0 40px;
+ line-height: 1.75;
+ font-weight: 400;
+ font-size: 14px;
+ height: 34px;
+ border-color: #dce6f1;
+ vertical-align: text-top;
+ }
}
- }
`;
const SearchIcon = styled.div`
- width: 40px;
- position: absolute;
- z-index: 1;
- top: 10px;
- left: 2px;
- border-radius: 0 2px 2px 0;
- margin: 0;
- pointer-events: none;
- display: flex;
- justify-content: center;
- align-items: center;
+ width: 40px;
+ position: absolute;
+ z-index: 1;
+ top: 10px;
+ left: 2px;
+ border-radius: 0 2px 2px 0;
+ margin: 0;
+ pointer-events: none;
+ display: flex;
+ justify-content: center;
+ align-items: center;
`;
const Nav = styled.nav`
- margin-left: auto;
- display: block;
- @media (max-width: 768px) {
- position: fixed;
- left: 0;
- bottom: 0;
- background: white;
- width: 100%;
- }
+ margin-left: auto;
+ display: block;
+
+ @media (max-width: 768px) {
+ position: fixed;
+ left: 0;
+ bottom: 0;
+ background: #ffffff;
+ width: 100%;
+ }
`;
const NavListWrap = styled.ul`
- display: flex;
- flex-wrap: nowrap;
- list-style-type: none;
+ display: flex;
+ flex-wrap: nowrap;
+ list-style-type: none;
- .active {
- span:after {
- content: "";
- transform: scaleX(1);
- border-bottom: 2px solid var(--white, #fff);
- bottom: 0;
- left: 0;
- position: absolute;
- transition: transform 0.2s ease-in-out;
- width: 100%;
- border-color: rgba(0, 0, 0, 0.9);
+ .active {
+ span:after {
+ content: '';
+ transform: scaleX(1);
+ border-bottom: 2px solid var(--white, #ffffff);
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ transition: transform 0.2s ease-in-out;
+ width: 100%;
+ border-color: rgba(0,0,0,0.9);
+ }
}
- }
`;
const NavList = styled.li`
- display: flex;
- align-items: center;
- a {
- align-items: center;
- background: transparent;
display: flex;
- flex-direction: column;
- font-size: 12px;
- font-weight: 400;
- justify-content: center;
- line-height: 1.5;
- min-height: 52px;
- min-width: 80px;
- position: relative;
- text-decoration: none;
+ align-items: center;
- span {
- color: rgba(0, 0, 0, 0.6);
- display: flex;
- align-items: center;
- }
+ a {
+ align-items: center;
+ background: transparent;
+ display: flex;
+ flex-direction: column;
+ font-size: 12px;
+ font-weight: 400;
+ justify-content: center;
+ line-height: 1.5;
+ min-height: 42px;
+ min-width: 88px;
+ position: relative;
+ text-decoration: none;
- @media (max-width: 768px) {
- min-width: 70px;
+ span {
+ color: rgba(0,0,0,0.6);
+ display: flex;
+ align-items: center;
+ }
+
+ @media (max-width: 768px) {
+ min-width: 70px;
+ }
}
- }
- &:hover,
- &:active {
- a {
- span {
- color: rgba(0, 0, 0, 0.9);
- }
+ &:hover,&:active {
+ a {
+ span {
+ color: rgba(0, 0, 0, 0.9);
+ }
+ }
}
- }
`;
const SignOut = styled.div`
- position: absolute;
- top: 45px;
- background: white;
- border-radius: 0 0 5px 5px;
- width: 100px;
- height: 40px;
- font-size: 16px;
- transition-duration: 167ms;
- text-align: center;
- display: none;
+ cursor: pointer;
+ position: absolute;
+ top: 45px;
+ background: #ffffff;
+ border-radius: 0 0 5px 5px;
+ width: 100px;
+ box-shadow: 2px 3px 5px -2px rgba(110,104,104,0.75);
+ height: 40px;
+ font-size: 16px;
+ transition-duration: 167ms;
+ text-align: center;
+ display: none;
`;
const User = styled(NavList)`
- a > svg {
- width: 24px;
- border-radius: 50%;
- }
+ a > svg {
+ padding-top: 5px;
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ }
- a > img {
- width: 24px;
- height: 24px;
- border-radius: 50%;
- }
+ a > img {
+ width: 24px;
+ height: 24px;
+ padding-top: 5px;
+ border-radius: 50%;
+ }
- span {
- display: flex;
- align-items: center;
- }
+ span {
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ }
- &:hover {
- ${SignOut} {
- align-items: center;
- display: flex;
- justify-content: center;
+ &:hover {
+ ${SignOut} {
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ }
}
- }
`;
const Work = styled(User)`
- border-left: 1px solid rgba(0, 0, 0, 0.08);
+ border-left: 1px solid rgba(0, 0, 0, 0.08);
`;
-export default Header;
+const mapStateToProps = (state) => {
+ return {
+ user: state.userState.user,
+ };
+};
+
+const mapDispatchToProps = (dispatch) => ({
+ signOut: () => dispatch(signOutAPI()),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(Header);
\ No newline at end of file
diff --git a/src/components/Home.js b/src/components/Home.js
index db0c42ad..31aafd47 100644
--- a/src/components/Home.js
+++ b/src/components/Home.js
@@ -1,81 +1,91 @@
import styled from "styled-components";
-import Leftside from "./Leftside";
-import Main from "./Main";
-import Rightside from "./Rightside";
-
+import Leftside from './Leftside';
+import Main from './Main';
+import Rightside from './Rightside';
+import { Redirect } from 'react-router-dom';
+import { connect } from 'react-redux';
+
const Home = (props) => {
- return (
-
-
-
-
- Find talented pros in record time with Upwork and keep business
- moving.
-
-
-
-
-
-
-
-
- );
-};
+ return (
+
+ {!props.user && }
+
+
+ Find talents in record time with LinkedIn Premium and unlock special benefits!
+
+
+
+
+
+
+
+
+ );
+}
const Container = styled.div`
- padding-top: 52px;
- max-width: 100%;
+ padding-top: 52px;
+ max-width: 100%;
`;
const Content = styled.div`
- max-width: 1128px;
- margin-left: auto;
- margin-right: auto;
+ max-width: 1120px;
+ margin-left: auto;
+ margin-right: auto;
`;
const Section = styled.section`
- min-height: 50px;
- padding: 16px 0;
- box-sizing: content-box;
- text-align: center;
- text-decoration: underline;
- display: flex;
- justify-content: center;
- h5 {
- color: #0a66c2;
- font-size: 14px;
- a {
- font-weight: 700;
+ min-height: 50px;
+ padding: 16px 0;
+ box-sizing: content-box;
+ text-align: center;
+ text-decoration: underline;
+ display: flex;
+ justify-content: center;
+
+ h5 {
+ color: #0a66c2;
+ font-size: 14px;
+
+ a {
+ font-weight: 700;
+ }
}
- }
- p {
- font-size: 14px;
- color: #434649;
- font-weight: 600;
- }
+ p {
+ font-size: 14px;
+ color: #434649;
+ font-weight: 600;
+ }
- @media (max-width: 768px) {
- flex-direction: column;
- padding: 0 5px;
- }
+ @media (max-width: 768px) {
+ flex-direction: column;
+ padding: 0 5px;
+ }
`;
const Layout = styled.div`
- display: grid;
- grid-template-areas: "leftside main rightside";
- grid-template-columns: minmax(0, 5fr) minmax(0, 12fr) minmax(300px, 7fr);
- column-gap: 25px;
- row-gap: 25px;
- /* grid-template-row: auto; */
- margin: 25px 0;
- @media (max-width: 768px) {
- display: flex;
- flex-direction: column;
- padding: 0 5px;
- }
+ display: grid;
+ grid-template-areas: "leftside main rightside";
+ grid-template-columns: minmax(0,5fr) minmax(0,12fr) minmax(300px,7fr);
+ column-gap: 25px;
+ row-gap: 25px;
+ margin: 25px 0;
+ /*grid-template-row: auto;*/
+
+ @media (max-width: 768px) {
+ display: flex;
+ flex-direction: column;
+ padding: 0 5px;
+ }
`;
-export default Home;
+const mapStateToProps = (state) => {
+ return {
+ user: state.userState.user,
+ };
+};
+
+export default connect(mapStateToProps)(Home);
\ No newline at end of file
diff --git a/src/components/Leftside.js b/src/components/Leftside.js
index b447259a..5516acb2 100644
--- a/src/components/Leftside.js
+++ b/src/components/Leftside.js
@@ -1,208 +1,225 @@
-import styled from "styled-components";
+import styled from 'styled-components';
+import { connect } from 'react-redux';
const Leftside = (props) => {
- return (
-
-
-
-
-
-
- Welcome, there!
-
-
- Add a photo
-
-
-
-
-
- Connections
- Grow your network
-
-
-
-
- -
-
-
- My Items
-
-
-
-
-
-
- Groups
-
-
-
- Events
-
-
-
-
- Follow Hashtags
-
-
- Discover more
-
-
-
- );
+ return (
+
+
+
+
+
+
+
+ Welcome, {props.user ? props.user.displayName : "there"}!
+
+
+
+
+
+
+
+
+
+
+ Connections
+ Grow your network
+
+
+
+
+
+ -
+
+
+ My Items
+
+
+
+
+
+
+ Groups
+
+
+
+ Events
+
+
+
+
+ Follow Hashtags
+
+
+ Discover more
+
+
+
+ );
};
const Container = styled.div`
- grid-area: leftside;
+ grid-area: leftside;
`;
const ArtCard = styled.div`
- text-align: center;
- overflow: hidden;
- margin-bottom: 8px;
- background-color: #fff;
- border-radius: 5px;
- transition: box-shadow 83ms;
- position: relative;
- border: none;
- box-shadow: 0 0 0 1px rgb(0 0 0 / 15%), 0 0 0 rgb(0 0 0 / 20%);
+ text-align: center;
+ overflow: hidden;
+ margin-bottom: 8px;
+ background-color: #ffffff;
+ border-radius: 5px;
+ transition: box-shadow 83ms;
+ position: relative;
+ border: none;
+ box-shadow: 0 0 0 1px rgb(0 0 0 / 15%), 0 0 0 rgb(0 0 0 / 20%);
`;
const UserInfo = styled.div`
- border-bottom: 1px solid rgba(0, 0, 0, 0.15);
- padding: 12px 12px 16px;
- word-wrap: break-word;
- word-break: break-word;
+ border-bottom: 1px solid rgba(0,0,0,0.15);
+ padding: 12px 12px 16px;
+ word-wrap: break-word;
+ word-break: break-word;
`;
const CardBackground = styled.div`
- background: url("/images/card-bg.svg");
- background-position: center;
- background-size: 462px;
- height: 54px;
- margin: -12px -12px 0;
+ background: url('/images/card-bg.svg');
+ background-position: center;
+ background-size: 462px;
+ height: 54px;
+ margin: -12px -12px 0;
`;
const Photo = styled.div`
- box-shadow: none;
- background-image: url("/images/photo.svg");
- width: 72px;
- height: 72px;
- box-sizing: border-box;
- background-clip: content-box;
- background-color: white;
- background-position: center;
- background-size: 60%;
- background-repeat: no-repeat;
- border: 2px solid white;
- margin: -38px auto 12px;
- border-radius: 50%;
+ box-shadow: none;
+ background-image: url('/images/photo.svg');
+ width: 72px;
+ height: 72px;
+ box-sizing: border-box;
+ background-clip: content-box;
+ background-color: #ffffff;
+ background-position: center;
+ background-size: 60%;
+ background-repeat: no-repeat;
+ border: 2px solid #ffffff;
+ margin : -38px auto 12px;
+ border-radius: 50%;
`;
const Link = styled.div`
- font-size: 16px;
- line-height: 1.5;
- color: rgba(0, 0, 0, 0.9);
- font-weight: 600;
+ font-size: 16px;
+ line-height: 16px;
+ color: rgba(0,0,0,0.9);
+ font-weight: 600;
`;
const AddPhotoText = styled.div`
- color: #0a66c2;
- margin-top: 4px;
- font-size: 12px;
- line-height: 1.33;
- font-weight: 400;
+ color: #0a66c2;
+ margin-top: 4px;
+ font-size: 12px;
+ line-height: 1.33;
+ font-weight: 400;
`;
const Widget = styled.div`
- border-bottom: 1px solid rgba(0, 0, 0, 0.15);
- padding-top: 12px;
- padding-bottom: 12px;
+ border-bottom: 1px solid rgba(0,0,0,0.15);
+ padding-top: 12px;
+ padding-bottom: 12px;
+
+ & > a {
+ text-decoration: none;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 4px 12px;
+
+ &:hover {
+ background-color: rgba(0,0,0,0.08);
+ }
- & > a {
- text-decoration: none;
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 4px 12px;
+ div {
+ display: flex;
+ flex-direction: column;
+ text-align: left;
- &:hover {
- background-color: rgba(0, 0, 0, 0.08);
- }
+ span {
+ font-size: 12px;
+ line-height: 1.333;
- div {
- display: flex;
- flex-direction: column;
- text-align: left;
- span {
- font-size: 12px;
- line-height: 1.333;
- &:first-child {
- color: rgba(0, 0, 0, 0.6);
- }
- &:nth-child(2) {
- color: rgba(0, 0, 0, 1);
+ &:first-child {
+ color: rgba(0, 0, 0, 0.6);
+ }
+
+ &:nth-child(2) {
+ color: rgba(0, 0, 0, 1);
+ }
+ }
}
- }
}
- }
- svg {
- color: rgba(0, 0, 0, 1);
- }
+ svg {
+ color: rgba(0, 0, 0, 1);
+ }
`;
const Item = styled.a`
- border-color: rgba(0, 0, 0, 0.8);
- text-align: left;
- padding: 12px;
- font-size: 12px;
- display: block;
- span {
- display: flex;
- align-items: center;
- color: rgba(0, 0, 0, 1);
- svg {
- color: rgba(0, 0, 0, 0.6);
+ border-color: rgba(0, 0, 0, 0.8);
+ text-align: left;
+ padding: 12px;
+ font-size: 12px;
+ display: block;
+
+ span {
+ display: flex;
+ align-items: center;
+ color: rgba(0, 0, 0, 1);
+
+ svg {
+ color: rgba(0, 0, 0, 0.6);
+ }
}
- }
- &:hover {
- background-color: rgba(0, 0, 0, 0.08);
- }
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.08);
+ }
`;
const CommunityCard = styled(ArtCard)`
- padding: 8px 0 0;
- text-align: left;
- display: flex;
- flex-direction: column;
- a {
- color: black;
- padding: 4px 12px 4px 12px;
- font-size: 12px;
+ padding: 8px 0 0;
+ text-align: left;
+ display: flex;
+ flex-direction: column;
- &:hover {
- color: #0a66c2;
- }
+ a {
+ color: #000000;
+ padding: 4px 12px;
+ font-size: 12px;
- span {
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
+ &:hover {
+ color: #0a66c2;
+ }
- &:last-child {
- color: rgba(0, 0, 0, 0.6);
- text-decoration: none;
+ span {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
- border-top: 1px solid #d6cec2;
- padding: 12px;
- &:hover {
- background-color: rgba(0, 0, 0, 0.08);
- }
+ &:last-child {
+ color: rgba(0,0,0,0.6);
+ text-decoration: none;
+ border-top: 1px solid #d6cec2;
+ padding: 12px;
+
+ &:hover {
+ background-color: rgba(0,0,0,0.08);
+ }
+ }
}
- }
`;
-export default Leftside;
+const mapStateToProps = (state) => {
+ return {
+ user: state.userState.user,
+ };
+};
+
+export default connect(mapStateToProps)(Leftside);
\ No newline at end of file
diff --git a/src/components/Login.js b/src/components/Login.js
index 10bf7e8b..b93a4f92 100644
--- a/src/components/Login.js
+++ b/src/components/Login.js
@@ -1,169 +1,196 @@
import styled from "styled-components";
+import { connect } from 'react-redux';
+import { signInAPI } from '../actions';
+import { Redirect } from 'react-router';
const Login = (props) => {
- return (
-
-
-
-
-
-
- Join now
- Sign in
-
-
-
-
- Welcome to your professional community
-
-
-
-
-
- );
+ return (
+
+ {
+ props.user &&
+
+ }
+
+
+
+
+
+ Join Now
+ Sign In
+
+
+
+
+
+ Welcome to your professional community
+
+
+
+
+
+
+ );
};
const Container = styled.div`
- padding: 0px;
+ padding: 0px;
`;
const Nav = styled.nav`
- max-width: 1128px;
- margin: auto;
- padding: 12px 0 16px;
- display: flex;
- align-items: center;
- position: relative;
- justify-content: space-between;
- flex-wrap: nowrap;
-
- & > a {
- width: 135px;
- height: 34px;
- @media (max-width: 768px) {
- padding: 0 5px;
+ max-width: 1128px;
+ margin: auto;
+ padding: 12px 0 16px 0;
+ display: flex;
+ align-items: center;
+ position: relative;
+ justify-content: space-between;
+ flex-wrap: nowrap;
+
+ & > a {
+ width: 135px;
+ height: 34px;
+
+ @media (max-width: 768px) {
+ padding: 0 5px;
+ }
}
- }
`;
const Join = styled.a`
- font-size: 16px;
- padding: 10px 12px;
- text-decoration: none;
- border-radius: 4px;
- color: rgba(0, 0, 0, 0.6);
- margin-right: 12px;
- &:hover {
- background-color: rgba(0, 0, 0, 0.08);
- color: rgba(0, 0, 0, 0.9);
+ font-size: 16px;
+ padding: 10px 12px;
text-decoration: none;
- }
+ color: rgba(0, 0, 0, 0.6);
+ margin-right: 12px;
+ font-weight: 600;
+ border-radius: 4px;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.08);
+ color: rgba(0, 0, 0, 0.9);
+ text-decoration: none;
+ cursor: pointer;
+ }
`;
const SignIn = styled.a`
- box-shadow: inset 0 0 0 1px #0a66c2;
- color: #0a66c2;
- border-radius: 24px;
- transition-duration: 167ms;
- font-size: 16px;
- font-weight: 600;
- line-height: 40px;
- padding: 10px 24px;
- text-align: center;
- background-color: rgba(0, 0, 0, 0);
- &:hover {
- background-color: rgba(112, 181, 249, 0.15);
+ box-shadow: inset 0 0 0 1px #0a66c2;
color: #0a66c2;
- text-decoration: none;
- }
+ border-radius: 24px;
+ transition-duration: 167ms;
+ font-size: 16px;
+ font-weight: 600;
+ line-height: 40px;
+ padding: 12px 23px;
+ text-align: center;
+ background-color: rgba(0, 0, 0, 0);
+
+ &:hover {
+ background-color: rgba(112, 181, 249, 0.15);
+ color: #0a66c2;
+ text-decoration: none;
+ cursor: pointer;
+ box-shadow: inset 0 0 0 2px #0a66c2;
+ }
`;
const Section = styled.section`
- display: flex;
- align-content: start;
- min-height: 700px;
- padding-bottom: 138px;
- padding-top: 40px;
- padding: 60px 0;
- position: relative;
- flex-wrap: wrap;
- width: 100%;
- max-width: 1128px;
- align-items: center;
- margin: auto;
-
- @media (max-width: 768px) {
+ display: flex;
+ align-content: start;
+ min-height: 700px;
+ padding-bottom: 138px;
+ padding-top: 40px;
+ padding: 60px 0;
+ position: relative;
+ flex-wrap: wrap;
+ width: 100%;
+ align-items: center;
margin: auto;
- min-height: 0px;
- }
+
+ @media (max-width: 768px) {
+ margin: auto;
+ min-height: 0px;
+ }
`;
const Hero = styled.div`
- width: 100%;
- h1 {
- padding-bottom: 0;
- width: 55%;
- font-size: 56px;
- color: #2977c9;
- font-weight: 200;
- line-height: 70px;
- @media (max-width: 768px) {
- text-align: center;
- font-size: 20px;
- width: 100%;
- line-height: 2;
+ width: 100%;
+ h1 {
+ padding-bottom: 0;
+ width: 55%;
+ font-size: 53px;
+ color: #2977c9;
+ font-weight: 200;
+ line-height: 70px;
+
+ @media (max-width: 768px) {
+ text-align: center;
+ font-size: 20px;
+ width: 100%;
+ width: 100%;
+ line-height: 2;
+ }
}
- }
-
- img {
- /* z-index: -1; */
- width: 700px;
- height: 670px;
- position: absolute;
- bottom: -2px;
- right: -150px;
- @media (max-width: 768px) {
- top: 230px;
- width: initial;
- position: initial;
- height: initial;
+
+ img {
+ /*z-index: -1;*/
+ width: 700px;
+ height: 670px;
+ position: absolute;
+ bottom: -2px;
+ right: -150px;
+
+ @media (max-width: 768px) {
+ top: 230px;
+ width: initial;
+ position: initial;
+ height: initial;
+ }
}
- }
`;
const Form = styled.div`
- margin-top: 100px;
- width: 408px;
- @media (max-width: 768px) {
- margin-top: 20px;
- }
+ margin-top: 100px;
+ width: 408px;
+ @media (max-width: 768px) {
+ margin-top: 20px;
+ }
`;
const Google = styled.button`
- display: flex;
- justify-content: center;
- background-color: #fff;
- align-items: center;
- height: 56px;
- width: 100%;
- border-radius: 28px;
- box-shadow: inset 0 0 0 1px rgb(0 0 0 / 60%),
- inset 0 0 0 2px rgb(0 0 0 / 0%) inset 0 0 0 1px rgb(0 0 0 / 0);
-
- vertical-align: middle;
- z-index: 0;
- transition-duration: 167ms;
- font-size: 20px;
- color: rgba(0, 0, 0, 0.6);
- &:hover {
- background-color: rgba(207, 207, 207, 0.25);
- color: rgba(0, 0, 0, 0.75);
- }
+ display: flex;
+ justify-content: center;
+ background-color: #fff;
+ align-items: center;
+ height: 56px;
+ width: 100%;
+ border-radius: 28px;
+ box-shadow: inset 0 0 0 1px rgba(0 0 0 / 60%), inset 0 0 0 2px rgb(0 0 0 / 0%) inset 0 0 0 1px rgb(0 0 0 / 0%);
+ vertical-align: middle;
+ z-index: 0;
+ transition-duration: 167ms;
+ font-size: 20px;
+ color: rgba(0, 0 , 0, 0.6);
+
+ &:hover {
+ background-color: rgba(207, 207, 207, 0.25);
+ color: rgba(0, 0, 0, 0.75);
+ cursor: pointer;
+ }
`;
-export default Login;
+const mapStateToProps = (state) => {
+ return {
+ user: state.userState.user,
+ };
+};
+
+const mapDispatchToProps = (dispatch) => ({
+ signIn: () => dispatch(signInAPI()),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(Login);
\ No newline at end of file
diff --git a/src/components/Main.js b/src/components/Main.js
index fd6e2d54..555a10e2 100644
--- a/src/components/Main.js
+++ b/src/components/Main.js
@@ -1,11 +1,406 @@
-import styled from "styled-components";
+import { useEffect, useState } from 'react';
+import styled from 'styled-components';
+import PostModal from './PostModal';
+import ReactPlayer from 'react-player';
+import { connect } from 'react-redux';
+import { getArticlesAPI } from '../actions';
const Main = (props) => {
- return Main;
+ const [showModal, setShowModal] = useState("close");
+
+ useEffect(() => {
+ props.getArticles()
+ }, []);
+
+ const handleClick = (e) => {
+ e.preventDefault();
+ if(e.target !== e.currentTarget) {
+ return;
+ }
+
+ switch(showModal) {
+ case "open":
+ setShowModal("close");
+ break;
+ case "close":
+ setShowModal("open");
+ break;
+ default:
+ setShowModal("close");
+ break;
+ }
+ }
+
+ return (
+ // <>
+ // { props.articles.length === 0 ? (
+ // No articles to show.
+ // ) :
+ // (
+
+
+
+ { props.user && props.user.photoURL ?
+ (

)
+ :
+ (

)
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ props.loading &&
+ }
+ {
+ props.articles.length != 0 &&
+ props.articles.map((article, key) => (
+
+
+
+
+
+
+ {article.actor.title}
+ {article.actor.description}
+ {article.actor.date.toDate().toLocaleDateString()}
+
+
+
+
+
+
+ {article.description}
+
+
+
+ {
+ !article.sharedImg && article.video ?
+ ()
+ :
+ (
+ article.sharedImg &&
+ )
+ }
+
+
+
+
+
+
+
+
+ {article.comments} comments
+
+
+
+
+
+
+
+
+
+
+
+ ))
+ }
+
+
+
+
+ // )
+ // }
+ // >
+ );
};
const Container = styled.div`
- grid-area: main;
+ grid-area: main;
`;
-export default Main;
+const CommonCard = styled.div`
+ text-align: center;
+ overflow: hidden;
+ margin-bottom: 8px;
+ background-color: #fff;
+ border-radius: 5px;
+ position: relative;
+ border: none;
+ border-radius: 0 0 0 1px rgb(0 0 0 / 15%), 0 0 0 rgb(0 0 0 / 20%);
+`;
+
+const ShareBox = styled(CommonCard)`
+ display: flex;
+ flex-direction: column;
+ color: #958b7b;
+ margin: 0 0 8px 0;
+ background: #fff;
+
+ div {
+ button {
+ outline: none;
+ color: rgba(0,0,0,0.6);
+ font-size: 14px;
+ line-height: 1.5;
+ min-height: 48px;
+ background: transparent;
+ border: none;
+ display: flex;
+ align-items: center;
+ font-weight: 600;
+
+ &:hover {
+ background-color: rgba(0,0,0,0.07);
+ border-radius: 6px;
+ }
+ }
+
+ .post-space {
+ box-shadow: 1px 1px 2px 1px rgba(159,156,156,0.75);
+ }
+
+ .post-icon {
+ width: 27px;
+ }
+
+ &:first-child {
+ display: flex;
+ align-items: center;
+ padding: 8px 16px;
+
+ img {
+ width: 48px;
+ margin-right: 8px;
+ border-radius: 50%;
+ }
+
+ button {
+ margin: 4px 0;
+ flex-grow: 1;
+ border-radius: 35px;
+ padding-left: 16px;
+ border: 1px solid rgba(0,0,0,0,15);
+ border-radius: 35px;
+ background-color: #fff;
+ text-align: left;
+ }
+ }
+
+ &:nth-child(2) {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-around;
+ padding-bottom: 4px;
+
+ button {
+ img {
+ margin: 0 4px 0 -2px;
+ }
+
+ span {
+ color: #70b5f9;
+ }
+ }
+ }
+ }
+`;
+
+const Article = styled(CommonCard)`
+ padding: 0;
+ margin: 0 0 8px;
+ overflow: visible;
+`;
+
+const SharedActor = styled.div`
+ padding-right: 40px;
+ flex-wrap: nowrap;
+ padding: 12px 16px 0;
+ margin-bottom: 8px;
+ align-items: center;
+ display: flex;
+
+ a {
+ margin-right: 12px;
+ flex-grow: 1;
+ overflow: hidden;
+ display: flex;
+ text-decoration: none;
+
+ img {
+ width: 48px;
+ height: 48px;
+ }
+
+ & > div {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ flex-basis: 0;
+ margin-left: 8px;
+ overflow: hidden;
+
+ span {
+ text-align: left;
+
+ &:first-child {
+ font-size: 14px;
+ font-weight: 700;
+ color: rgba(0, 0, 0, 1);
+ }
+
+ &:nth-child(n+1) {
+ font-size: 12px;
+ color: rgba(0,0,0,0.6);
+ }
+ }
+ }
+ }
+
+ button {
+ position: absolute;
+ right: 12px;
+ outline: none;
+ border: none;
+ top: 0;
+ background: transparent;
+ }
+`;
+
+const Description = styled.div`
+ padding: 0 16px;
+ overflow: hidden;
+ color: rgba(0,0,0,0.9);
+ font-size: 14px;
+ text-align: left;
+`;
+
+const SharedImage = styled.div`
+ margin-top: 8px;
+ width: 100%;
+ display: block;
+ position: relative;
+ background-color: #f9fafb;
+
+ img {
+ object-fit: contain;
+ width: 100%;
+ height: 100%;
+ }
+`;
+
+const SocialCounts = styled.ul`
+ line-height: 100%;
+ display: flex;
+ align-items: flex-start;
+ overflow: auto;
+ list-style: none;
+ margin: 0 16px;
+ padding: 8px 0;
+ border-bottom: 1px solid #e9e5df;
+
+ li {
+ margin-right: 5px;
+ font-size: 12px;
+
+ button {
+ display: flex;
+ border: none;
+ background: #fff;
+ }
+ }
+
+ img {
+ width: 18px;
+ }
+`;
+
+const SocialActions = styled.div`
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ margin: 0;
+ min-height: 40px;
+ padding: 4px 8px;
+
+ button {
+ display: inline-flex;
+ align-items: center;
+ padding: 8px;
+ color: #0a66c2;
+ border: none;
+ background-color: #fff;
+
+ @media (min-width: 768px) {
+ span {
+ margin-left: 8px;
+ }
+ }
+ }
+`;
+
+const Content = styled.div`
+ text-align: center;
+ & > img {
+ width: 30px;
+ }
+`;
+
+const mapStateToProps = (state) => {
+ return {
+ loading: state.articleState.loading,
+ user: state.userState.user,
+ articles: state.articleState.articles,
+ }
+}
+
+const mapDispatchToProps = (dispatch) => ({
+ getArticles: () => dispatch(getArticlesAPI()),
+})
+
+export default connect(mapStateToProps, mapDispatchToProps) (Main);
\ No newline at end of file
diff --git a/src/components/PostModal.js b/src/components/PostModal.js
new file mode 100644
index 00000000..8e57e3a2
--- /dev/null
+++ b/src/components/PostModal.js
@@ -0,0 +1,327 @@
+import { useState } from 'react';
+import styled from 'styled-components';
+import ReactPlayer from 'react-player';
+import { connect } from 'react-redux';
+import firebase from 'firebase';
+import { postArticleAPI } from '../actions';
+
+const PostModal = (props) => {
+ const [editorText, setEditorText] = useState('');
+ const [sharedImage, setSharedImage] = useState('');
+ const [videoLink, setVideoLink] = useState('');
+ const [assetArea, setAssetArea] = useState('');
+
+ const handleChange = (e) => {
+ const image = e.target.files[0];
+
+ if(image === '' || image === undefined)
+ {
+ alert(`not an image, the file is a ${typeof image}`);
+ return;
+ }
+ setSharedImage(image);
+ };
+
+ const switchAssetArea = (area) => {
+ setSharedImage('');
+ setVideoLink('');
+ setAssetArea(area);
+ };
+
+ const postArticle = (e) => {
+ e.preventDefault();
+ if(e.target !== e.currentTarget)
+ {
+ return;
+ }
+
+ const payload = {
+ image: sharedImage,
+ video: videoLink,
+ user: props.user,
+ description: editorText,
+ timestamp: firebase.firestore.Timestamp.now(),
+ };
+
+ props.postArticle(payload);
+ reset(e);
+ };
+
+ const reset = (e) => {
+ setEditorText("");
+ setSharedImage('');
+ setVideoLink('');
+ setAssetArea('');
+ props.handleClick(e);
+ }
+
+ return (
+ <>
+ { props.showModal === "open" &&
+
+
+
+ Create a post
+
+
+
+
+
+ {props.user.photoURL ? (
+
+ ) : (
+
+ )}
+
+ {props.user.displayName}
+
+
+
+
+
+
+
+
+
+ switchAssetArea('image')}>
+
+
+ switchAssetArea('media')}>
+
+
+
+
+
+
+
+ Anyone
+
+
+
+ postArticle(event)} >
+ Post
+
+
+
+
+
+ }
+ >
+ );
+};
+
+const Container = styled.div`
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 9999;
+ color: #000000;
+ background-color: rgba(0,0,0,0.8);
+ animation: fadeIn 0.3s;
+`;
+
+const Content = styled.div`
+ width: 100%;
+ max-width: 552px;
+ background-color: #fff;
+ max-height: 90%;
+ overflow: initial;
+ border-radius: 5px;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ top: 32px;
+ margin: 0 auto;
+`;
+
+const Header = styled.div`
+ display: block;
+ padding: 16px 28px;
+ border-bottom: 1px solid rgba(0,0,0,0.15);
+ font-size: 16px;
+ line-height: 1.5;
+ color: rgba(0,0,0,0.6);
+ font-weight: 400;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ button {
+ height: 48px;
+ width: 40px;
+ min-width: auto;
+ color: rgba(0,0,0,0.15);
+
+ img {
+ pointer-events: none;
+ }
+ }
+`;
+
+const SharedContent = styled.div`
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ overflow-y: auto;
+ vertical-align: baseline;
+ background: transparent;
+ padding: 8px 12px;
+`;
+
+const UserInfo = styled.div`
+ display: flex;
+ align-items: center;
+ padding: 12px 24px;
+
+ svg,img {
+ width: 48px;
+ height: 48px;
+ background-clip: content-box;
+ border: 2px solid transparent;
+ border-radius: 50%;
+ margin-right: 5px;
+ }
+
+ span {
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 1.5;
+ }
+`;
+
+const SharedCreation = styled.div`
+ display: flex;
+ justify-content: space-between;
+ padding: 12px 24px 12px 16px;
+`;
+
+const AssetButton = styled.button`
+ display: flex;
+ align-items: center;
+ height: 40px;
+ min-width: auto;
+ color: rgba(0,0,0,0.5);
+`;
+
+const AttachAssets = styled.div`
+ align-items: center;
+ display: flex;
+ padding-right: 8px;
+
+ ${AssetButton} {
+ width: 40px;
+ }
+`;
+
+const ShareComment = styled.div`
+ padding-left: 8px;
+ margin-right: auto;
+ border-left: 1px solid rgba(0,0,0,0.15);
+
+ ${AssetButton} {
+ img {
+ margin-right: 5px;
+ }
+ }
+`;
+
+const PostButton = styled.button`
+ min-width: 60px;
+ border-radius: 20px;
+ padding-left: 16px;
+ padding-right: 16px;
+ background: ${props => props.disabled ? 'rgba(0,0,0,0.5)' : '#0a66c2'};
+ color: ${props => props.disabled ? 'rgba(1,1,1,0.2)' : '#fff'};
+
+ &:hover {
+ background: ${props => props.disabled ? 'rgba(0,0,0,0.08)' : '#004182'};
+ cursor: ${props => props.disabled ? 'none' : 'pointer'};
+ outline: none !important;
+ }
+`;
+
+const Editor = styled.div`
+ padding: 12px 24px;
+
+ textarea {
+ width: 100%;
+ min-height: 100px;
+ resize: none;
+ }
+
+ input {
+ width: 100%;
+ height: 35px;
+ font-size: 16px;
+ margin-bottom: 20px;
+ }
+`;
+
+const UploadImage = styled.div`
+ text-align: center;
+
+ img {
+ width: 100%;
+ }
+`;
+
+const mapStateToProps = (state) => {
+ return {
+ user: state.userState.user,
+ };
+};
+
+const mapDispatchToProps = (dispatch) => ({
+ postArticle: (payload) => dispatch(postArticleAPI(payload)),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps) (PostModal);
\ No newline at end of file
diff --git a/src/components/Rightside.js b/src/components/Rightside.js
index 8778f809..606cbb79 100644
--- a/src/components/Rightside.js
+++ b/src/components/Rightside.js
@@ -1,129 +1,134 @@
-import styled from "styled-components";
+import styled from 'styled-components';
const Rightside = (props) => {
- return (
-
-
-
- Add to your feed
-
-
+ return (
+
+
+
+ Add to your feed
+
+
-
-
-
-
-
-
- #Linkedin
-
-
-
-
-
-
-
-
- #Video
-
-
-
-
+
+
+
+
+
+
+ #LinkedIn
+
+
+
+
+
+
+
+
+ #Video
+
+
+
+
-
- View all recommendations
-
-
-
-
-
-
-
- );
+
+ View all recommendations
+
+
+
+
+
+
+
+
+ );
};
const Container = styled.div`
- grid-area: rightside;
+ grid-area: rightside;
`;
const FollowCard = styled.div`
- text-align: center;
- overflow: hidden;
- margin-bottom: 8px;
- background-color: #fff;
- border-radius: 5px;
- position: relative;
- border: none;
- box-shadow: 0 0 0 1px rgb(0 0 0 / 15%), 0 0 0 rgb(0 0 0 / 20%);
- padding: 12px;
+ text-align: center;
+ overflow: hidden;
+ margin-bottom: 8px;
+ background-color: #fff;
+ border-radius: 5px;
+ position: relative;
+ border: none;
+ box-shadow: 2px 3px 2px -2px rgba(110,104,104,0.75);
+ padding: 12px;
`;
-const Title = styled.div`
- display: inline-flex;
- align-items: center;
- justify-content: space-between;
- font-size: 16px;
- width: 100%;
- color: rgba(0, 0, 0, 0.6);
+const Title =styled.div`
+ display: inline-flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: 16px;
+ width: 100%;
+ color: rgba(0, 0, 0, 0.6);
`;
const FeedList = styled.ul`
- margin-top: 16px;
- li {
- display: flex;
- align-items: center;
- margin: 12px 0;
- position: relative;
- font-size: 14px;
- & > div {
- display: flex;
- flex-direction: column;
- }
+ margin-top: 16px;
+
+ li {
+ display: flex;
+ align-items: center;
+ margin: 12px;
+ position: relative;
+ font-size: 14px;
+
+ & > div {
+ display: flex;
+ flex-direction: column;
+ }
- button {
- background-color: transparent;
- color: rgba(0, 0, 0, 0.6);
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.6);
- padding: 16px;
- align-items: center;
- border-radius: 15px;
- box-sizing: border-box;
- font-weight: 600;
- display: inline-flex;
- justify-content: center;
- max-height: 32px;
- max-width: 480px;
- text-align: center;
- outline: none;
+ button {
+ background-color: transparent;
+ color: rgba(0, 0, 0, 0.6);
+ box-shadow: 2px 3px 0px -2px rgba(110,104,104,0.75) inset;
+ padding: 16px;
+ align-items: center;
+ border-radius: 15px;
+ box-sizing: border-box;
+ font-weight: 600;
+ display: inline-flex;
+ justify-content: center;
+ max-height: 32px;
+ max-width: 480px;
+ text-align: center;
+ outline: none;
+
+ &:hover {
+ background-color: rgba(0,0,0,0.08);
+ cursor: pointer;
+ }
+ }
}
- }
`;
const Avatar = styled.div`
- background-image: url("https://static-exp1.licdn.com/sc/h/1b4vl1r54ijmrmcyxzoidwmxs");
- background-size: contain;
- background-position: center;
- background-repeat: no-repeat;
- width: 48px;
- height: 48px;
- margin-right: 8px;
+ background-image: url('https://static-exp1.licdn.com/sc/h/1b4vl1r54ijmrmcyxzoidwmxs');
+ background-size: contain;
+ background-position: center;
+ background-repeat: no-repeat;
+ width: 48px;
+ height: 48px;
+ margin-right: 8px;
`;
const Recommendation = styled.a`
- color: #0a66c2;
- display: flex;
- align-items: center;
- font-size: 14px;
+ color: #0a66c2;
+ display: flex;
+ align-items: center;
+ font-size: 14px;
`;
const BannerCard = styled(FollowCard)`
- img {
- width: 100%;
- height: 100%;
- }
+ img {
+ width: 100%;
+ height: 100%;
+ }
`;
-export default Rightside;
+export default Rightside;
\ No newline at end of file
diff --git a/src/firebase.js b/src/firebase.js
new file mode 100644
index 00000000..cedefb19
--- /dev/null
+++ b/src/firebase.js
@@ -0,0 +1,23 @@
+import firebase from 'firebase';
+
+// Paste your firebase details below:
+const firebaseConfig = {
+ apiKey: "-------",
+ authDomain: "---------------",
+ projectId: "-------------",
+ storageBucket: "-------",
+ messagingSenderId: "------------",
+ appId: "-------------",
+ measurementId: "-------------"
+ };
+
+
+ // No need to change anything below this line
+const firebaseApp = firebase.initializeApp(firebaseConfig);
+const db = firebaseApp.firestore();
+const auth = firebaseApp.auth();
+const provider = new firebase.auth.GoogleAuthProvider();
+const storage = firebaseApp.storage();
+
+export { auth, provider, storage };
+export default db;
\ No newline at end of file
diff --git a/src/index.css b/src/index.css
index 65646e15..09ccdefc 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,42 +1,45 @@
body {
- overflow-y: scroll;
- overflow-x: hidden;
-}
-
-:root,
-body,
-html {
- background-color: #f5f5f5;
- box-sizing: border-box;
-}
-
-div,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-header,
-html,
-i,
-img,
-label,
-li,
-nav,
-p,
-small,
-span,
-ul {
- margin: 0;
- padding: 0;
- border: 0;
- outline: none;
- font-size: 100%;
- vertical-align: baseline;
- background: transparent;
-}
-
-body {
- font-family: Arial, sans-serif;
-}
+ overflow-y: scroll;
+ overflow-x: hidden;
+ }
+
+ :root,body,html {
+ background-color: #f5f5f5;
+ box-sizing: border-box;
+ }
+
+ div,h1,h2,h3,h4,h5,h6,header,html,i,img,label,li,nav,p,small,span,ul {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: none;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+ }
+
+ body {
+ font-family: Helvetica, Arial, sans-serif;
+ }
+
+
+
+ @keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+ }
+
+ @-webkit-keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+ }
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 1bc4857e..e9a06659 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,15 +1,20 @@
-import React from "react";
-import ReactDOM from "react-dom";
-import "./index.css";
-import App from "./App";
+import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import App from './App';
+
+import { Provider } from 'react-redux';
+import store from './store';
ReactDOM.render(
-
+
+
+
,
- document.getElementById("root")
+ document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
-// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
\ No newline at end of file
diff --git a/src/reducers/articleReducer.js b/src/reducers/articleReducer.js
new file mode 100644
index 00000000..3d703053
--- /dev/null
+++ b/src/reducers/articleReducer.js
@@ -0,0 +1,25 @@
+import { SET_LOADING_STATUS, GET_ARTICLES } from '../actions/actionType';
+
+export const initState = {
+ articles: [],
+ loading: false,
+};
+
+const articleReducer = (state = initState, action) => {
+ switch(action.type) {
+ case GET_ARTICLES:
+ return {
+ ...state,
+ articles: action.payload,
+ };
+ case SET_LOADING_STATUS:
+ return {
+ ...state,
+ loading: action.status,
+ };
+ default:
+ return state;
+ }
+};
+
+export default articleReducer;
\ No newline at end of file
diff --git a/src/reducers/index.js b/src/reducers/index.js
new file mode 100644
index 00000000..731c9ea4
--- /dev/null
+++ b/src/reducers/index.js
@@ -0,0 +1,10 @@
+import { combineReducers } from 'redux';
+import userReducer from './userReducer';
+import articleReducer from './articleReducer';
+
+const rootReducer = combineReducers({
+ userState: userReducer,
+ articleState: articleReducer,
+});
+
+export default rootReducer;
\ No newline at end of file
diff --git a/src/reducers/userReducer.js b/src/reducers/userReducer.js
new file mode 100644
index 00000000..0c747870
--- /dev/null
+++ b/src/reducers/userReducer.js
@@ -0,0 +1,19 @@
+import { SET_USER } from '../actions/actionType';
+
+const INITIAL_STATE = {
+ user: null,
+};
+
+const userReducer = (state = INITIAL_STATE, action) => {
+ switch(action.type) {
+ case SET_USER:
+ return {
+ ...state,
+ user: action.user,
+ }
+ default:
+ return state;
+ }
+};
+
+export default userReducer;
\ No newline at end of file
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 00000000..6c1df437
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,7 @@
+import { createStore, applyMiddleware } from 'redux';
+import thunkMiddleware from 'redux-thunk';
+import rootReducer from '../reducers';
+
+const store = createStore(rootReducer, applyMiddleware(thunkMiddleware));
+
+export default store;
\ No newline at end of file