├── screenshot └── thumbnail.png ├── src ├── client │ ├── images │ │ ├── ic_logo.png │ │ ├── ic_banner.png │ │ ├── ic_close.png │ │ ├── ic_github.png │ │ ├── ic_facebook.png │ │ ├── ic_linkedin.png │ │ ├── ic_twitter.png │ │ ├── ic_web_site.png │ │ ├── ic_youtube.png │ │ ├── ic_down_arrow.png │ │ ├── ic_profile_img.jpg │ │ ├── ic_black_facebook.png │ │ ├── ic_black_github.png │ │ ├── ic_black_linkedin.png │ │ ├── ic_black_twitter.png │ │ ├── ic_black_youtube.png │ │ ├── ic_github_white.png │ │ ├── ic_mobile_banner.png │ │ └── ic_google_playstore.png │ ├── fonts │ │ └── FredokaOne-Regular.ttf │ ├── routes.js │ ├── index.js │ ├── store │ │ └── index.js │ ├── actions │ │ ├── constants.js │ │ └── index.js │ ├── reducers │ │ ├── index.js │ │ ├── blogsReducer.js │ │ ├── projectReducer.js │ │ └── skillSetsReducer.js │ ├── App.js │ ├── components │ │ ├── BlogsComponent.js │ │ ├── ContactsComponent.js │ │ ├── SkillSetsComponent.js │ │ ├── ProfileComponent.js │ │ ├── DashboardComponent.js │ │ └── ProjectsComponent.js │ └── css │ │ └── index.css └── server │ ├── skills │ ├── skills_schema.js │ └── skills_controller.js │ ├── blogs │ ├── blogs.js │ └── blogs_controller.js │ ├── projects │ ├── projects_controller.js │ └── projects_schema.js │ └── index.js ├── .gitignore ├── databases ├── blogs.json ├── skills.json └── projects.json ├── LICENSE ├── README.md ├── webpack.client.js ├── webpack.server.js └── package.json /screenshot/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/screenshot/thumbnail.png -------------------------------------------------------------------------------- /src/client/images/ic_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_logo.png -------------------------------------------------------------------------------- /src/client/images/ic_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_banner.png -------------------------------------------------------------------------------- /src/client/images/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_close.png -------------------------------------------------------------------------------- /src/client/images/ic_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_github.png -------------------------------------------------------------------------------- /src/client/images/ic_facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_facebook.png -------------------------------------------------------------------------------- /src/client/images/ic_linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_linkedin.png -------------------------------------------------------------------------------- /src/client/images/ic_twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_twitter.png -------------------------------------------------------------------------------- /src/client/images/ic_web_site.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_web_site.png -------------------------------------------------------------------------------- /src/client/images/ic_youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_youtube.png -------------------------------------------------------------------------------- /src/client/images/ic_down_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_down_arrow.png -------------------------------------------------------------------------------- /src/client/images/ic_profile_img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_profile_img.jpg -------------------------------------------------------------------------------- /src/client/fonts/FredokaOne-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/fonts/FredokaOne-Regular.ttf -------------------------------------------------------------------------------- /src/client/images/ic_black_facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_black_facebook.png -------------------------------------------------------------------------------- /src/client/images/ic_black_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_black_github.png -------------------------------------------------------------------------------- /src/client/images/ic_black_linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_black_linkedin.png -------------------------------------------------------------------------------- /src/client/images/ic_black_twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_black_twitter.png -------------------------------------------------------------------------------- /src/client/images/ic_black_youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_black_youtube.png -------------------------------------------------------------------------------- /src/client/images/ic_github_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_github_white.png -------------------------------------------------------------------------------- /src/client/images/ic_mobile_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_mobile_banner.png -------------------------------------------------------------------------------- /src/client/images/ic_google_playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anshumanpattnaik/reactjs-portfolio-mern-website/master/src/client/images/ic_google_playstore.png -------------------------------------------------------------------------------- /src/client/routes.js: -------------------------------------------------------------------------------- 1 | import Home from './components/DashboardComponent'; 2 | 3 | const routes = [ 4 | { 5 | path: "/", 6 | exact: true, 7 | component: Home 8 | } 9 | ]; 10 | 11 | export default routes; -------------------------------------------------------------------------------- /src/client/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { hydrate } from "react-dom"; 3 | import { BrowserRouter } from "react-router-dom"; 4 | import App from "./App"; 5 | 6 | hydrate( 7 | 8 | 9 | , 10 | document.querySelector("#root") 11 | ); -------------------------------------------------------------------------------- /src/client/store/index.js: -------------------------------------------------------------------------------- 1 | import {createStore, applyMiddleware} from "redux"; 2 | import thunk from 'redux-thunk'; 3 | import logger from 'redux-logger'; 4 | 5 | import rootReducer from '../reducers'; 6 | 7 | const middle = applyMiddleware(thunk, logger); 8 | const store = createStore(rootReducer, middle); 9 | 10 | export default store; -------------------------------------------------------------------------------- /src/client/actions/constants.js: -------------------------------------------------------------------------------- 1 | export const BASE_URL = 'http://localhost:9002'; 2 | export const SKILLS_ENDPOINT = '/api/skills'; 3 | export const PROJECTS_ENDPOINT = '/api/projects'; 4 | export const BLOGS_ENDPOINT = '/api/blogs'; 5 | 6 | export const FETCH_SKILLS_SETS = 'FETCH_SKILLS_SETS'; 7 | export const FETCH_PROJECTS = 'FETCH_PROJECTS'; 8 | export const FETCH_BLOGS = 'FETCH_BLOGS'; -------------------------------------------------------------------------------- /src/client/reducers/index.js: -------------------------------------------------------------------------------- 1 | import {combineReducers} from 'redux'; 2 | 3 | import skillSetsReducer from './skillSetsReducer'; 4 | import projectReducer from './projectReducer'; 5 | import blogsReducer from './blogsReducer'; 6 | 7 | const rootReducer = combineReducers({ 8 | skills: skillSetsReducer, 9 | projects: projectReducer, 10 | blogs: blogsReducer 11 | }); 12 | 13 | export default rootReducer; -------------------------------------------------------------------------------- /src/server/skills/skills_schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const skillsSchema = new mongoose.Schema({ 3 | tech_stack: { 4 | type: String, 5 | text: true, 6 | required: true 7 | }, 8 | label: { 9 | type: String, 10 | text: true, 11 | required: true 12 | }, 13 | skills: [{ 14 | type: String 15 | }] 16 | }); 17 | module.exports = mongoose.model("Skills", skillsSchema); -------------------------------------------------------------------------------- /src/server/blogs/blogs.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const blogSchema = new mongoose.Schema({ 3 | title: { 4 | type: String, 5 | text: true, 6 | required: true 7 | }, 8 | blog_link: { 9 | type: String, 10 | text: true, 11 | required: true 12 | }, 13 | thumbnail: { 14 | type: String, 15 | text: true, 16 | required: true 17 | } 18 | }); 19 | module.exports = mongoose.model("Blogs", blogSchema); -------------------------------------------------------------------------------- /src/server/blogs/blogs_controller.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | var mongoose = require("mongoose"); 4 | 5 | var Blogs = require("./blogs"); 6 | mongoose.connect("mongodb://127.0.0.1:27017/portfolio"); 7 | 8 | router.get("/", (req, res) => { 9 | Blogs.find({}, function(err, results) { 10 | if (err) return; 11 | res.json(results); 12 | }); 13 | }); 14 | 15 | module.exports = router; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | yarn.lock 25 | package-lock.json 26 | -------------------------------------------------------------------------------- /src/server/skills/skills_controller.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | var mongoose = require("mongoose"); 4 | 5 | var Skills = require("./skills_schema"); 6 | mongoose.connect("mongodb://127.0.0.1:27017/portfolio"); 7 | 8 | router.get("/", (req, res) => { 9 | Skills.find({}, function(err, results) { 10 | if (err) return; 11 | res.json(results); 12 | }); 13 | }); 14 | 15 | module.exports = router; -------------------------------------------------------------------------------- /src/server/projects/projects_controller.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | var mongoose = require("mongoose"); 4 | 5 | var Projects = require("./projects_schema"); 6 | mongoose.connect("mongodb://127.0.0.1:27017/portfolio"); 7 | 8 | router.get("/", (req, res) => { 9 | Projects.find({}, function(err, results) { 10 | if (err) return; 11 | res.json(results); 12 | }); 13 | }); 14 | 15 | module.exports = router; -------------------------------------------------------------------------------- /src/client/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Switch, Route } from 'react-router-dom'; 3 | import routes from "./routes"; 4 | 5 | import store from './store'; 6 | import { Provider } from 'react-redux' 7 | 8 | class App extends React.Component { 9 | render() { 10 | return ( 11 | 12 | 13 | {routes.map((route, i) => ( 14 | 15 | ))} 16 | 17 | 18 | ); 19 | } 20 | } 21 | 22 | export default App; -------------------------------------------------------------------------------- /src/client/reducers/blogsReducer.js: -------------------------------------------------------------------------------- 1 | import { FETCH_BLOGS } from '../actions/constants'; 2 | 3 | const initialState = { 4 | data: '', 5 | }; 6 | 7 | const blogsReducer = (state = initialState, action) => { 8 | switch (action.type) { 9 | case FETCH_BLOGS: { 10 | const newState = { 11 | ...state, 12 | data: action.payload, 13 | }; 14 | return newState; 15 | } 16 | default: 17 | return state; 18 | } 19 | }; 20 | 21 | export default blogsReducer; -------------------------------------------------------------------------------- /src/client/reducers/projectReducer.js: -------------------------------------------------------------------------------- 1 | import { FETCH_PROJECTS } from '../actions/constants'; 2 | 3 | const initialState = { 4 | data: '', 5 | }; 6 | 7 | const projectReducer = (state = initialState, action) => { 8 | switch (action.type) { 9 | case FETCH_PROJECTS: { 10 | const newState = { 11 | ...state, 12 | data: action.payload, 13 | }; 14 | return newState; 15 | } 16 | default: 17 | return state; 18 | } 19 | }; 20 | 21 | export default projectReducer; -------------------------------------------------------------------------------- /src/client/reducers/skillSetsReducer.js: -------------------------------------------------------------------------------- 1 | import { FETCH_SKILLS_SETS } from '../actions/constants'; 2 | 3 | const initialState = { 4 | data: '', 5 | }; 6 | 7 | const skillSetsReducer = (state = initialState, action) => { 8 | switch (action.type) { 9 | case FETCH_SKILLS_SETS: { 10 | const newState = { 11 | ...state, 12 | data: action.payload, 13 | }; 14 | return newState; 15 | } 16 | default: 17 | return state; 18 | } 19 | }; 20 | 21 | export default skillSetsReducer; -------------------------------------------------------------------------------- /databases/blogs.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "title": "10 Recon Tools For Bug Bounty", 3 | "thumbnail": "https://assets.hackbotone.com/images/top_10_recon_tools_for_bug_bounty/Thumbnail.jpg", 4 | "blog_link": "https://hackbotone.com/blog/10-recon-tools-for-bug-bounty" 5 | },{ 6 | "title": "Coronavirus (COVID-19) - Full Stack Application", 7 | "thumbnail": "https://assets.hackbotone.com/images/coronavirus_covid_19_full_stack_application/Thumbnail.png", 8 | "blog_link": "https://hackbotone.com/blog/covid-19-full-stack-application" 9 | },{ 10 | "title": "Cross-Site-Scripting — Reflected (JSON)", 11 | "thumbnail": "https://assets.hackbotone.com/images/cross_site_scripting_reflected_json/cross_site_scripting_reflected_json.png", 12 | "blog_link": "https://hackbotone.com/blog/cross-site-scripting-reflected-json" 13 | }] -------------------------------------------------------------------------------- /src/server/projects/projects_schema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const projectsSchema = new mongoose.Schema({ 3 | title: { 4 | type: String, 5 | text: true, 6 | required: true 7 | }, 8 | timestamp: { 9 | type: String, 10 | text: true, 11 | required: true 12 | }, 13 | tech_stack: [{ 14 | type: String 15 | }], 16 | type: { 17 | type: String, 18 | text: true, 19 | required: true 20 | }, 21 | project_link: { 22 | type: String, 23 | text: true, 24 | required: true 25 | }, 26 | github_link: { 27 | type: String, 28 | text: true, 29 | required: true 30 | }, 31 | description: { 32 | type: String, 33 | text: true, 34 | required: true 35 | } 36 | }); 37 | module.exports = mongoose.model("Projects", projectsSchema); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Anshuman Pattnaik 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/client/actions/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | BASE_URL, 3 | SKILLS_ENDPOINT, 4 | PROJECTS_ENDPOINT, 5 | BLOGS_ENDPOINT, 6 | FETCH_SKILLS_SETS, 7 | FETCH_PROJECTS, 8 | FETCH_BLOGS 9 | } from './constants'; 10 | 11 | export const dispatchSkillSets = data => ({ 12 | type: FETCH_SKILLS_SETS, 13 | payload: data 14 | }); 15 | 16 | export const dispatchProjects = data => ({ 17 | type: FETCH_PROJECTS, 18 | payload: data 19 | }); 20 | 21 | export const dispatchBlogs = data => ({ 22 | type: FETCH_BLOGS, 23 | payload: data 24 | }); 25 | 26 | export const fetchSkillSets = () => dispatch => { 27 | fetch(BASE_URL+SKILLS_ENDPOINT) 28 | .then(response => response.json()) 29 | .then(data => { 30 | dispatch(dispatchSkillSets(data)); 31 | }) 32 | } 33 | 34 | export const fetchProjects = () => dispatch => { 35 | fetch(BASE_URL+PROJECTS_ENDPOINT) 36 | .then(response => response.json()) 37 | .then(data => { 38 | dispatch(dispatchProjects(data)); 39 | }) 40 | } 41 | 42 | export const fetchBlogs = () => dispatch => { 43 | fetch(BASE_URL+BLOGS_ENDPOINT) 44 | .then(response => response.json()) 45 | .then(data => { 46 | dispatch(dispatchBlogs(data)); 47 | }) 48 | } -------------------------------------------------------------------------------- /databases/skills.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "tech_stack": "programming-languages", 3 | "label": "Programming Languages", 4 | "skills": [ 5 | "Java", 6 | "JavaScript", 7 | "Golang", 8 | "Kotlin", 9 | "PHP" 10 | ] 11 | },{ 12 | "tech_stack": "mobile", 13 | "label": "Mobile Platforms", 14 | "skills": [ 15 | "Android", 16 | "React-Native" 17 | ] 18 | },{ 19 | "tech_stack": "front-end", 20 | "label": "Web Front End", 21 | "skills": [ 22 | "React/Redux", 23 | "HTML5", 24 | "CSS3" 25 | ] 26 | },{ 27 | "tech_stack": "back-end", 28 | "label": "Web Back End", 29 | "skills": [ 30 | "Node.js" 31 | ] 32 | },{ 33 | "tech_stack": "databases", 34 | "label": "Databases", 35 | "skills": [ 36 | "MongoDB", 37 | "MySQL", 38 | "SQLite", 39 | "Realm" 40 | ] 41 | },{ 42 | "tech_stack": "ci-cd", 43 | "label": "CI/CD", 44 | "skills": [ 45 | "Docker", 46 | "Travis-CI", 47 | "Amazon AWS" 48 | ] 49 | },{ 50 | "tech_stack": "web-mobile-security", 51 | "label": "Web/Mobile Security", 52 | "skills": [ 53 | "Burp Suite", 54 | "Wireshark", 55 | "Nmap", 56 | "SqlMap", 57 | "Nessus", 58 | "Frida" 59 | ] 60 | },{ 61 | "tech_stack": "blockchain", 62 | "label": "Blockchain", 63 | "skills": [ 64 | "Hyperledger Fabric" 65 | ] 66 | }] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Technical Overview 2 | A portfolio site is essential for every software developer to showcase projects and technical skills which demonstrates what you can do based upon your resume. 3 | 4 | So I have built my site using react.js as a front end, node.js as a back-end, and MongoDB as storage, for better performance I have implemented server-side rendering technique which is a very popular technique for rendering client-side webpage on the server and server will send the complete result to the client, and to bundle the module I have used Webpack which is a module bundler to bundle javascript, front-end assets. 5 | 6 | 7 | 8 | ### MongoDB database import command 9 | Please import the databases after cloning this repo. 10 | 11 | ````````````````````````````````````` 12 | git clone https://github.com/anshumanpattnaik/reactjs-portfolio-mern-website.git 13 | 14 | cd reactjs-portfolio-mern-website/databases 15 | 16 | mongoimport --uri "mongodb://127.0.0.1:27017/portfolio" --collection skills --jsonArray --file skills.json 17 | mongoimport --uri "mongodb://127.0.0.1:27017/portfolio" --collection projects --jsonArray --file projects.json 18 | mongoimport --uri "mongodb://127.0.0.1:27017/portfolio" --collection blogs --jsonArray --file blogs.json 19 | ````````````````````````````````````` 20 | 21 | ### Installation 22 | `````````````````````````````````````` 23 | cd reactjs-portfolio-mern-website 24 | 25 | npm install 26 | npm run start 27 | `````````````````````````````````````` 28 | Open http://localhost:9002 to view it in the browser. 29 | 30 | ### Website Design & Developed by 31 | [Anshuman Pattnaik](https://www.linkedin.com/in/anshuman123/) 32 | 33 | ### License 34 | This project is licensed under the [MIT License](LICENSE) 35 | -------------------------------------------------------------------------------- /src/client/components/BlogsComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "../css/index.css"; 3 | 4 | import { connect } from 'react-redux'; 5 | 6 | import { fetchBlogs } from '../actions'; 7 | 8 | class BlogsComponent extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { 12 | 13 | } 14 | } 15 | 16 | componentDidMount() { 17 | this.props.fetchBlogs(); 18 | } 19 | 20 | render() { 21 | var results = JSON.parse(JSON.stringify(this.props.blogs)).data; 22 | 23 | return ( 24 |
25 |

26 | Here are some of my popular blogs posted on my site, for more blogs please follow my website. 27 |

28 |
29 | {results.length > 0 ? results.map(item => 30 |
31 | 32 |
33 | ) : null} 34 |
35 |
36 |
37 | ); 38 | } 39 | } 40 | 41 | const stateProps = state => ({ 42 | blogs: state.blogs 43 | }); 44 | 45 | const dispatchProps = dispatch => ({ 46 | fetchBlogs: () => dispatch(fetchBlogs()), 47 | }); 48 | 49 | export default connect(stateProps, dispatchProps)(BlogsComponent); -------------------------------------------------------------------------------- /src/client/components/ContactsComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "../css/index.css"; 3 | 4 | import facebook from '../images/ic_black_facebook.png'; 5 | import twitter from '../images/ic_black_twitter.png'; 6 | import linkedin from '../images/ic_black_linkedin.png'; 7 | import github from '../images/ic_black_github.png'; 8 | import youtube from '../images/ic_black_youtube.png'; 9 | 10 | class ContactsComponent extends React.Component { 11 | constructor(props) { 12 | super(props); 13 | this.state = { 14 | 15 | } 16 | } 17 | 18 | componentDidMount() { 19 | 20 | } 21 | 22 | render() { 23 | return ( 24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 |
32 |
33 |

© 2020 HACKBOTONE. ALL RIGHTS RESERVED.

34 |
35 | ); 36 | } 37 | } 38 | 39 | export default ContactsComponent; -------------------------------------------------------------------------------- /webpack.client.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | target: 'node', 5 | entry: './src/client/index.js', 6 | output: { 7 | filename: 'client_bundle.js', 8 | path: path.resolve(__dirname, 'build/public'), 9 | publicPath: '/build/public' 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: [/\.svg$/, /\.gif$/, /\.jpe?g$/, /\.png$/], 15 | loader: "file-loader", 16 | options: { 17 | name: "/media/[name].[ext]", 18 | publicPath: url => url.replace(/build/, "") 19 | } 20 | }, 21 | { 22 | test: /\.js$/, 23 | loader: 'babel-loader', 24 | exclude: '/node_modules/', 25 | options: { 26 | presets: [ 27 | '@babel/preset-react', 28 | '@babel/env' 29 | ], 30 | "plugins": [ 31 | "@babel/plugin-proposal-class-properties" 32 | ] 33 | } 34 | }, 35 | { 36 | test: /\.css$/i, 37 | loader: ['style-loader', 'css-loader'] 38 | }, 39 | { 40 | test: /\.scss$/, 41 | loader: 'style-loader!css-loader!sass-loader' 42 | }, 43 | { 44 | test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, 45 | use: [{ 46 | loader: 'file-loader', 47 | options: { 48 | name: '[name].[ext]', 49 | outputPath: './fonts/' 50 | } 51 | }] 52 | } 53 | ] 54 | } 55 | } -------------------------------------------------------------------------------- /webpack.server.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpackNodeExternals = require('webpack-node-externals'); 3 | 4 | module.exports = { 5 | target: 'node', 6 | entry: './src/server/index.js', 7 | output: { 8 | filename: 'bundle.js', 9 | path: path.resolve(__dirname, 'build'), 10 | publicPath: '/build' 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: [/\.svg$/, /\.gif$/, /\.jpe?g$/, /\.png$/], 16 | loader: "file-loader", 17 | options: { 18 | name: "/media/[name].[ext]", 19 | publicPath: url => url.replace(/build/, ""), 20 | emit: false 21 | } 22 | }, 23 | { 24 | test: /\.js$/, 25 | loader: 'babel-loader', 26 | exclude: '/node_modules/', 27 | options: { 28 | "presets": [ 29 | ['@babel/preset-env', { 30 | "targets": { 31 | "esmodules": true, 32 | }, 33 | }], 34 | '@babel/preset-react' 35 | ], 36 | plugins: [ 37 | ["@babel/plugin-proposal-class-properties"], 38 | ["@babel/transform-regenerator"], 39 | ["@babel/transform-runtime", { 40 | "regenerator": true 41 | }] 42 | ] 43 | } 44 | }, 45 | { 46 | test: /\.css$/, 47 | use: [ 48 | { 49 | loader: "css-loader" 50 | } 51 | ] 52 | }, 53 | { 54 | test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, 55 | use: [{ 56 | loader: 'file-loader', 57 | options: { 58 | name: '[name].[ext]', 59 | outputPath: './fonts/' 60 | } 61 | }] 62 | } 63 | ] 64 | }, 65 | externals: [webpackNodeExternals()] 66 | } -------------------------------------------------------------------------------- /src/client/components/SkillSetsComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "../css/index.css"; 3 | 4 | import { connect } from 'react-redux'; 5 | 6 | import { fetchSkillSets } from '../actions'; 7 | 8 | class SkillSetsComponent extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | } 12 | 13 | componentDidMount() { 14 | this.props.fetchSkillSets(); 15 | } 16 | 17 | renderTechSkills = (items) => { 18 | return ( 19 | items.map(data => 20 |
21 | {data} 22 |
23 | ) 24 | ); 25 | } 26 | 27 | renderTechStacks = (results) => { 28 | if (results.length > 0) { 29 | return ( 30 | results.map(item => 31 |
32 |
33 | {item.label} 34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | {this.renderTechSkills(item.skills)} 43 |
44 |
45 | ) 46 | ); 47 | } 48 | } 49 | 50 | render() { 51 | var results = JSON.parse(JSON.stringify(this.props.skills)).data; 52 | return ( 53 |
54 | {this.renderTechStacks(results)} 55 |
56 |
57 | ); 58 | } 59 | } 60 | 61 | const stateProps = state => ({ 62 | skills: state.skills 63 | }); 64 | 65 | const dispatchProps = dispatch => ({ 66 | fetchSkillSets: () => dispatch(fetchSkillSets()), 67 | }); 68 | 69 | export default connect(stateProps, dispatchProps)(SkillSetsComponent); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactjs-portfolio-mern-application", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@babel/cli": "^7.10.1", 7 | "@babel/core": "^7.10.2", 8 | "@babel/plugin-proposal-class-properties": "^7.10.1", 9 | "@babel/plugin-transform-async-to-generator": "^7.10.1", 10 | "@babel/plugin-transform-runtime": "^7.10.1", 11 | "@babel/polyfill": "^7.10.1", 12 | "@babel/preset-env": "^7.10.2", 13 | "@babel/preset-react": "^7.10.1", 14 | "@babel/runtime-corejs3": "^7.10.2", 15 | "@testing-library/jest-dom": "^4.2.4", 16 | "@testing-library/react": "^9.3.2", 17 | "@testing-library/user-event": "^7.1.2", 18 | "babel-loader": "^8.1.0", 19 | "babel-plugin-transform-runtime": "^6.23.0", 20 | "babel-preset-es2015": "^6.24.1", 21 | "babel-preset-stage-0": "^6.24.1", 22 | "body-parser": "^1.19.0", 23 | "cors": "^2.8.5", 24 | "css-loader": "^3.5.3", 25 | "express": "^4.17.1", 26 | "extract-text-webpack-plugin": "^4.0.0-beta.0", 27 | "file-loader": "^6.0.0", 28 | "flatlist-react": "^1.4.2", 29 | "mongoose": "^5.9.19", 30 | "nodemon": "^2.0.4", 31 | "npm-run-all": "^4.1.5", 32 | "postcss-loader": "^3.0.0", 33 | "react": "^16.13.1", 34 | "react-dom": "^16.13.1", 35 | "react-redux": "^7.2.0", 36 | "react-router": "^5.2.0", 37 | "react-router-dom": "^5.2.0", 38 | "react-scripts": "3.4.1", 39 | "redux": "^4.0.5", 40 | "redux-logger": "^3.0.6", 41 | "redux-thunk": "^2.3.0", 42 | "style-loader": "^1.2.1", 43 | "url-loader": "^4.1.0", 44 | "webpack": "^4.43.0", 45 | "webpack-cli": "^3.3.11", 46 | "webpack-node-externals": "^1.7.2" 47 | }, 48 | "scripts": { 49 | "start": "npm-run-all --parallel webpack:*", 50 | "webpack:client": "webpack --config webpack.client.js --watch", 51 | "webpack:server": "webpack --config webpack.server.js --watch", 52 | "webpack:start": "nodemon --watch build --exec node build/bundle.js", 53 | "build": "webpack --config webpack.client.js && webpack --config webpack.server.js" 54 | }, 55 | "eslintConfig": { 56 | "extends": "react-app" 57 | }, 58 | "browserslist": { 59 | "production": [ 60 | ">0.2%", 61 | "not dead", 62 | "not op_mini all" 63 | ], 64 | "development": [ 65 | "last 1 chrome version", 66 | "last 1 firefox version", 67 | "last 1 safari version" 68 | ] 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/server/index.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import bodyParser from 'body-parser'; 3 | 4 | import '@babel/polyfill'; 5 | import React from 'react'; 6 | import ReactDOMServer from 'react-dom/server'; 7 | import { StaticRouter } from 'react-router'; 8 | 9 | import App from '../client/App'; 10 | 11 | const cors = require('cors'); 12 | const app = express(); 13 | const PORT = process.env.PORT || 9002; 14 | 15 | var skills_route = require('./skills/skills_controller'); 16 | var projects_route = require('./projects/projects_controller'); 17 | var blogs_route = require('./blogs/blogs_controller'); 18 | 19 | app.use("/api/projects", projects_route); 20 | app.use("/api/skills", skills_route); 21 | app.use("/api/blogs", blogs_route); 22 | 23 | app.use(bodyParser.json()); 24 | app.use(cors()); 25 | app.use(express.static('build/public')); 26 | 27 | app.get('*', (req, res) => { 28 | var title = "My Portfolio | Full Stack Mern Application"; 29 | var description = "A portfolio site is essential for every software developer to showcase projects and technical skills which demonstrates what you can do based upon your resume."; 30 | var thumb = "https://assets.hackbotone.com/images/my-portfolio-full-stack-mern-application/Thumbnail.png"; 31 | var favicon = "https://assets.hackbotone.com/images/icons/anshuman_pattnaik.jpg"; 32 | var link = "https://myportfolio.hackbotone.com"; 33 | 34 | const context = {} 35 | 36 | const markup = ReactDOMServer.renderToString( 37 | 38 | 39 | 40 | ); 41 | 42 | const html = ` 43 | 44 | 45 | 46 | 47 | 48 | 49 | ${title} 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
${markup}
71 | 72 | 73 | `; 74 | 75 | res.send(html); 76 | }) 77 | 78 | app.listen(PORT, () => { 79 | console.log(`Server listening on ${PORT}`); 80 | }) -------------------------------------------------------------------------------- /src/client/components/ProfileComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "../css/index.css"; 3 | 4 | import profile from "../images/ic_profile_img.jpg"; 5 | import facebook from "../images/ic_facebook.png"; 6 | import twitter from "../images/ic_twitter.png"; 7 | import github from "../images/ic_github.png"; 8 | import linkedin from "../images/ic_linkedin.png"; 9 | import youtube from "../images/ic_youtube.png"; 10 | 11 | class ProfileComponent extends React.Component { 12 | constructor(props) { 13 | super(props); 14 | } 15 | 16 | componentDidMount() { 17 | 18 | } 19 | 20 | render() { 21 | return ( 22 |
23 |
24 |
25 |
26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 |
34 |
35 |
36 |

Hello, I'm Anshuman Pattnaik

37 |

38 | I'm a Senior Software Engineer specialized in Android & Web application development, having fluent knowledge in the Android framework and developed many mobile applications from various domains such as (Payment, IoT, Graphics, Augmented Reality & Virtual Reality) and also developed cross-platform based mobile application using React-Native framework. In terms of the Web framework having experience in both back-end and front-end development, developed many full-stack based web application using Node.js, React.js & MongoDB. 39 |

40 |

41 | To improve my skill sets in security I like to participate in various Bug Bounty programs (Bugcrowd, HackerOne & many others) In Bug Bounty programs, I found many vulnerabilities that come under OWASP top 10. 42 |

43 |

44 | As a hobby love to make games using Unity3d game engine and to share my work with developer communities I write blogs and make tutorial videos on my Youtube channel. 45 |

46 |
47 |
48 | 49 |
50 | ); 51 | } 52 | } 53 | 54 | export default ProfileComponent; -------------------------------------------------------------------------------- /src/client/components/DashboardComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "../css/index.css"; 3 | 4 | import logo from '../images/ic_logo.png'; 5 | import down_arrow from '../images/ic_down_arrow.png'; 6 | 7 | import ProfileComponent from './ProfileComponent'; 8 | import SkillSetsComponent from './SkillSetsComponent'; 9 | import ProjectsComponent from './ProjectsComponent'; 10 | import BlogsComponent from './BlogsComponent'; 11 | import ContactsComponent from './ContactsComponent'; 12 | 13 | class DashboardComponent extends React.Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { 17 | tabItem: ['HOME', 'SKILLS', 'PROJECTS', 'BLOGS'], 18 | selectedItem: 'HOME' 19 | } 20 | } 21 | 22 | componentDidMount() { 23 | 24 | } 25 | 26 | setSelectedTab = (item) => { 27 | this.setState({ 28 | selectedItem: item 29 | }) 30 | } 31 | 32 | renderTabContents = () => { 33 | var tabItem = this.state.selectedItem; 34 | if (tabItem === 'HOME') { 35 | return ( 36 | 37 | ) 38 | } 39 | if (tabItem === 'SKILLS') { 40 | return ( 41 | 42 | ) 43 | } 44 | if (tabItem === 'PROJECTS') { 45 | return ( 46 | 47 | ) 48 | } 49 | if (tabItem === 'BLOGS') { 50 | return ( 51 | 52 | ) 53 | } 54 | } 55 | 56 | render() { 57 | return ( 58 |
59 |
60 |
61 | 62 |
63 |
64 | {this.renderTabContents()} 65 |
66 |
67 | {this.state.tabItem.map(data => 68 |
69 | {data} 70 |
71 | )} 72 |
73 |
74 |
75 |
76 |
77 | 78 |
79 |
80 | HOME 81 | SKILLS 82 | PROJECTS 83 | BLOGS 84 | CONTACTS 85 |
86 |
87 | 88 |
89 | 90 |
91 |
92 |
93 | Technical Skills 94 |
95 | 96 |
97 |
98 |
99 | Projects 100 |
101 | 102 |
103 |
104 |
105 | Blogs 106 |
107 | 108 |
109 |
110 |
111 | Contacts 112 |
113 | 114 |
115 |
116 |
117 | ); 118 | } 119 | } 120 | 121 | export default DashboardComponent; -------------------------------------------------------------------------------- /databases/projects.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "title": "My Portfolio | Full Stack MERN Application", 3 | "timestamp": "1592980488", 4 | "date": "June 06, 2020", 5 | "thumbnail": "https://assets.hackbotone.com/images/my-portfolio-full-stack-mern-application/Thumbnail.png", 6 | "tech_stack": [ 7 | "React.js", 8 | "Node.js", 9 | "MongoDB", 10 | "Webpack" 11 | ], 12 | "type": "Web", 13 | "project_link": "https://myportfolio.hackbotone.com/", 14 | "github_link": "https://github.com/anshumanpattnaik/reactjs-portfolio-mern-website", 15 | "description": "A portfolio site is essential for every software developer to showcase projects and technical skills which demonstrates what you can do based upon your resume." 16 | },{ 17 | "title": "Forest Assassin 2D Platformer Game", 18 | "timestamp": "1588283414", 19 | "date": "May 01, 2020", 20 | "thumbnail": "https://assets.hackbotone.com/images/forest-assassin-2d-platformer-game/Thumbnail.png", 21 | "tech_stack": [ 22 | "Unity3D", 23 | "WebGL", 24 | "C#", 25 | "Node.js", 26 | "HTML5" 27 | ], 28 | "type": "Web", 29 | "project_link": "https://games.hackbotone.com/forest-assassin/", 30 | "github_link": "https://github.com/anshumanpattnaik/unity-2d-forest-assassin-game", 31 | "description": "Forest Assassin is a 2D adventure platformer game with easy controls and is developed with Unity3d game engine and is available for both Android & Web platforms." 32 | },{ 33 | "title": "Coronavirus (COVID-19) - Full Stack Application", 34 | "timestamp": "1586728214", 35 | "date": "April 13, 2020", 36 | "thumbnail": "https://assets.hackbotone.com/images/coronavirus_covid_19_full_stack_application/Thumbnail.png", 37 | "tech_stack": [ 38 | "React.js", 39 | "Node.js", 40 | "MongoDB", 41 | "MapBox" 42 | ], 43 | "type": "Web", 44 | "project_link": "https://covid19.hackbotone.com/", 45 | "github_link": "https://github.com/anshumanpattnaik/covid19-full-stack-application", 46 | "description": "The idea behind this application is to displays the statistics of Coronavirus (COVID-19) around the world and populate the statistics over the map." 47 | },{ 48 | "title": "HackbotOne - Full Stack Application", 49 | "timestamp": "1577953333", 50 | "date": "January 02, 2020", 51 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/hackbotone_thumbnail.png", 52 | "tech_stack": [ 53 | "React.js", 54 | "Node.js", 55 | "Webpack", 56 | "MongoDB" 57 | ], 58 | "type": "Web", 59 | "project_link": "https://hackbotone.com/", 60 | "github_link": "https://github.com/anshumanpattnaik/hackbotone-mern-website", 61 | "description": "HackbotOne website produce contents from various domains such as Web Hacking, Bug Bounty, Application Development & GameDevelopment." 62 | },{ 63 | "title": "Virtual Reality Panorama viewer", 64 | "timestamp": "1474494614", 65 | "date": "Sep 22, 2016", 66 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/vr_panorama_thumb.png", 67 | "tech_stack": [ 68 | "Unity", 69 | "Virtual Reality", 70 | "C#" 71 | ], 72 | "type": "Mobile/Youtube", 73 | "project_link": "https://www.youtube.com/watch?v=cPp14W910ZA", 74 | "github_link": "N/A", 75 | "description": "The idea behind this project is to demonstrate how a user can able to see a panoramic image in virtual reality and the application was built using Unity3d panoramic SDK and build for Android devices." 76 | },{ 77 | "title": "Virtual Reality | Google VR SDK", 78 | "timestamp": "1488235814", 79 | "date": "Feb 28, 2017", 80 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/google_thumb.png", 81 | "tech_stack": [ 82 | "VR SDK", 83 | "Android", 84 | "Java" 85 | ], 86 | "type": "Mobile/Youtube", 87 | "project_link": "https://www.youtube.com/watch?v=Cqa9Iz06y0M&t=125s", 88 | "github_link": "https://github.com/anshumanpattnaik/Android-PanoramaViewer", 89 | "description": "The idea behind this project was to demonstrate how we can stream 360 videos using Google VR SDK and the proof of concept was developed using many Youtube 360 videos." 90 | },{ 91 | "title": "Android Home Automation System using Arduino", 92 | "timestamp": "1474321814", 93 | "date": "Oct 30, 2014", 94 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/Android_Arduino_Home_Thumb.png", 95 | "tech_stack": [ 96 | "Java", 97 | "Android", 98 | "Arduino", 99 | "C" 100 | ], 101 | "type": "Mobile/Youtube", 102 | "project_link": "https://www.youtube.com/watch?v=qB12ryYComE&t=10s", 103 | "github_link": "N/A", 104 | "description": "The idea behind this project is to demonstrate how can we control the home electronic appliances by programming the Arduino microcontroller and control the board using an android application through Bluetooth." 105 | },{ 106 | "title": "Twine", 107 | "timestamp": "1434059414", 108 | "date": "Jun 12, 2015", 109 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/twine_thumb.png", 110 | "tech_stack": [ 111 | "Java", 112 | "Android", 113 | "Venmo", 114 | "Realm", 115 | "AWS" 116 | ], 117 | "type": "Mobile/Blog", 118 | "project_link": "https://www.7cstudio.com/twine.html", 119 | "github_link": "N/A", 120 | "description": "Twine is a payment based android application and the idea behind this application is to exchange money in between users, it supports Venmo payment gateway to transfer the money, this application is only available for the US market." 121 | },{ 122 | "title": "Fellow PRAP", 123 | "timestamp": "1414623014", 124 | "date": "Oct 30, 2014", 125 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/Fellow_PRAP_Thumb.png", 126 | "tech_stack": [ 127 | "Java", 128 | "Android", 129 | "SQLite", 130 | "JSON" 131 | ], 132 | "type": "Mobile/PlayStore", 133 | "project_link": "https://play.google.com/store/apps/details?id=com.mindtree.kefprap", 134 | "github_link": "N/A", 135 | "description": "This application was developed for the Kaivalya education foundation group and the application was specifically designed & developed for the fellow to appear their internal examination." 136 | },{ 137 | "title": "Fellow Register", 138 | "timestamp": "1407102614", 139 | "date": "Aug 04, 2014", 140 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/Fellow_Register_thumbnail.png", 141 | "tech_stack": [ 142 | "Java", 143 | "Android", 144 | "SQLite", 145 | "JSON" 146 | ], 147 | "type": "Mobile/PlayStore", 148 | "project_link": "https://play.google.com/store/apps/details?id=com.mindtree.keffellowregister", 149 | "github_link": "N/A", 150 | "description": "This application was developed for the Kaivalya education foundation group and the application has some good features such as Planner, Notes, Calendar & Diary." 151 | },{ 152 | "title": "PHP Translation Tool", 153 | "timestamp": "1372663333", 154 | "date": "JULY 2013", 155 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/PHP_DOM_Parser_Thumb.png", 156 | "tech_stack": [ 157 | "PHP", 158 | "HTML", 159 | "DOM", 160 | "MySQL", 161 | "Translation" 162 | ], 163 | "type": "Web", 164 | "project_link": "N/A", 165 | "github_link": "https://github.com/anshumanpattnaik/php-dom-parser-translation-tool", 166 | "description": "The idea behind this project is to translate the webpages from English to Odia language by parsing the HTML DOM of the webpage and it was a proof of concept in early 2013. " 167 | },{ 168 | "title": "English to Odia Dictionary", 169 | "timestamp": "1325371814", 170 | "date": "Jan 01, 2012", 171 | "thumbnail": "https://assets.hackbotone.com/images/portfolio/English_To_OdiaThumb.png", 172 | "tech_stack": [ 173 | "Java", 174 | "Android", 175 | "Keyboard", 176 | "SQLite" 177 | ], 178 | "type": "Mobile/PlayStore", 179 | "project_link": "https://play.google.com/store/apps/details?id=com.ori.dic", 180 | "github_link": "N/A", 181 | "description": "It's an offline android dictionary by using this application a user can get the English meaning of an Odia word, this application has around 1 Million+ downloads in google play store." 182 | }] -------------------------------------------------------------------------------- /src/client/components/ProjectsComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "../css/index.css"; 3 | 4 | import { connect } from 'react-redux'; 5 | import Modal from 'react-modal'; 6 | 7 | import { fetchProjects } from '../actions'; 8 | 9 | import closeIcon from '../images/ic_close.png'; 10 | import githubIcon from '../images/ic_github_white.png'; 11 | import webIcon from '../images/ic_web_site.png'; 12 | import playstore from '../images/ic_google_playstore.png'; 13 | 14 | const modalStyles = { 15 | overlay: { 16 | zIndex: 2000, 17 | backgroundColor: 'rgba(52, 52, 52, 0.8)' 18 | }, 19 | content: { 20 | position: 'absolute', 21 | top: '50%', 22 | left: '50%', 23 | right: 'auto', 24 | bottom: 'auto', 25 | zIndex: 2000, 26 | padding: '0px', 27 | borderRadius: '0px', 28 | transform: 'translate(-50%, -50%)' 29 | } 30 | }; 31 | 32 | Modal.setAppElement('#root'); 33 | 34 | class ProjectsComponent extends React.Component { 35 | constructor(props) { 36 | super(props); 37 | this.state = { 38 | tabItem: ['All', 'Web', 'Mobile'], 39 | selectedItem: 'All', 40 | projectItem: null, 41 | isDialogOpen: false, 42 | } 43 | } 44 | 45 | componentDidMount() { 46 | this.props.fetchProjects(); 47 | } 48 | 49 | setSelectedTab = (item) => { 50 | this.setState({ 51 | selectedItem: item 52 | }) 53 | } 54 | 55 | renderProjects = (results) => { 56 | if (results.length > 0) { 57 | return ( 58 | results.map((item) => { 59 | var type = item.type; 60 | var tabItem = this.state.selectedItem; 61 | 62 | if (type.includes(tabItem)) { 63 | return ( 64 |
{this.renderProjectItems(item)}
65 | ); 66 | } 67 | }) 68 | ) 69 | } 70 | } 71 | 72 | renderProjectItems = (item) => { 73 | return ( 74 |
75 |
76 |
77 |
78 |

{item.title}

79 |
80 | Read More 81 |
82 |
83 |
84 |
85 | 86 |
87 | ) 88 | } 89 | 90 | renderAllProjects = (results) => { 91 | if (results.length > 0) { 92 | return ( 93 | results.map((item) => { 94 | return ( 95 |
{this.renderProjectItems(item)}
96 | ); 97 | }) 98 | ) 99 | } 100 | } 101 | 102 | onSetProjectDialogState = (isShow, item) => { 103 | this.setState({ 104 | isDialogOpen: isShow, 105 | projectItem: item 106 | }) 107 | } 108 | 109 | openProjectDialog = () => { 110 | var isShow = this.state.isDialogOpen; 111 | var item = this.state.projectItem; 112 | 113 | if (isShow) { 114 | return ( 115 | 120 |
121 | 122 |
123 | {item.title} 124 |

{item.description}

125 |

Technology Stack

126 |
127 | {item.tech_stack.map(tech => 128 |
129 | {tech} 130 |
131 | )} 132 |
133 | 162 |
163 |
164 |
165 | ) 166 | } 167 | } 168 | 169 | render() { 170 | var results = JSON.parse(JSON.stringify(this.props.projects)).data; 171 | 172 | return ( 173 |
174 |
175 |
176 | {this.state.tabItem.map(data => 177 |
178 | {data} 179 |
180 |
181 | )} 182 |
183 |
184 |
185 | {this.state.selectedItem === 'All' ? this.renderAllProjects(results) : this.renderProjects(results)} 186 |
187 |
188 |
189 | {this.openProjectDialog()} 190 |
191 | ); 192 | } 193 | } 194 | 195 | const stateProps = state => ({ 196 | projects: state.projects 197 | }); 198 | 199 | const dispatchProps = dispatch => ({ 200 | fetchProjects: () => dispatch(fetchProjects()), 201 | }); 202 | 203 | export default connect(stateProps, dispatchProps)(ProjectsComponent); -------------------------------------------------------------------------------- /src/client/css/index.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap'); 2 | 3 | html, body { 4 | margin: 0; 5 | font-family: 'Poppins', sans-serif; 6 | scroll-behavior: smooth; 7 | overflow-x: hidden; 8 | } 9 | .dashboard-parent-container { 10 | width: 100%; 11 | height: auto; 12 | } 13 | .desktop-parent-container { 14 | width: 100%; 15 | height: auto; 16 | display: block; 17 | } 18 | .mobile-parent-container { 19 | display: none; 20 | } 21 | .logo { 22 | width: auto; 23 | height: 2em; 24 | margin-left: 5em; 25 | } 26 | .logo-container { 27 | width: 30%; 28 | display: flex; 29 | flex-direction: row; 30 | justify-content: flex-end; 31 | align-items: center; 32 | } 33 | .menu-bar-container { 34 | width: 100vw; 35 | height: 3.5em; 36 | z-index: 3000; 37 | position: fixed; 38 | display: flex; 39 | flex-direction: row; 40 | justify-content: center; 41 | align-items: center; 42 | border-bottom: 0.5px solid #646464; 43 | background: rgb(29, 29, 29); 44 | } 45 | .menu-item-container { 46 | width: 70%; 47 | display: flex; 48 | flex-direction: row; 49 | justify-content: flex-end; 50 | align-items: center; 51 | margin-right: 15em; 52 | } 53 | .menu-item-txt { 54 | font-size: 0.9rem; 55 | color: #FFF; 56 | text-decoration: none; 57 | padding: 1em; 58 | } 59 | .menu-item-txt:hover { 60 | font-size: 0.9rem; 61 | color: rgb(238, 39, 39); 62 | text-decoration: none; 63 | cursor: pointer; 64 | padding: 1em; 65 | } 66 | .dashboard-header-container { 67 | width: 100vw; 68 | height: 100vh; 69 | background: #ffffff; 70 | } 71 | .dashboard-banner-img { 72 | width: 100vw; 73 | height: 100vh; 74 | position: relative; 75 | background-repeat: no-repeat; 76 | background-position: center; 77 | background-size:contain; 78 | background-image: url('../images/ic_banner.png'); 79 | } 80 | .dashboard-down-arrow-container { 81 | width: 100%; 82 | height: 10%; 83 | position: absolute; 84 | bottom: 0; 85 | z-index: 2000; 86 | display: flex; 87 | justify-content: center; 88 | align-items: center; 89 | } 90 | .dashboard-down-arrow { 91 | width: 3.5em; 92 | height: 3.5em; 93 | cursor: pointer; 94 | } 95 | .dashboard-banner-overlay { 96 | width: 100vw; 97 | height: 100vh; 98 | position: absolute; 99 | z-index: 1; 100 | background: #111111; 101 | opacity: 0.95; 102 | } 103 | .dashboard-profile-div { 104 | width: 100%; 105 | height: 100vh; 106 | position: absolute; 107 | margin-top: 0em; 108 | z-index: 10; 109 | display: flex; 110 | justify-content: center; 111 | align-items: center; 112 | flex-direction: row; 113 | } 114 | .dashboard-profile-img-container { 115 | height: auto; 116 | display: flex; 117 | flex-direction: column; 118 | justify-content: center; 119 | align-items: center; 120 | } 121 | .dashboard-profile-img { 122 | width: 15em; 123 | height: 15em; 124 | padding: 1px; 125 | margin-top: 3em; 126 | border: 1px solid #ddd; 127 | border-radius: 50%; 128 | background: #ffffff; 129 | position: relative; 130 | animation: profile-image-animation; 131 | animation-duration: 2s; 132 | animation-fill-mode: forwards; 133 | } 134 | .social-profile-container { 135 | height: auto; 136 | display: flex; 137 | flex-direction: row; 138 | align-items: center; 139 | margin-top: 1em; 140 | } 141 | .social-profile-icon { 142 | width: 2em; 143 | height: 2em; 144 | padding: 1em; 145 | } 146 | .dashboard-profile-details-container { 147 | width: 60%; 148 | height: auto; 149 | margin-top: 0em; 150 | margin-left: 4em; 151 | } 152 | .dashboard-profile-name-label { 153 | font-weight: 700; 154 | font-size: 2.5rem; 155 | color: white; 156 | position: relative; 157 | animation: profile-name-animation; 158 | animation-duration: 2s; 159 | animation-fill-mode: forwards; 160 | } 161 | .dashboard-profile-name { 162 | font-weight: 700; 163 | font-size: 2.5rem; 164 | color: #EA0047; 165 | position: relative; 166 | animation: profile-name-animation; 167 | animation-duration: 2s; 168 | animation-fill-mode: forwards; 169 | } 170 | .dashboard-profile-deatils { 171 | font-size: 0.95rem; 172 | color: #ffffff; 173 | line-height: 1.7em; 174 | position: relative; 175 | animation: profile-details-animation; 176 | animation-duration: 2s; 177 | animation-fill-mode: forwards; 178 | } 179 | .profile-details-link { 180 | font-size: 0.95rem; 181 | color: #ffffff; 182 | line-height: 1.7em; 183 | text-decoration: underline; 184 | position: relative; 185 | animation: profile-details-link-animation; 186 | animation-duration: 2s; 187 | animation-fill-mode: forwards; 188 | } 189 | .profile-details-link:hover { 190 | font-size: 0.95rem; 191 | color: #c7f109; 192 | line-height: 1.7em; 193 | text-decoration: underline; 194 | } 195 | .dashboard-skill-sets-container { 196 | width: 100vw; 197 | height: auto; 198 | margin-top: 3em; 199 | display: flex; 200 | flex-direction: column; 201 | justify-content: center; 202 | align-items: center; 203 | background: #FFF; 204 | } 205 | .skills-container { 206 | width: 15em; 207 | height: 3em; 208 | border: 0.5px solid #333; 209 | border-radius: 2em; 210 | display: flex; 211 | justify-content: center; 212 | align-items: center; 213 | background: #333; 214 | box-shadow: 1px 1px #333; 215 | margin-top: 3em; 216 | } 217 | .dashboard-skills-label { 218 | font-size: 1.2rem; 219 | color: #FFF; 220 | font-weight: bold; 221 | } 222 | 223 | /*************************SkillSets Styles********************************/ 224 | .skills-parent-container { 225 | width: 100vw; 226 | height: auto; 227 | display: flex; 228 | flex-direction: column; 229 | margin-top: 3em; 230 | margin-bottom: 0em; 231 | } 232 | .skills-sets-container { 233 | width: 100%; 234 | height: 5em; 235 | display: flex; 236 | flex-direction: row; 237 | } 238 | .skills-separator-container { 239 | width: 1em; 240 | height: 5em; 241 | display: flex; 242 | flex-direction: column; 243 | align-items: center; 244 | } 245 | .skills-separator-line { 246 | height: 4.5em; 247 | border: 0.5px solid #d8d7d7; 248 | } 249 | .skills-separator-circle { 250 | width: 1em; 251 | height: 1em; 252 | border-radius: 50%; 253 | display: flex; 254 | justify-content: center; 255 | align-items: center; 256 | border: 1px solid #d8d7d7; 257 | } 258 | .skills-separator-inner-circle { 259 | width: 0.5em; 260 | height: 0.5em; 261 | border-radius: 5em; 262 | background:#d8d7d7; 263 | } 264 | .skills-label-container { 265 | width: 35%; 266 | height: auto; 267 | display: flex; 268 | justify-content: flex-end; 269 | align-items: center; 270 | } 271 | .skills-label { 272 | font-size: 1.2rem; 273 | font-weight: bold; 274 | color: #333; 275 | margin-right: 2em; 276 | } 277 | .skills-items-container { 278 | padding: 1em; 279 | display: flex; 280 | flex-direction: row; 281 | justify-content: center; 282 | align-items: center; 283 | } 284 | .skills-item-container { 285 | padding-left: 1em; 286 | padding-right: 1em; 287 | padding-top: 0.2em; 288 | padding-bottom: 0.2em; 289 | border-radius: 5em; 290 | border: 0.5px solid #333; 291 | display: flex; 292 | justify-content: center; 293 | align-items: center; 294 | margin-left: 1.5em; 295 | display: block; 296 | background: #333; 297 | } 298 | .skills-item-text { 299 | font-size: 1rem; 300 | font-weight: bold; 301 | color: #FFF; 302 | } 303 | .skills-item-container-hide { 304 | display: none; 305 | } 306 | /*************************************************************************/ 307 | 308 | /*************************Projects Styles********************************/ 309 | .projects-parent-container { 310 | width: 100vw; 311 | height: auto; 312 | display: flex; 313 | flex-direction: column; 314 | align-items: center; 315 | margin-top: 3em; 316 | background: #f2f2f2; 317 | } 318 | .project-child-container { 319 | width: 80em; 320 | height: auto; 321 | } 322 | .projects-tab-container { 323 | width: 100%; 324 | height: 8%; 325 | display: grid; 326 | grid-template-columns: 33% 33% 33%; 327 | justify-content: center; 328 | align-items: center; 329 | } 330 | .tab-container { 331 | width: 100%; 332 | height: 5em; 333 | display: flex; 334 | flex-direction: column; 335 | justify-content: center; 336 | align-items: center; 337 | } 338 | .tab-container:hover { 339 | width: 100%; 340 | height: 5em; 341 | display: flex; 342 | flex-direction: column; 343 | justify-content: center; 344 | align-items: center; 345 | cursor: pointer; 346 | } 347 | .tab-label { 348 | font-size: 1.2rem; 349 | font-weight: bold; 350 | color: #333; 351 | margin-bottom: 0em; 352 | } 353 | .tab-label:hover { 354 | font-size: 1.2rem; 355 | font-weight: bold; 356 | color: #4c8bf5; 357 | margin-bottom: 0em; 358 | } 359 | .tab-selected-label { 360 | font-size: 1.2rem; 361 | font-weight: bold; 362 | color: #4c8bf5; 363 | margin-bottom: 0em; 364 | } 365 | .tab-selected { 366 | width: 100%; 367 | height: 0.2em; 368 | margin: 1em; 369 | background: #4c8bf5; 370 | } 371 | .tab-unselected { 372 | width: 100%; 373 | height: 0.2em; 374 | margin: 1em; 375 | background: #CCC; 376 | } 377 | .projects-items-container { 378 | display: grid; 379 | justify-content: center; 380 | grid-template-columns: 33% 33% 33%; 381 | grid-gap: 0.5rem; 382 | margin-top: 0.5em; 383 | margin: 0.1em; 384 | padding-bottom: 2em; 385 | } 386 | .projects-card-item { 387 | display: flex; 388 | flex-direction: column; 389 | } 390 | .project-title { 391 | font-size: 1.2rem; 392 | font-weight: bold; 393 | margin-top: 2em; 394 | text-align: center; 395 | color: #333; 396 | position: relative; 397 | animation: project-title; 398 | animation-duration: 0.2s; 399 | animation-fill-mode: forwards; 400 | } 401 | .overlay-item-container { 402 | display: none; 403 | } 404 | .div-thumb-overlay { 405 | width: 26.35em; 406 | height: 14.8em; 407 | position: absolute; 408 | display: flex; 409 | justify-content: center; 410 | } 411 | .div-thumb-overlay:hover .overlay-item-container { 412 | width: 26.35em; 413 | height: 14.8em; 414 | display: flex; 415 | justify-content: center; 416 | position: absolute; 417 | cursor: pointer; 418 | border: 0.5px solid #CCC; 419 | background: #FCFCFC; 420 | } 421 | .overlay-project-div { 422 | width: 100%; 423 | display: flex; 424 | flex-direction: column; 425 | justify-content: center; 426 | align-items: center; 427 | } 428 | .project-readmore-container { 429 | display: flex; 430 | justify-content: center; 431 | align-items: center; 432 | position: relative; 433 | background: #FFF; 434 | animation: project-readmore-container; 435 | animation-duration: 0.2s; 436 | animation-fill-mode: forwards; 437 | } 438 | .project-readmore-container:hover { 439 | display: flex; 440 | justify-content: center; 441 | align-items: center; 442 | position: relative; 443 | background: #333; 444 | animation: project-readmore-container; 445 | animation-duration: 0.2s; 446 | animation-fill-mode: forwards; 447 | } 448 | .project-readmore-text { 449 | font-size: 1rem; 450 | color: #333; 451 | padding: 0.5em; 452 | border: 1.5px solid #333; 453 | } 454 | .project-readmore-text:hover { 455 | font-size: 1rem; 456 | color: #FFF; 457 | padding: 0.5em; 458 | border: 1.5px solid #333; 459 | } 460 | .projects-thumb-img { 461 | width: 100%; 462 | height: auto; 463 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 464 | } 465 | /*************************************************************************/ 466 | 467 | /***************************Blogs Styles*************************/ 468 | .blogs-parent-container { 469 | width: 100vw; 470 | height: auto; 471 | display: flex; 472 | flex-direction: column; 473 | align-items: center; 474 | padding-bottom: 2em; 475 | background: #4c8bf5; 476 | } 477 | .blogs-parent-contents-container { 478 | width: 80vw; 479 | height: 25em; 480 | display: flex; 481 | flex-direction: column; 482 | align-items: center; 483 | } 484 | .blogs-contents-container { 485 | width: 80vw; 486 | height: auto; 487 | display: flex; 488 | flex-direction: row; 489 | justify-content: center; 490 | align-items: center; 491 | } 492 | .blogs-text { 493 | font-size: 1rem; 494 | color: #FFF; 495 | margin-top: 3em; 496 | } 497 | .blogs-poster-container { 498 | width: 50em; 499 | height: auto; 500 | padding: 1em; 501 | margin-top: 1em; 502 | display: flex; 503 | justify-content: center; 504 | align-items: center; 505 | } 506 | .blogs-poster-img { 507 | width: 100%; 508 | height: auto; 509 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 510 | } 511 | .blogs-details-link { 512 | font-size: 0.95rem; 513 | color: #ffffff; 514 | line-height: 1.7em; 515 | text-decoration: underline; 516 | } 517 | .blogs-details-link:hover { 518 | font-size: 0.95rem; 519 | color: #c7f109; 520 | line-height: 1.7em; 521 | text-decoration: underline; 522 | } 523 | /****************************************************************/ 524 | 525 | /**********************Contacts Styles********************/ 526 | .contacts-parent-container { 527 | width: 100vw; 528 | height: auto; 529 | display: flex; 530 | flex-direction: column; 531 | align-items: center; 532 | background: rgb(248, 248, 248); 533 | } 534 | .contacts-contents-container { 535 | width: 100vw; 536 | height: auto; 537 | display: flex; 538 | flex-direction: column; 539 | align-items: center; 540 | } 541 | .contacts-social-container { 542 | display: flex; 543 | flex-direction: row; 544 | margin-top: 2.5em; 545 | } 546 | .contact-social-img { 547 | width: 3em; 548 | height: 3em; 549 | margin: 1em; 550 | } 551 | .contacts-footer-div { 552 | width: 50em; 553 | height: 0.5px; 554 | margin-top: 3em; 555 | background: #CCC; 556 | } 557 | .contacts-footer-text { 558 | font-size: 0.8rem; 559 | color: #333; 560 | margin-top: 2em; 561 | } 562 | /*********************************************************/ 563 | 564 | /*************************************Project Dialog*************************************/ 565 | .project-modal-container { 566 | width: 35em; 567 | height: auto; 568 | overflow: hidden; 569 | display: flex; 570 | flex-direction: column; 571 | background: #FFF; 572 | } 573 | .project-modal-thumb { 574 | width: 100%; 575 | height: auto; 576 | } 577 | .project-modal-content-container { 578 | width: 100%; 579 | height: auto; 580 | display: flex; 581 | flex-direction: column; 582 | margin: 1em; 583 | } 584 | .project-modal-title { 585 | font-size: 1.2rem; 586 | font-weight: bold; 587 | color: #333; 588 | } 589 | .project-modal-description { 590 | font-size: 0.9rem; 591 | color: #333; 592 | line-height: 1.8em; 593 | margin-top: 1em; 594 | margin-right: 2em; 595 | } 596 | .project-modal-tech-container { 597 | width: 97%; 598 | height: 2.5em; 599 | display: flex; 600 | flex-direction: row; 601 | margin-top: 0.1em; 602 | } 603 | .tech-stack-text { 604 | font-size: 1em; 605 | color: #000; 606 | font-weight: bold; 607 | margin-top: 1em; 608 | } 609 | .tech-container-div { 610 | padding: 1em; 611 | margin: 0.1em; 612 | display: flex; 613 | justify-content: center; 614 | align-items: center; 615 | border: 0.5px solid #f2f2f2; 616 | background: #f2f2f2; 617 | } 618 | .tech-span { 619 | font-size: 0.8rem; 620 | font-weight: bold; 621 | color: #333; 622 | } 623 | .project-footer-modal { 624 | width: 95%; 625 | height: 3em; 626 | display: flex; 627 | flex-direction: row; 628 | margin-top: 2em; 629 | border-top: 0.5px solid rgb(214, 214, 214); 630 | justify-content: flex-end; 631 | align-items: center; 632 | } 633 | .project-hyperlink { 634 | display: block; 635 | text-decoration: none; 636 | } 637 | .project-hide-hyperlink { 638 | display: none; 639 | } 640 | .github-hyperlink { 641 | display: block; 642 | text-decoration: none; 643 | } 644 | .github-hide-hyperlink { 645 | display: none; 646 | } 647 | .close-site-div { 648 | width: 8em; 649 | height: 2.5em; 650 | display: flex; 651 | flex-direction: row; 652 | align-items: center; 653 | margin-top: 1em; 654 | margin-right: 1em; 655 | border: 0.5px solid rgb(236, 118, 118); 656 | background: rgb(236, 118, 118); 657 | } 658 | .close-site-div:hover { 659 | width: 8em; 660 | height: 2.5em; 661 | display: flex; 662 | flex-direction: row; 663 | align-items: center; 664 | cursor: pointer; 665 | margin-top: 1em; 666 | margin-right: 1em; 667 | border: 0.5px solid rgb(238, 83, 83); 668 | background: rgb(238, 83, 83); 669 | } 670 | .close-site-icon { 671 | width: 1.2em; 672 | height: 1.2em; 673 | margin-left: 1em; 674 | } 675 | .close-site-text { 676 | font-size: 0.8rem; 677 | font-weight: bold; 678 | color: #FFF; 679 | margin-left: 1em; 680 | } 681 | .github-site-div { 682 | width: 8em; 683 | height: 2.5em; 684 | display: flex; 685 | flex-direction: row; 686 | align-items: center; 687 | margin-top: 1em; 688 | margin-right: 1em; 689 | border: 0.5px solid #000; 690 | background: #000; 691 | } 692 | .github-site-div:hover { 693 | width: 8em; 694 | height: 2.5em; 695 | display: flex; 696 | flex-direction: row; 697 | align-items: center; 698 | cursor: pointer; 699 | margin-top: 1em; 700 | margin-right: 1em; 701 | border: 0.5px solid #333; 702 | background: #333; 703 | } 704 | .github-site-icon { 705 | width: 1.2em; 706 | height: 1.2em; 707 | margin-left: 1em; 708 | } 709 | .github-site-text { 710 | font-size: 0.8rem; 711 | font-weight: bold; 712 | color: #FFF; 713 | margin-left: 1em; 714 | } 715 | .visit-site-div { 716 | width: 8em; 717 | height: 2.5em; 718 | display: flex; 719 | flex-direction: row; 720 | align-items: center; 721 | margin-top: 1em; 722 | border: 0.5px solid #4c8bf5; 723 | background: #4c8bf5; 724 | } 725 | .visit-site-div:hover { 726 | width: 8em; 727 | height: 2.5em; 728 | display: flex; 729 | flex-direction: row; 730 | align-items: center; 731 | margin-top: 1em; 732 | cursor: pointer; 733 | border: 0.5px solid #003a9e; 734 | background: #003a9e; 735 | } 736 | .visit-site-icon { 737 | width: 1.2em; 738 | height: 1.2em; 739 | margin-left: 1em; 740 | } 741 | .visit-site-text { 742 | font-size: 0.8rem; 743 | font-weight: bold; 744 | color: #FFF; 745 | margin-left: 0.8em; 746 | } 747 | .youtube-site-div { 748 | width: 10em; 749 | height: 2.5em; 750 | display: flex; 751 | flex-direction: row; 752 | align-items: center; 753 | margin-top: 1em; 754 | border: 0.5px solid #c4302b; 755 | background: #c4302b; 756 | } 757 | .youtube-site-div:hover { 758 | width: 10em; 759 | height: 2.5em; 760 | display: flex; 761 | flex-direction: row; 762 | align-items: center; 763 | margin-top: 1em; 764 | cursor: pointer; 765 | border: 0.5px solid #e24944; 766 | background: #e24944; 767 | } 768 | .youtube-site-icon { 769 | width: 1.2em; 770 | height: 1.2em; 771 | margin-left: 1em; 772 | } 773 | .youtube-site-text { 774 | font-size: 0.8rem; 775 | font-weight: bold; 776 | color: #FFF; 777 | margin-left: 0.8em; 778 | } 779 | .play-store-div { 780 | width: 10em; 781 | height: 2.5em; 782 | display: flex; 783 | justify-content: center; 784 | align-items: center; 785 | margin-top: 1em; 786 | } 787 | .play-store-icon { 788 | width: auto; 789 | height: 4em; 790 | } 791 | .skills-mobile-gap { 792 | display: none; 793 | } 794 | .projects-mobile-items-gap { 795 | display: none; 796 | } 797 | 798 | /****************************************************************************************/ 799 | 800 | @media only screen and (max-width: 1000px) { 801 | .desktop-parent-container { 802 | display: none; 803 | } 804 | .dashboard-down-arrow-container { 805 | display: none; 806 | } 807 | .mobile-parent-container { 808 | width: 100%; 809 | height: 100vh; 810 | display: flex; 811 | flex-direction: column; 812 | } 813 | .mobile-header-container { 814 | width: 100%; 815 | height: 7%; 816 | position: fixed; 817 | z-index: 1000; 818 | top: 0; 819 | display: flex; 820 | justify-content: center; 821 | align-items: center; 822 | border-bottom: 0.5px solid #646464; 823 | background: rgb(29, 29, 29); 824 | } 825 | .mobile-logo { 826 | width: auto; 827 | height: 2em; 828 | } 829 | .mobile-body-container { 830 | width: 100%; 831 | height: 100%; 832 | display: flex; 833 | justify-content: flex-start; 834 | background: rgb(255, 255, 255); 835 | } 836 | .mobile-footer-container { 837 | width: 100%; 838 | height: 3.2em; 839 | display: grid; 840 | grid-template-columns: 25% 25% 25% 25%; 841 | position: fixed; 842 | z-index: 1000; 843 | bottom: 0; 844 | border-top: 0.5px solid #646464; 845 | background: rgb(29, 29, 29); 846 | } 847 | .bottom-menu-item-container { 848 | padding: 0.5em; 849 | display: flex; 850 | justify-content: center; 851 | align-items: center; 852 | cursor: pointer; 853 | border-top: 2px solid #CCC; 854 | } 855 | .bottom-menu-item-selected-container { 856 | padding: 0.5em; 857 | display: flex; 858 | justify-content: center; 859 | align-items: center; 860 | cursor: pointer; 861 | border-top: 2px solid #c4302b; 862 | } 863 | .bottom-menu-item-txt { 864 | font-size: 1rem; 865 | color: #FFF; 866 | } 867 | .bottom-menu-selected-item-txt { 868 | font-size: 1rem; 869 | color: #e76864; 870 | } 871 | .dashboard-header-container { 872 | width: 100%; 873 | height: auto; 874 | background: #ffffff; 875 | } 876 | .dashboard-banner-img { 877 | width: 100%; 878 | height: 100%; 879 | position: fixed; 880 | background-repeat: no-repeat; 881 | background-position: center; 882 | background-size:contain; 883 | background-image: url('../images/ic_mobile_banner.png'); 884 | } 885 | .dashboard-banner-overlay { 886 | width: 100%; 887 | height: 100%; 888 | position: fixed; 889 | z-index: 1; 890 | background: #111111; 891 | opacity: 0.95; 892 | } 893 | .dashboard-profile-div { 894 | width: 100%; 895 | height: auto; 896 | position: absolute; 897 | margin-top: 5em; 898 | z-index: 10; 899 | display: flex; 900 | justify-content: center; 901 | flex-direction: column; 902 | } 903 | .dashboard-profile-img-container { 904 | width: 100%; 905 | height: 10em; 906 | display: flex; 907 | flex-direction: column; 908 | justify-content: center; 909 | align-items: center; 910 | margin-top: 2em; 911 | } 912 | .dashboard-profile-img { 913 | width: 10em; 914 | height: 10em; 915 | padding: 1px; 916 | margin-top: 3em; 917 | border: 1px solid #ddd; 918 | border-radius: 50%; 919 | background: #ffffff; 920 | position: relative; 921 | animation: profile-image-animation; 922 | animation-duration: 2s; 923 | animation-fill-mode: forwards; 924 | } 925 | .social-profile-container { 926 | height: auto; 927 | display: flex; 928 | flex-direction: row; 929 | align-items: center; 930 | margin-top: 1em; 931 | } 932 | .social-profile-icon { 933 | width: 2em; 934 | height: 2em; 935 | padding: 1em; 936 | } 937 | .dashboard-profile-details-container { 938 | width: 90%; 939 | height: auto; 940 | margin-top: 5em; 941 | margin-left: 0em; 942 | } 943 | .dashboard-profile-name-label { 944 | font-weight: 700; 945 | font-size: 1.5rem; 946 | color: white; 947 | position: relative; 948 | animation: profile-name-animation; 949 | animation-duration: 2s; 950 | animation-fill-mode: forwards; 951 | } 952 | .dashboard-profile-name { 953 | font-weight: 700; 954 | font-size: 1.5rem; 955 | color: #EA0047; 956 | position: relative; 957 | animation: profile-name-animation; 958 | animation-duration: 2s; 959 | animation-fill-mode: forwards; 960 | } 961 | .dashboard-profile-deatils { 962 | font-size: 0.95rem; 963 | color: #ffffff; 964 | line-height: 1.7em; 965 | position: relative; 966 | animation: profile-details-animation; 967 | animation-duration: 2s; 968 | animation-fill-mode: forwards; 969 | } 970 | .profile-details-link { 971 | font-size: 0.95rem; 972 | color: #ffffff; 973 | line-height: 1.7em; 974 | text-decoration: underline; 975 | position: relative; 976 | animation: profile-details-link-animation; 977 | animation-duration: 2s; 978 | animation-fill-mode: forwards; 979 | } 980 | .profile-details-link:hover { 981 | font-size: 0.95rem; 982 | color: #c7f109; 983 | line-height: 1.7em; 984 | text-decoration: underline; 985 | } 986 | .skills-mobile-gap { 987 | width: 100%; 988 | height: 5em; 989 | display: block; 990 | } 991 | .skills-parent-container { 992 | width: 100%; 993 | height: auto; 994 | display: flex; 995 | flex-direction: column; 996 | position: absolute; 997 | margin-top: 3em; 998 | margin-bottom: 0em; 999 | } 1000 | .skills-sets-container { 1001 | width: 100%; 1002 | height: auto; 1003 | display: flex; 1004 | flex-direction: row; 1005 | } 1006 | .skills-separator-container { 1007 | width: 1em; 1008 | height: auto; 1009 | display: flex; 1010 | flex-direction: column; 1011 | align-items: center; 1012 | } 1013 | .skills-separator-line { 1014 | height: 100%; 1015 | border: 0.5px solid #d8d7d7; 1016 | } 1017 | .skills-separator-circle { 1018 | width: 1em; 1019 | height: 1em; 1020 | border-radius: 50%; 1021 | display: flex; 1022 | justify-content: center; 1023 | align-items: center; 1024 | border: 1px solid #d8d7d7; 1025 | } 1026 | .skills-separator-inner-circle { 1027 | width: 0.5em; 1028 | height: 0.5em; 1029 | border-radius: 5em; 1030 | background:#d8d7d7; 1031 | } 1032 | .skills-label-container { 1033 | width: 45vw; 1034 | height: auto; 1035 | display: flex; 1036 | justify-content: center; 1037 | align-items: center; 1038 | } 1039 | .skills-label { 1040 | font-size: 0.8rem; 1041 | font-weight: bold; 1042 | color: #333; 1043 | margin-right: 0em; 1044 | } 1045 | .skills-items-container { 1046 | padding: 1em; 1047 | display: flex; 1048 | flex-direction: column; 1049 | justify-content: flex-start; 1050 | align-items: flex-start; 1051 | } 1052 | .skills-item-container { 1053 | padding-left: 1em; 1054 | padding-right: 1em; 1055 | padding-top: 0.2em; 1056 | padding-bottom: 0.2em; 1057 | margin: 0.5em; 1058 | border-radius: 5em; 1059 | border: 0.5px solid #333; 1060 | display: flex; 1061 | justify-content: center; 1062 | align-items: center; 1063 | margin-left: 0em; 1064 | display: block; 1065 | background: #333; 1066 | } 1067 | .skills-item-text { 1068 | font-size: 0.8rem; 1069 | font-weight: bold; 1070 | color: #FFF; 1071 | } 1072 | .skills-item-container-hide { 1073 | display: none; 1074 | } 1075 | .projects-parent-container { 1076 | width: 100%; 1077 | height: 100%; 1078 | display: flex; 1079 | flex-direction: column; 1080 | align-items: center; 1081 | position: absolute; 1082 | margin-top: 2.5em; 1083 | background: #FFF; 1084 | } 1085 | .project-child-container { 1086 | width: 100%; 1087 | height: auto; 1088 | } 1089 | .projects-tab-container { 1090 | width: 100%; 1091 | height: 4em; 1092 | display: grid; 1093 | position: fixed; 1094 | grid-template-columns: 33% 33% 33%; 1095 | } 1096 | .tab-container { 1097 | width: 100%; 1098 | height: 4em; 1099 | display: flex; 1100 | flex-direction: column; 1101 | justify-content: flex-end; 1102 | align-items: center; 1103 | background: #FFF; 1104 | } 1105 | .tab-container:hover { 1106 | width: 100%; 1107 | height: 4em; 1108 | display: flex; 1109 | flex-direction: column; 1110 | justify-content: flex-end; 1111 | align-items: center; 1112 | cursor: pointer; 1113 | background: #FFF; 1114 | } 1115 | .tab-label { 1116 | font-size: 1rem; 1117 | font-weight: bold; 1118 | color: #333; 1119 | margin-bottom: 1em; 1120 | } 1121 | .tab-label:hover { 1122 | font-size: 1rem; 1123 | font-weight: bold; 1124 | color: #4c8bf5; 1125 | margin-bottom: 1em; 1126 | } 1127 | .tab-selected-label { 1128 | font-size: 1rem; 1129 | font-weight: bold; 1130 | color: #4c8bf5; 1131 | margin-bottom: 1em; 1132 | } 1133 | .tab-selected { 1134 | width: 100%; 1135 | height: 0.2em; 1136 | margin: 0em; 1137 | background: #4c8bf5; 1138 | } 1139 | .tab-unselected { 1140 | width: 100%; 1141 | height: 0.2em; 1142 | margin: 0em; 1143 | background: #CCC; 1144 | } 1145 | .projects-items-container { 1146 | display: grid; 1147 | justify-content: center; 1148 | grid-template-columns: 100%; 1149 | grid-gap: 0rem; 1150 | margin-top: 0em; 1151 | margin: 0em; 1152 | padding-bottom: 0em; 1153 | } 1154 | .projects-mobile-items-gap { 1155 | width: 100%; 1156 | height: 3.5em; 1157 | display: block; 1158 | background: white; 1159 | } 1160 | .projects-thumb-img { 1161 | width: 100%; 1162 | height: auto; 1163 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 1164 | } 1165 | .projects-card-item { 1166 | display: flex; 1167 | flex-direction: column; 1168 | margin-top: 0.5em; 1169 | } 1170 | .overlay-item-container { 1171 | display: none; 1172 | } 1173 | .div-thumb-overlay { 1174 | width: 26.35em; 1175 | height: 14.8em; 1176 | position: absolute; 1177 | display: none; 1178 | justify-content: center; 1179 | } 1180 | .project-modal-container { 1181 | width: 23.5em; 1182 | height: auto; 1183 | overflow: hidden; 1184 | display: flex; 1185 | justify-content: center; 1186 | align-items: center; 1187 | flex-direction: column; 1188 | background: #FFF; 1189 | } 1190 | .project-modal-thumb { 1191 | width: 100%; 1192 | height: auto; 1193 | } 1194 | .project-modal-content-container { 1195 | width: 23em; 1196 | height: auto; 1197 | display: flex; 1198 | flex-direction: column; 1199 | margin-left: 2em; 1200 | } 1201 | .project-modal-title { 1202 | font-size: 1rem; 1203 | font-weight: bold; 1204 | color: #333; 1205 | } 1206 | .project-modal-description { 1207 | font-size: 0.7rem; 1208 | color: #333; 1209 | line-height: 1.8em; 1210 | margin-top: 1em; 1211 | margin-right: 2em; 1212 | } 1213 | .project-modal-tech-container { 1214 | width: 15em; 1215 | height: 2.5em; 1216 | display: flex; 1217 | flex-direction: row; 1218 | margin-top: 0.1em; 1219 | } 1220 | .tech-stack-text { 1221 | font-size: 0.8em; 1222 | color: #000; 1223 | font-weight: bold; 1224 | margin-top: 1em; 1225 | } 1226 | .tech-container-div { 1227 | padding: 0.8em; 1228 | margin: 0.1em; 1229 | display: flex; 1230 | justify-content: center; 1231 | align-items: center; 1232 | border: 0.5px solid #f2f2f2; 1233 | background: #f2f2f2; 1234 | } 1235 | .tech-span { 1236 | font-size: 0.7rem; 1237 | font-weight: bold; 1238 | color: #333; 1239 | } 1240 | .project-footer-modal { 1241 | width: 22em; 1242 | height: 3em; 1243 | display: flex; 1244 | flex-direction: row; 1245 | margin-top: 2em; 1246 | border-top: 0.5px solid rgb(214, 214, 214); 1247 | justify-content: flex-end; 1248 | align-items: center; 1249 | } 1250 | .project-hyperlink { 1251 | display: block; 1252 | text-decoration: none; 1253 | } 1254 | .project-hide-hyperlink { 1255 | display: none; 1256 | } 1257 | .github-hyperlink { 1258 | display: block; 1259 | text-decoration: none; 1260 | } 1261 | .github-hide-hyperlink { 1262 | display: none; 1263 | } 1264 | .close-site-div { 1265 | width: 6em; 1266 | height: 1.8em; 1267 | display: flex; 1268 | flex-direction: row; 1269 | align-items: center; 1270 | margin-top: 1em; 1271 | margin-right: 1em; 1272 | border: 0.5px solid rgb(236, 118, 118); 1273 | background: rgb(236, 118, 118); 1274 | } 1275 | .close-site-div:hover { 1276 | width: 6em; 1277 | height: 1.8em; 1278 | display: flex; 1279 | flex-direction: row; 1280 | align-items: center; 1281 | cursor: pointer; 1282 | margin-top: 1em; 1283 | margin-right: 1em; 1284 | border: 0.5px solid rgb(238, 83, 83); 1285 | background: rgb(238, 83, 83); 1286 | } 1287 | .close-site-icon { 1288 | width: 1em; 1289 | height: 1em; 1290 | margin-left: 1em; 1291 | } 1292 | .close-site-text { 1293 | font-size: 0.7rem; 1294 | font-weight: bold; 1295 | color: #FFF; 1296 | margin-left: 0.6em; 1297 | } 1298 | .github-site-div { 1299 | width: 6em; 1300 | height: 1.8em; 1301 | display: flex; 1302 | flex-direction: row; 1303 | align-items: center; 1304 | margin-top: 1em; 1305 | margin-right: 1em; 1306 | border: 0.5px solid #000; 1307 | background: #000; 1308 | } 1309 | .github-site-div:hover { 1310 | width: 6em; 1311 | height: 1.8em; 1312 | display: flex; 1313 | flex-direction: row; 1314 | align-items: center; 1315 | cursor: pointer; 1316 | margin-top: 1em; 1317 | margin-right: 1em; 1318 | border: 0.5px solid #333; 1319 | background: #333; 1320 | } 1321 | .github-site-icon { 1322 | width: 1em; 1323 | height: 1em; 1324 | margin-left: 0.8em; 1325 | } 1326 | .github-site-text { 1327 | font-size: 0.7rem; 1328 | font-weight: bold; 1329 | color: #FFF; 1330 | margin-left: 0.6em; 1331 | } 1332 | .visit-site-div { 1333 | width: 6em; 1334 | height: 1.8em; 1335 | display: flex; 1336 | flex-direction: row; 1337 | align-items: center; 1338 | margin-top: 1em; 1339 | border: 0.5px solid #4c8bf5; 1340 | background: #4c8bf5; 1341 | } 1342 | .visit-site-div:hover { 1343 | width: 6em; 1344 | height: 1.8em; 1345 | display: flex; 1346 | flex-direction: row; 1347 | align-items: center; 1348 | margin-top: 1em; 1349 | cursor: pointer; 1350 | border: 0.5px solid #003a9e; 1351 | background: #003a9e; 1352 | } 1353 | .visit-site-icon { 1354 | width: 1em; 1355 | height: 1em; 1356 | margin-left: 0.8em; 1357 | } 1358 | .visit-site-text { 1359 | font-size: 0.7rem; 1360 | font-weight: bold; 1361 | color: #FFF; 1362 | margin-left: 0.6em; 1363 | } 1364 | .youtube-site-div { 1365 | width: 8em; 1366 | height: 1.8em; 1367 | display: flex; 1368 | flex-direction: row; 1369 | align-items: center; 1370 | margin-top: 1em; 1371 | border: 0.5px solid #c4302b; 1372 | background: #c4302b; 1373 | } 1374 | .youtube-site-div:hover { 1375 | width: 8em; 1376 | height: 1.8em; 1377 | display: flex; 1378 | flex-direction: row; 1379 | align-items: center; 1380 | margin-top: 1em; 1381 | cursor: pointer; 1382 | border: 0.5px solid #e24944; 1383 | background: #e24944; 1384 | } 1385 | .youtube-site-icon { 1386 | width: 1em; 1387 | height: 1em; 1388 | margin-left: 0.8em; 1389 | } 1390 | .youtube-site-text { 1391 | font-size: 0.7rem; 1392 | font-weight: bold; 1393 | color: #FFF; 1394 | margin-left: 0.6em; 1395 | } 1396 | .play-store-div { 1397 | width: 8em; 1398 | height: 2.5em; 1399 | display: flex; 1400 | justify-content: center; 1401 | align-items: center; 1402 | margin-top: 1em; 1403 | } 1404 | .play-store-icon { 1405 | width: auto; 1406 | height: 3em; 1407 | } 1408 | .blogs-parent-container { 1409 | width: 100vw; 1410 | height: auto; 1411 | display: flex; 1412 | flex-direction: column; 1413 | align-items: center; 1414 | padding-bottom: 2em; 1415 | background: #4c8bf5; 1416 | } 1417 | .blogs-parent-contents-container { 1418 | width: 100%; 1419 | height: auto; 1420 | position: absolute; 1421 | display: flex; 1422 | flex-direction: column; 1423 | justify-content: center; 1424 | align-items: center; 1425 | background: #4c8bf5; 1426 | } 1427 | .blogs-contents-container { 1428 | width: 95vw; 1429 | height: auto; 1430 | display: flex; 1431 | flex-direction: column; 1432 | justify-content: center; 1433 | align-items: center; 1434 | } 1435 | .blogs-text { 1436 | font-size: 0.8rem; 1437 | color: #FFF; 1438 | text-align: center; 1439 | margin-top: 7em; 1440 | } 1441 | .blogs-poster-container { 1442 | width: 100%; 1443 | height: auto; 1444 | padding: 0em; 1445 | margin-top: 1em; 1446 | display: flex; 1447 | justify-content: center; 1448 | align-items: center; 1449 | } 1450 | .blogs-poster-img { 1451 | width: 100%; 1452 | height: auto; 1453 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 1454 | } 1455 | .blogs-details-link { 1456 | font-size: 0.8rem; 1457 | color: #ffffff; 1458 | line-height: 1.7em; 1459 | text-decoration: underline; 1460 | } 1461 | .blogs-details-link:hover { 1462 | font-size: 0.8rem; 1463 | color: #c7f109; 1464 | line-height: 1.7em; 1465 | text-decoration: underline; 1466 | } 1467 | } 1468 | 1469 | /***************Animation Keyframes**************/ 1470 | @keyframes profile-name-animation { 1471 | 0% {top: -100px} 1472 | 100% {top: 0px} 1473 | } 1474 | 1475 | @keyframes profile-image-animation { 1476 | 0% {left: -100px;} 1477 | 100% {left: 0px} 1478 | } 1479 | 1480 | @keyframes profile-details-animation { 1481 | 0% {bottom: -100px;} 1482 | 100% {bottom: 0px} 1483 | } 1484 | 1485 | @keyframes profile-details-link-animation { 1486 | 0% {bottom: -100px;} 1487 | 100% {bottom: 0px} 1488 | } 1489 | 1490 | @keyframes project-title { 1491 | 0% {top: -30px} 1492 | 100% {top: 0px} 1493 | } 1494 | 1495 | @keyframes project-readmore-container { 1496 | 0% {bottom: -30px;} 1497 | 100% {bottom: 0px} 1498 | } --------------------------------------------------------------------------------