mirror of
https://github.com/rjNemo/devbook_ts
synced 2026-06-12 13:36:43 +00:00
refactor
This commit is contained in:
parent
cf0b4a2e65
commit
30676a8875
23 changed files with 93 additions and 35 deletions
|
|
@ -3,6 +3,7 @@ import {BrowserRouter} from 'react-router-dom';
|
||||||
import NavBar from './components/NavBar';
|
import NavBar from './components/NavBar';
|
||||||
import Router from './router/Router';
|
import Router from './router/Router';
|
||||||
|
|
||||||
|
/** Main App container */
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
import React, {FC} from 'react';
|
import React, {FC} from 'react';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||||
import {faCheck} from '@fortawesome/free-solid-svg-icons';
|
import {faCheck} from '@fortawesome/free-solid-svg-icons';
|
||||||
import DevSummary from '../models/DevSummary';
|
import {DevSummary} from '../models/Dev';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Present a dev profile succintly. Redirect to dev profile on click.
|
||||||
|
* @param props DevSummary object
|
||||||
|
*/
|
||||||
const DevProfile: FC<DevSummary> = ({
|
const DevProfile: FC<DevSummary> = ({
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ interface IProps {
|
||||||
icon?: string;
|
icon?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Header component displayed on form pages */
|
||||||
const FormHeader: FC<IProps> = props => (
|
const FormHeader: FC<IProps> = props => (
|
||||||
<>
|
<>
|
||||||
<Header {...props} />
|
<Header {...props} />
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,12 @@ interface IProps {
|
||||||
icon?: string;
|
icon?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header component
|
||||||
|
* @param title of the page
|
||||||
|
* @param lead description of the content
|
||||||
|
* @param icon to display (optional and default to faUser)
|
||||||
|
*/
|
||||||
const Header: FC<IProps> = ({title, lead, icon = 'faUser'}) => {
|
const Header: FC<IProps> = ({title, lead, icon = 'faUser'}) => {
|
||||||
const RenderIcon = (icon: string) => {
|
const RenderIcon = (icon: string) => {
|
||||||
if (icon === 'faUser') {
|
if (icon === 'faUser') {
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,14 @@ import React, {FC} from 'react';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||||
import {faCode} from '@fortawesome/free-solid-svg-icons';
|
import {faCode} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main Navbar serves navigation routes.
|
||||||
|
*/
|
||||||
const NavBar: FC = () => (
|
const NavBar: FC = () => (
|
||||||
<nav className="navbar bg-dark">
|
<nav className="navbar bg-dark">
|
||||||
<h1>
|
<h1>
|
||||||
<a href="dashboard.html">
|
<a href="dashboard.html">
|
||||||
<FontAwesomeIcon icon={faCode} /> {' '} DevBook
|
<FontAwesomeIcon icon={faCode} /> DevBook
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,21 @@
|
||||||
import DevSummary from '../models/DevSummary';
|
import Experience from '../types/Experience';
|
||||||
import Experience from './Experience';
|
import Education from '../types/Education';
|
||||||
import Education from './Education';
|
import Repo from '../types/Repo';
|
||||||
import Repo from './Repo';
|
|
||||||
|
|
||||||
/**Full developer profile information. extends summary to avoid duplication */
|
/** Shorter dev interface */
|
||||||
interface DevFull extends DevSummary {
|
export interface DevSummary {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
picture: string;
|
||||||
|
description: string;
|
||||||
|
location: string;
|
||||||
|
skills: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Full developer profile information.
|
||||||
|
* @extends DevSummary to avoid duplication
|
||||||
|
*/
|
||||||
|
interface Dev extends DevSummary {
|
||||||
bio: string;
|
bio: string;
|
||||||
links: Object;
|
links: Object;
|
||||||
experiences: Experience[];
|
experiences: Experience[];
|
||||||
|
|
@ -13,9 +24,9 @@ interface DevFull extends DevSummary {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sample DevFull for development and tests
|
* sample Dev for development and tests
|
||||||
*/
|
*/
|
||||||
export const dummyDevFull: DevFull = {
|
export const dummyDev: Dev = {
|
||||||
id: '0',
|
id: '0',
|
||||||
name: 'John Doe',
|
name: 'John Doe',
|
||||||
picture:
|
picture:
|
||||||
|
|
@ -92,4 +103,4 @@ export const dummyDevFull: DevFull = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
export default DevFull;
|
export default Dev;
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
interface DevSummary {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
picture: string;
|
|
||||||
description: string;
|
|
||||||
location: string;
|
|
||||||
skills: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default DevSummary;
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
import Comment from '../types/Comment';
|
import Comment from '../types/Comment';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post send by a dev
|
||||||
|
*/
|
||||||
interface Post {
|
interface Post {
|
||||||
|
id: string;
|
||||||
userID: string;
|
userID: string;
|
||||||
name: string;
|
name: string;
|
||||||
text: string;
|
text: string;
|
||||||
|
|
@ -10,7 +14,11 @@ interface Post {
|
||||||
// date: Date;
|
// date: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sample Post for development and tests
|
||||||
|
*/
|
||||||
export const dummyPost: Post = {
|
export const dummyPost: Post = {
|
||||||
|
id: '12',
|
||||||
userID: '42',
|
userID: '42',
|
||||||
picture:
|
picture:
|
||||||
'https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?s=200',
|
'https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?s=200',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import React, {FC} from 'react';
|
import React, {FC} from 'react';
|
||||||
import FormHeader from '../components/FormHeader';
|
import FormHeader from '../components/FormHeader';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form to add an Education step to Profile
|
||||||
|
*/
|
||||||
const AddEducation: FC = () => (
|
const AddEducation: FC = () => (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
<FormHeader
|
<FormHeader
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import React, {FC} from 'react';
|
import React, {FC} from 'react';
|
||||||
import FormHeader from '../components/FormHeader';
|
import FormHeader from '../components/FormHeader';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form to add an Education step to Profile
|
||||||
|
*/
|
||||||
const AddExperience: FC = () => {
|
const AddExperience: FC = () => {
|
||||||
return (
|
return (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,15 @@ import {
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import {faBlackTie} from '@fortawesome/free-brands-svg-icons';
|
import {faBlackTie} from '@fortawesome/free-brands-svg-icons';
|
||||||
import Header from '../components/Header';
|
import Header from '../components/Header';
|
||||||
import DevFull, {dummyDevFull as dev} from '../models/DevFull';
|
import Dev, {dummyDev as dev} from '../models/Dev';
|
||||||
import Experience from '../models/Experience';
|
import Experience from '../types/Experience';
|
||||||
import {getTimePeriod} from '../types/TimePeriod';
|
import {getTimePeriod} from '../types/TimePeriod';
|
||||||
import Education from '../models/Education';
|
import Education from '../types/Education';
|
||||||
|
|
||||||
const Dashboard: FC<DevFull> = () => {
|
/**
|
||||||
|
* Main page from which a Dev can peek and edit its own profile.
|
||||||
|
*/
|
||||||
|
const Dashboard: FC<Dev> = () => {
|
||||||
return (
|
return (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
<Header title="Dashboard" lead={`Welcome ${dev.name}`} />
|
<Header title="Dashboard" lead={`Welcome ${dev.name}`} />
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
import React, {FC} from 'react';
|
import React, {FC} from 'react';
|
||||||
import Header from '../components/Header';
|
import Header from '../components/Header';
|
||||||
import DevProfile from '../components/DevProfile';
|
import DevProfile from '../components/DevProfile';
|
||||||
import DevSummary from '../models/DevSummary';
|
import {DevSummary} from '../models/Dev';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Developers list page
|
||||||
|
*/
|
||||||
// const Developers: FC<DevSummary[]> = (developers) => {
|
// const Developers: FC<DevSummary[]> = (developers) => {
|
||||||
const Developers: FC = () => {
|
const Developers: FC = () => {
|
||||||
const developers: DevSummary[] = [
|
const developers: DevSummary[] = [
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import {
|
||||||
} from '@fortawesome/free-brands-svg-icons';
|
} from '@fortawesome/free-brands-svg-icons';
|
||||||
import FormHeader from '../components/FormHeader';
|
import FormHeader from '../components/FormHeader';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form to update dev's personal information.
|
||||||
|
*/
|
||||||
const EditProfile: FC = () => {
|
const EditProfile: FC = () => {
|
||||||
return (
|
return (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import React, {FC} from 'react';
|
import React, {FC} from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Landing page
|
||||||
|
*/
|
||||||
const Landing: FC = () => (
|
const Landing: FC = () => (
|
||||||
<section className="landing">
|
<section className="landing">
|
||||||
<div className="dark-overlay">
|
<div className="dark-overlay">
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ import React, {FC} from 'react';
|
||||||
import Post, {dummyPost as post} from '../models/Post';
|
import Post, {dummyPost as post} from '../models/Post';
|
||||||
import Comment from '../types/Comment';
|
import Comment from '../types/Comment';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a Post and the related comments. Shows a form to add a comment.
|
||||||
|
*/
|
||||||
const PostPage: FC<Post> = () => (
|
const PostPage: FC<Post> = () => (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
<a href="posts.html" className="btn btn-light">
|
<a href="posts.html" className="btn btn-light">
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ import Header from '../components/Header';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||||
import {faThumbsUp, faThumbsDown} from '@fortawesome/free-solid-svg-icons';
|
import {faThumbsUp, faThumbsDown} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Dev's Posts list
|
||||||
|
*/
|
||||||
const Posts: FC = () => {
|
const Posts: FC = () => {
|
||||||
const posts: Post[] = [post, post];
|
const posts: Post[] = [post, post];
|
||||||
|
|
||||||
|
|
@ -19,8 +22,8 @@ const Posts: FC = () => {
|
||||||
<textarea cols={30} rows={5} placeholder="Create a post"></textarea>
|
<textarea cols={30} rows={5} placeholder="Create a post"></textarea>
|
||||||
<input type="submit" value="Submit" className="btn btn-dark my-1" />
|
<input type="submit" value="Submit" className="btn btn-dark my-1" />
|
||||||
<div className="posts">
|
<div className="posts">
|
||||||
{posts.map((post: Post, i: number) => (
|
{posts.map((post: Post) => (
|
||||||
<div className="post bg-white p-1 my-1" key={i}>
|
<div className="post bg-white p-1 my-1" key={post.id}>
|
||||||
<div>
|
<div>
|
||||||
<a href="profile.html">
|
<a href="profile.html">
|
||||||
<img
|
<img
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,16 @@ import {
|
||||||
faEye,
|
faEye,
|
||||||
faCodeBranch,
|
faCodeBranch,
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import DevFull, {dummyDevFull as dev} from '../models/DevFull';
|
import Dev, {dummyDev as dev} from '../models/Dev';
|
||||||
import Experience from '../models/Experience';
|
import Experience from '../types/Experience';
|
||||||
import {getTimePeriod} from '../types/TimePeriod';
|
import {getTimePeriod} from '../types/TimePeriod';
|
||||||
import Education from '../models/Education';
|
import Education from '../types/Education';
|
||||||
import Repo from '../models/Repo';
|
import Repo from '../types/Repo';
|
||||||
|
|
||||||
const Profile: FC<DevFull> = () => {
|
/**
|
||||||
|
* Dev personal profile as seen by other people.
|
||||||
|
*/
|
||||||
|
const Profile: FC<Dev> = () => {
|
||||||
/** return the icon corresponding to the social name */
|
/** return the icon corresponding to the social name */
|
||||||
const renderSocialIcon = (name: string): IconDefinition => {
|
const renderSocialIcon = (name: string): IconDefinition => {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import React, {FC} from 'react';
|
import React, {FC} from 'react';
|
||||||
import Header from '../components/Header';
|
import Header from '../components/Header';
|
||||||
|
|
||||||
const SignUp: FC = () => (
|
/**
|
||||||
|
* Sign in form
|
||||||
|
*/
|
||||||
|
const SignIn: FC = () => (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
<div className="alert alert-danger">Invalid credentials</div>
|
<div className="alert alert-danger">Invalid credentials</div>
|
||||||
<Header title="Sign In" lead="Sign into your account" />
|
<Header title="Sign In" lead="Sign into your account" />
|
||||||
|
|
@ -21,4 +24,4 @@ const SignUp: FC = () => (
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default SignUp;
|
export default SignIn;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import React, {FC} from 'react';
|
import React, {FC} from 'react';
|
||||||
import Header from '../components/Header';
|
import Header from '../components/Header';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign up form
|
||||||
|
*/
|
||||||
const SignUp: FC = () => (
|
const SignUp: FC = () => (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
<Header title="Sign Up" lead="Create your account" />
|
<Header title="Sign Up" lead="Create your account" />
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import PostPage from '../pages/Post';
|
||||||
import Posts from '../pages/Posts';
|
import Posts from '../pages/Posts';
|
||||||
import * as ROUTES from '../constants/routes';
|
import * as ROUTES from '../constants/routes';
|
||||||
|
|
||||||
|
/** Register navigation paths accessible */
|
||||||
const Router: FC = () => (
|
const Router: FC = () => (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path={ROUTES.LANDING} component={Landing} />
|
<Route exact path={ROUTES.LANDING} component={Landing} />
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue