- Introduction
- 1: Setup a dev environment
- 2: Setup a project
- 3: Develop the site
- 4: Customize (guided experimentation)
- Conclusion
- Appendix
The following will take you step-by-step through the process of creating and deploying a basic, modern web app. The product in this case is a developer portfolio.
Many steps can be altered or skipped entirely, depending on your existing setup, expertise and/or preferences, but this lesson is geared toward beginners. I will assume we’re starting from scratch and will aim for simplicity. Several steps may eschew simplicity to familiarize you with current tools and/or processes.
This lesson will only cover front-end development with React. Lesson 2 will cover full-stack development using the same approach with Express and Mongo. Lesson 3 will focus on web services and DevOps with Azure.
Some of the following setup isn’t strictly necessary to complete this lesson, but will be necessary for future lessons and will prepare your system for future development.
While there are alternatives to Git, they are not as common these days. You should learn Git. To a lesser but still notable degree, Node is popular in the web dev sphere. For this lesson, both are required.
Download installer here. Yours is likely a 64-bit system. Use defaults but, if you’re on Windows, make sure to choose "use git and optional unix tools."
If you forget the step above, you will later receive a "command not found"
message. To fix,
open your terminal
and run SETX PATH "%PATH%;C:\Program Files\Git\usr\bin"
to update your PATH
variable, or
edit it in system settings.
To confirm Git installed successfully, open your terminal, type git --version
and press enter. A number should display.
Download installer here. The update PATH option should
be checked by default, but if for some reason it doesn't update you can use
where node to get Node’s path on disk and SETX PATH
like above, or just run
the installer again with the box checked.
ℹ️Note: if you’re on a Unix (Mac or Linux) system, using NVM instead of the default installer is highly recommended.
To confirm Node installed successfully, open your terminal, type
node --version
and press enter. A number should display.
You can always use the stock terminal/command-prompt, and some are decent like Powershell (Windows) and Gnome terminal (most Linux distros), but most developers end up using alternatives for the extra features and customizability.
Popular options:
ℹ️Note: Microsoft just announced a better stock terminal for Windows 10 which might be out soon, so that might be worth a look. Also, for further terminal customization in *nix environments, I recommend oh-my-zsh.
There’s a lot of options here, including just a stock text editor, however I recommend Visual Studio Code as a popular and relatively beginner-friendly option that will familiarize you with IDEs.
For this lesson you don’t need any extensions, and you can explore the extension market at your leisure, but I recommend finding yourself a linter (like TSLint) or ESlint and a code formatter (like Prettier).
If you’d like to try something different, here are some other common editors. ℹ️Note: if you go with Vim, be prepared for a steep learning curve. This game is a fun way to start learning.
Basically this is either Yarn or
NPM. In this lesson I’ll use Yarn but you’ll see NPM
used in other tutorials. To install yarn, just npm i -g yarn
.
If you want to use npm just use npm in place of yarn in any of the commands below.
You’ll also see the use of npx below, which isn’t a typo. It’s a special npm command for temporarily installing and eXecuting libraries you intend to only use once.
This makes it much easier to manage changes in your project, especially with multiple developers involved. Think of it like a thumbdrive that remembers exactly how its files have been changed over time. Even for small projects like the one in this lesson, Version Control is always recommended for project source code.
The SSH setup below is not strictly required, since you could use the HTTPS protocol and authenticate in the terminal, however you’ll later need SSH for a variety of other tasks, and employers will expect you’re familiar with it.
Simple enough: go to the join page and follow the instructions, but a quick note regarding username choice:
Some people argue it’s better to use your real name as your username if you intend to use it as part of your portfolio, sort of like using your name in the email address you put on your resume instead of your old AIM handle. I never gave it much thought, personally, but later in this lesson we will host your site for free at username.github.io so bear that in mind when choosing your username.
The steps for this vary depending on your operating system.
-
Mac and Linux: use ssh-keygen
Without going into further detail re: SSH, just know that it’s a way of protecting traffic between computers on the web, and what the steps above do is create a public key and a private key. The private key stays on your machine and shouldn’t be shared with anyone. The public key is given to the service you want to communicate with.
Follow these steps.
In this section we will generate a boilerplate React app. React is a framework created by Facebook that’s fairly popular right now.
There will likely be some new, trendy framework in a few years, but the principles and patterns of MV* architecture, statefulness, and componentization aren’t going anywhere and are transferable concepts.
Create react app is a project boilerplate generator which abstracts out a lot of typical project complexity. In our next lesson we will see what a more DIY approach looks like.
Navigate to your project directory using cd (e.g. cd ~/projects
). If this is
your first project, you can mkdir project
s and cd projects
.
Run npx create-react-app username.github.io --typescript
where "username" is
your GitHub username.
Once complete, navigate into this directory (e.g. cd my-app
) and git log
to
see that a git repo was initialized by CRA on your behalf. To escape the log
view, press Q
.
To view the boilerplate app in its current state, run yarn start and the app should serve up locally and open in your browser.
This step ensures your code changes are backed up.
Follow the steps on this page to create a remote repo on Github and make sure to not check the box to initialize the repo (if you accidentally initialize, it’s easy to delete and recreate the repo).
Next, add the remote URL
to your local repo by running
git remote add origin git@github.com:username/username.github.io.git
where
"username" is your username.
Finally, push your local repo to Github with
git push --set-upstream origin master
. If you refresh your repo page, you
should now see your latest files and commits.
Install the gh-pages library with yarn add gh-pages.
Open package.json which is at the root of the project and add the property "homepage" to point to a Github pages site like the following:
{
...
"homepage": "http://username.github.io"
...
}
If you visit this URL in the browser now, there won’t be anything to see.
Also, add two lines to "scripts"
{
...
"scripts": {
...
"predeploy": "yarn run build",
"deploy": "gh-pages -d build",
...
},
...
}
These lines define npm script aliases,
which help to simplify and organize commands and scripting in your project. For
example, the command yarn run deploy
now executes the command
gh-pages -d build
, however because "predeploy" is defined, it runs
yarn run build
prior to deploying, which is the default build command for your
app. To summarize, now whenever you yarn run deploy
, your app will build and
deploy to Github Pages.
So let’s try it. Execute yarn run deploy in your terminal. At this point, if you go to the URL of the homepage you defined above, you should see the spinning React logo.
This will be the command you use in the future to deploy updates to your site.
At this point, we should commit our changes with
git commit -am "Add deployment scripts" && git push
.
UI frameworks are not a requirement for most projects, and sometimes they can even get in the way, however many developers use them to enforce design principles in an application and/or to rapidly prototype views.
A few popular UI frameworks right now are Material (Google), Bootstrap (Twitter), and Semantic (non-profit). Each have their merits but I’ll be using Semantic UI in this lesson.
To install, run yarn add semantic-ui-react
, then just add the CSS link to the
head tag of your HTML (./public/index.html). Also, while you're there, you might
as well update the title tag to something relevant.
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<link
rel="stylesheet"
href="//cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"
/>
<title>Your Name</title>
</head>
Start by blasting the boilerplate CRA content in src/App.tsx:
import React from 'react';
import './App.css';
const App: React.FC = () => {
return (
<div className="App">
</div>
);
};
export default App;
Replace it with a call to your homepage component. We’ll call it "PageHome" to keep the component classification info at the front.
import React from 'react';
import './App.css';
import PageHome from './components/PageHome';
const App: React.FC = () => {
return (
<div className="App">
<PageHome />
</div>
);
};
export default App;
You should see an error in the terminal after saving, since the PageHome.tsx file doesn’t exist. We’ll do that next. Create a new file at src/components/PageHome.tsx and populate it with the following to start:
import React from 'react';
import './PageHome.css';
const PageHome: React.FC = () => {
return (
<div className="page-home">
<div className="centering-container">
</div>
</div>
);
};
export default PageHome;
This sets up a component consisting of just an outer page div and an inner
centering container div. The terminal will show an error until we add the CSS
file at src/components/PageHome.css
, which can look like this:
.page-home {
height: 100%;
width: 100%;
}
.centering-container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
height: 30vh;
width: 40vw;
}
At this point your homepage will render, however it will be completely blank! Next, we’ll add some content to the homepage using Semantic components:
import React from 'react';
import { Header, Icon, Container } from 'semantic-ui-react';
import './PageHome.css';
const PageHome: React.FC = () => {
return (
<div className="page-home">
<div className="centering-container">
<Header as="h2" icon textAlign="center">
<Icon name="user" circular />
<Header.Content>Your Name</Header.Content>
</Header>
<Container>
Hi, I'm so-and-so. I'm a student at Borough of Manhattan Community
College and a web app developer.
</Container>
</div>
</div>
);
};
export default PageHome;
This should show up as a blank page with your image placeholder, your name, and an introduction.
Later we’ll customize this page with your profile picture and social media buttons, but this is a start.
Technically you could create this site purely with React state hooks, however one of the fundamental assumptions of web browsers is that the URL path corresponds to the page the user is on.
For example, when you copy paste a URL into a text message, you probably expect that whoever uses the link would see the same page you do.
To preserve this behavior in a modern Single Page Application, which as its name indicates does not consist of multiple pages with different locations on the server, requires some form of routing emulation system. React router is a popular library which helps accomplish this.
To use React router we first install the dependency (and its typings file) with yarn add react-router-dom @types/react-router-dom.
Next, we need to add the BrowserRouter HoE to the entry-point file src/index.tsx:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import \* as serviceWorker from './serviceWorker';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
Next, we will need access to the router state from within the application, so we’ll need to run App through react-router’s withRouter function.
import React from 'react';
import { Switch, Route, withRouter } from 'react-router-dom';
import './App.css';
import PageHome from './components/PageHome';
const App = withRouter(props => {
const {
location: { pathname }
} = props;
console.log(pathname);
return (
<div className="App">
<Switch>
<Route exact path="/" component={PageHome} />
</Switch>
</div>
);
});
export default App;
In your browser, if you open the console you’ll see your current route being logged (right now it should be the default, "/".
Next, we must add our first route to src/App.tsx:
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import './App.css';
import PageHome from './components/PageHome';
const App: React.FC = () => {
return (
<div className="App">
<Switch>
<Route exact path="/" component={PageHome}/>
</Switch>
</div>
);
};
export default App;
This will have no perceivable effect at the moment, since "/" was the default route we were already on, but we’ll need to add more pages next, and that’s where the additional routes come in.
We’ll add a navbar to your app. These types of menus are ubiquitous and with reason: in short, while it’s cool to experiment with new approaches to layouts and UI concepts, generally good UIs are intuitive, which means predictable, and the easiest way to make something predictable is to do things the way users are already familiar with.
First, create a new root level SUI element in src/App.tsx called Menu:
import React from 'react';
import { Switch, Route, Link, withRouter } from 'react-router-dom';
import './App.css';
import PageHome from './components/PageHome';
import { Menu } from 'semantic-ui-react';
const App = withRouter(props => {
return (
<div className="App">
<Menu fixed={'top'} pointing={true} secondary={true}>
</Menu>
<Switch>
<Route exact path="/" component={PageHome} />
</Switch>
</div>
);
});
export default App;
This will appear as an empty navigation bar. We’ll need to add a menu item that corresponds to the home page route:
import React from 'react';
import { Switch, Route, Link, withRouter } from 'react-router-dom';
import './App.css';
import PageHome from './components/PageHome';
import { Menu } from 'semantic-ui-react';
const App = withRouter(props => {
const {
location: { pathname }
} = props;
return (
<div className="App">
<Menu fixed={'top'} pointing={true} secondary={true}>
<Menu.Item
active={pathname === '/'}
name="Home"
icon="home"
as={Link}
to="/"
/>
</Menu>
<Switch>
<Route exact path="/" component={PageHome} />
</Switch>
</div>
);
});
export default App;
At this point, you should see the rendered navigation bar with a new home page button:
Nice, we now have a menu, though it’s kind of sparse. Let’s add a few more pages.
We’ll start with a resume page. There are many ways you can do this, including using resume HTML templates which you can copy-paste into your react component, however I will give an example of a basic resume layout using Semantic UI.
First, create a new component at src/components/PageResume.tsx:
import React from 'react';
import { Header, Content } from 'semantic-ui-react';
const PageResume: React.FC = () => {
return (
<div className="page-resume">
<Header>Your Name</Header>
<Content>
Stuff about me
</Content>
</div>
);
};
export default PageResume;
Before continuing, let’s add the route we need to access this new page. In src/App.tsx, add an additional Route and MenuItem corresponding to our new page:
import React from 'react';
import { Switch, Route, Link, withRouter } from 'react-router-dom';
import { Menu } from 'semantic-ui-react';
import './App.css';
import PageHome from './components/PageHome';
import PageResume from './components/PageResume';
const App = withRouter(props => {
const {
location: { pathname }
} = props;
return (
<div className="App">
<Menu fixed={'top'} pointing={true} secondary={true}>
<Menu.Item
active={pathname === '/'}
name="Home"
icon="home"
as={Link}
to="/"
/>
<Menu.Item
active={pathname === '/about'}
name="About Me"
as={Link}
to="/about"
/>
</Menu>
<Switch>
<Route exact path="/" component={PageHome} />
<Route exact path="/about" component={PageResume} />
</Switch>
</div>
);
});
export default App;
At this point, our menu should start looking more like a menu:
"About" is a common page on websites, and usually contains at least a paragraph or two regarding the company, product, or individual. In this case, you could just write a couple of paragraphs about yourself and call it a day. If you have time, however, it wouldn't be a bad idea to fill this out as a complete, printable resume. In this example, we'll create a page that's a full HTML-based resume, in case that's something you're interested in.
We can use Semantic UI to map out the general structure of a typical resume:
import React from 'react';
import './PageResume.css';
import { Header, Container, Divider } from 'semantic-ui-react';
const PageResume: React.FC = () => {
return (
<div className="page-resume">
<Header as="h2" textAlign={'center'}>
Your Name
</Header>
<Container text textAlign={'left'}>
<Header as="h3">Education</Header>
</Container>
<Divider hidden />
<Container text>
<Header as="h3">Skills</Header>
</Container>
<Divider hidden />
<Container text>
<Header as="h3">Experience</Header>
</Container>
<Divider hidden />
<Container text>
<Header as="h3">Projects</Header>
</Container>
</div>
);
};
export default PageResume;
This divides the page into a title header (your name) and 4 distinct sections for education, skills, experience and projects. Resumes can be organized in a lot of ways, of course, and this is just an example, but if you're applying to your first developer job after school, odds are your actual relevant experience is limited and you'll need to emphasize education and projects (personal, research, etc).
We can also add an accompanying CSS file (src/components/PageResume.css) to adjust the page position:
.page-resume {
margin-top: 50px;
text-align: left;
}
We can fill out the content of each section with some basic HTML:
import React from 'react';
import './PageResume.css';
import { Header, Container, Divider } from 'semantic-ui-react';
const PageResume: React.FC = () => {
return (
<div className="page-resume">
<Header as="h2" textAlign={'center'}>
Your Name
</Header>
<Container text textAlign={'left'}>
<Header as="h3">Education</Header>
<p>
<strong>Borough of Manhattan Community College</strong>, New York, NY
<br />
Associate in Science, Computer Science, 2019, 3.7 GPA
</p>
</Container>
<Divider hidden />
<Container text>
<Header as="h3">Skills</Header>
<p>
<em>Coding:</em> C/C++, Java, x86 assembly, C#, PHP, Javascript, HTML,
CSS, SML, Ruby, Perl
<em>Technologies/Environment:</em> Windows, Win32 API/GUI, Linux,
MySQL, OpenGL, ASP.NET
</p>
</Container>
<Divider hidden />
<Container text>
<Header as="h3">Experience</Header>
<strong>
Artemia Health Systems, New York, NY Student Intern (Summer 2018)
</strong>
<ul>
<li>
Created new functionality for state-level prescription drug
information system
</li>
<li>Worked with end users to determine their information needs</li>
<li>Wrote application to create custom surveys</li>
<li>Migrated existing website from SQL Membership to to ASP.NET</li>
</ul>
<strong>
Borough of Manhattan Community College Computing Services Help Center,
New York, NY Student Consultant (September 2018 – Present)
</strong>
<ul>
<li>
Resolved issues regarding networking (wired, wireless, and dialup),
and email problems for Borough of Manhattan Community College users
</li>
<li>
Answered questions about software supported by the university, such
as MS Office
</li>
<li>
Communicated with customers through email, telephone, and face to
face
</li>
</ul>
</Container>
<Divider hidden />
<Container text>
<Header as="h3">Projects</Header>
<strong>
Vintage Foundation (Fall 2017) – a consulting project in a nonprofit
organization
</strong>
<ul>
<li>
Advised on new technologies to help further the organizational
mission
</li>
<li>
Instructed program director on building a user-friendly website and
relational database
</li>
<li>Assessed systemic problems and suggested possible solutions</li>
</ul>
<strong>
News Delivery System (Spring 2018) - online information
gathering/presentation system
</strong>
<ul>
<li>
Integrated old code with new for web application delivering custom
tailored web news
</li>
<li>Coded in Java using Model-View-Controller architecture</li>
</ul>
<strong>
Ebarter (Fall 2017) - an online bartering system running on Apache
Tomcat
</strong>
<ul>
<li>
Applied software engineering principles along with J2SE Web
Development Kit
</li>
<li>Led team in coding phase of development</li>
</ul>
</Container>
</div>
);
};
export default PageResume;
We now have a content-filled web page that should double as a workable resume.
You can try printing this page to see how it looks.
The projects page will be the entry-point for our project summaries.
import React from 'react';
import './PageProjects.css';
import { Container, Card, Divider } from 'semantic-ui-react';
const PageProjects: React.FC = () => {
return (
<div className="page-projects">
<Divider hidden />
<Container>
</Container>
</div>
);
};
export default PageProjects;
There are a number of ways we could organize this page, but one popular UI scheme is a card system. Cards are good at chunking summary info in an interactive way:
import React from 'react';
import './PageProjects.css';
import { Container, Card, Divider } from 'semantic-ui-react';
const PageProjects: React.FC = () => {
return (
<div className="page-projects">
<Divider hidden />
<Container>
<Card.Group centered>
<Card
header="Project #1"
meta="February 2019 - May 2019"
description="Drone-based anti-mosquito air superiority"
href={'https://github.com/username/repo-name'}
image={
'https://i.ytimg.com/vi/91gnkZGKGEY/maxresdefault.jpg'
}
/>
<Card
header="Project #2"
meta="August 2018 - January 2019"
description="Climate crisis solved using legos"
href={'https://github.com/username/repo-name'}
image={
'https://cms.qz.com/wp-content/uploads/2017/07/lego-wind-turbines_landscape_high-e1501029441183.jpg?quality=75&strip=all&w=410&h=230.55432984004415'
}
/>
<Card
header="Project #3"
meta="March 2018 - July 2018"
description="Super secret classified project (with pictures)"
href={'https://github.com/username/repo-name'}
image={
'https://i.kym-cdn.com/entries/icons/mobile/000/023/397/C-658VsXoAo3ovC.jpg'
}
/>
</Card.Group>
</Container>
</div>
);
};
export default PageProjects;
Which should result in a three-card projects group:
These cards can link directly to project pages, such as a github repo or a publication, or we could add project details within popup "modals" like this:
import React, { Component, MouseEvent } from 'react';
import './PageProjects.css';
import {
Container,
Card,
Divider,
Modal,
Header,
Button,
CardProps,
Image
} from 'semantic-ui-react';
interface PageProjectsProps {
// tslint:disable-line
}
interface PageProjectsState {
activeModal: number;
}
class PageProjects extends Component<PageProjectsProps, PageProjectsState> {
public constructor(props: PageProjectsProps, context: object) {
super(props, context);
this.state = {
activeModal: -1
};
}
protected handleModalClose = () => this.setState({ activeModal: -1 });
protected handleModalOpen = (
_: MouseEvent,
{ index: activeModal }: CardProps
) => this.setState({ activeModal });
private get modals() {
const modalConfigs = [
[
'sun',
'Drone-based anti-mosquito air superiority',
'https://i.ytimg.com/vi/91gnkZGKGEY/maxresdefault.jpg'
],
[
'superpowers',
'Climate crisis solved using legos',
'https://cms.qz.com/wp-content/uploads/2017/07/lego-wind-turbines_landscape_high-e1501029441183.jpg'
],
[
'user secret',
'Super secret classified project with pictures',
'https://static.tvtropes.org/pmwiki/pub/images/secret_squirrel_1965_shush_3766.jpg'
]
];
return modalConfigs.map(([icon, title, imgSrc], idx) => (
<Modal
key={`modal_${idx}`}
open={this.state.activeModal === idx}
onClose={this.handleModalClose}
size="small"
>
<Header icon={icon} content={`Project #${idx + 1}`} />
<Modal.Content>
<h3>{title}</h3>
<Image src={imgSrc} />
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</p>
</Modal.Content>
<Modal.Actions>
<Button
color="green"
onClick={this.handleModalClose}
icon="checkmark"
content="Got it"
inverted
/>
</Modal.Actions>
</Modal>
));
}
public render() {
return (
<div className="page-projects">
<Divider hidden />
<Container>
<Card.Group centered>
<Card
header="Project #1"
meta="February 2019 - May 2019"
index={0}
onClick={this.handleModalOpen}
description="Drone-based anti-mosquito air superiority"
image={
'https://cdn2.iconfinder.com/data/icons/gears-wheels-blades/512/gears-512.png'
}
/>
<Card
header="Project #2"
meta="August 2018 - January 2019"
index={1}
onClick={this.handleModalOpen}
description="Climate crisis solved using legos"
image={
'https://cdn2.iconfinder.com/data/icons/gears-wheels-blades/512/gears-512.png'
}
/>
<Card
header="Project #3"
meta="March 2018 - July 2018"
index={2}
onClick={this.handleModalOpen}
description="Super secret classified project with pictures"
image={
'https://cdn2.iconfinder.com/data/icons/gears-wheels-blades/512/gears-512.png'
}
/>
</Card.Group>
</Container>
{this.modals}
</div>
);
}
}
export default PageProjects;
Which would show a modal dialog when the project cards are clicked:
Here are some exercises you can try on your own. Solution examples are in the appendix.
Right now, the image on the home page is a placeholder icon. You might consider adding a picture of yourself there. How would you go about this?
Hints:
- It requires editing the PageHome.tsx file
- You will probably need to import a local image
- Alternatively, you could use an existing online pic
Bonus:
- You could use the Semantic UI Image component
An easy way to connect with your audience is via social media, and since users prefer to have everything at their fingertips, a common option for the social-media-inclined is to add buttons that link directly to relevant social media profiles. How would you go about this?
Hints:
- You'll be editing the PageHome.tsx file again
- You could use Semantic UI buttons
In this lesson we built a simple website using React, a modern single-page web application framework. A lot of web applications can be built this way.
Our next lesson will expand on what we learned here, covering full-stack development with an Express server and Mongo database for persisting data between sessions.
Lesson 3 will focus on web services and DevOps with Azure. This will expand on the concepts we learn in lesson 2 and highlight current methods for modularizing back-end functionality.
import React from 'react';
import { Header, Container, Button, Divider, Image } from 'semantic-ui-react';
import './PageHome.css';
const PageHome: React.FC = () => {
return (
<div className="page-home">
<div className="centering-container">
<Header as="h2" icon textAlign="center">
<Image
src={yourProfilePhoto}
circular={true}
style={{ height: 150, width: 150 }}
/>
<Divider hidden={true} />
<Header.Content>Your Name</Header.Content>
</Header>
<Container>
Hi, I'm so-and-so. I'm a student at Borough of Manhattan Community
College and a web app developer.
</Container>
</div>
</div>
);
};
export default PageHome;
import React from 'react';
import { Header, Container, Button, Divider, Image } from 'semantic-ui-react';
import './PageHome.css';
import yourProfilePhoto from '../images/your_pic.jpg';
const PageHome: React.FC = () => {
return (
<div className="page-home">
<div className="centering-container">
<Header as="h2" icon textAlign="center">
<Image
src={yourProfilePhoto}
circular={true}
style={{ height: 150, width: 150 }}
/>
<Divider hidden={true} />
<Header.Content>Your Name</Header.Content>
</Header>
<Container>
Hi, I'm so-and-so. I'm a student at Borough of Manhattan Community
College and a web app developer.
</Container>
<Divider />
<Container>
<Button circular color="black" icon="github" />
<Button circular color="facebook" icon="facebook" />
<Button circular color="twitter" icon="twitter" />
<Button circular color="linkedin" icon="linkedin" />
<Button circular color="instagram" icon="instagram" />
<Button circular color="purple" icon="twitch" />
</Container>
</div>
</div>
);
};
export default PageHome;