mirror of
https://github.com/jambonz/next-static-site.git
synced 2025-12-19 04:47:44 +00:00
Static homepage complete
This commit is contained in:
@@ -3,6 +3,15 @@ import classNames from 'classnames';
|
||||
import * as Icons from 'react-feather';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
export function normalizeSubtext(subtext) {
|
||||
// Normalize how we work with the subtext as an array[]
|
||||
if (!Array.isArray(subtext)) {
|
||||
subtext = [subtext];
|
||||
}
|
||||
|
||||
return subtext;
|
||||
}
|
||||
|
||||
export function H1({ children }) {
|
||||
return <div className="h1">{children}</div>;
|
||||
}
|
||||
@@ -46,12 +55,15 @@ export function MXS({ children }) {
|
||||
export function Hero({ data, subStyle }) {
|
||||
const classes = {
|
||||
'hero': true,
|
||||
'pad': true,
|
||||
};
|
||||
|
||||
if (subStyle) {
|
||||
classes[`hero--${subStyle}`] = true;
|
||||
}
|
||||
|
||||
data.subtext = normalizeSubtext(data.subtext);
|
||||
|
||||
return (
|
||||
<div className={classNames(classes)}>
|
||||
<div className="wrap hero__wrap">
|
||||
@@ -59,11 +71,9 @@ export function Hero({ data, subStyle }) {
|
||||
<H1>{data.headline}</H1>
|
||||
</div>
|
||||
<div className="hero__subtext">
|
||||
{Array.isArray(data.subtext) ? data.subtext.map((subtext) => {
|
||||
{data.subtext.map((subtext) => {
|
||||
return <H5 key={nanoid()}>{subtext}</H5>;
|
||||
}) : (
|
||||
<H5>{data.subtext}</H5>
|
||||
)}
|
||||
})}
|
||||
</div>
|
||||
{data.cta && (
|
||||
<div className="hero__cta">
|
||||
|
||||
@@ -6,7 +6,7 @@ export default function KitOfParts({pageData}) {
|
||||
return (
|
||||
<div className="kop">
|
||||
{/* High-level design information */}
|
||||
<div className="hero">
|
||||
<div className="hero pad">
|
||||
<div className="wrap">
|
||||
<H1>
|
||||
<div>Kit of Parts</div>
|
||||
|
||||
@@ -19,4 +19,75 @@ tech:
|
||||
text: We work in the open, so that you can see all that we do and can gain the greatest value from our products.
|
||||
-
|
||||
title: Reliable
|
||||
text: Built by a team that has been delivering five 9’s products to telcos since VoIP was a thing.
|
||||
text: Built by a team that has been delivering five 9’s products to telcos since VoIP was a thing.
|
||||
dilemma:
|
||||
headline: "Have you found yourself asking this question:"
|
||||
subtext:
|
||||
- “Do I buy a <span>commercial</span> platform/service?
|
||||
- Or do I <span>roll my own</span> using open source?”
|
||||
tables:
|
||||
-
|
||||
title: Buy commercial
|
||||
points:
|
||||
-
|
||||
icon: XCircle
|
||||
text: expensive
|
||||
-
|
||||
icon: XCircle
|
||||
text: inflexible
|
||||
-
|
||||
icon: XCircle
|
||||
text: pay $$$ for every change
|
||||
-
|
||||
icon: XCircle
|
||||
text: EOL = end of my business
|
||||
-
|
||||
title: Roll your own
|
||||
points:
|
||||
-
|
||||
icon: CheckCircle
|
||||
text: "cheaper up front, but:"
|
||||
-
|
||||
icon: XCircle
|
||||
text: stitched-together “one off” open source = overly complex and brittle
|
||||
-
|
||||
icon: XCircle
|
||||
text: multiple dependencies to manage and track
|
||||
-
|
||||
icon: XCircle
|
||||
text:
|
||||
- solution uniqueness
|
||||
- = no community
|
||||
- = no flow of new features/fixes
|
||||
-
|
||||
icon: XCircle
|
||||
text: costly to manage over time
|
||||
-
|
||||
logo: /svg/jambonz.svg
|
||||
points:
|
||||
-
|
||||
icon: CheckCircle
|
||||
text: complete open source (MIT License)
|
||||
-
|
||||
icon: CheckCircle
|
||||
text: connect to our our cloud service OR deploy on your own infrastructure
|
||||
-
|
||||
icon: CheckCircle
|
||||
text: vibrant community of users and contributors
|
||||
-
|
||||
icon: CheckCircle
|
||||
text: designed for simplicity and integrates with your existing tech stack
|
||||
-
|
||||
icon: CheckCircle
|
||||
text: five 9's reliability coupled with excellent customer service
|
||||
byo:
|
||||
headline: The “bring your own everything” CPaaS
|
||||
subtext: Your infrastructure. Your SIP trunks. Your storage. Your cloud.
|
||||
icons:
|
||||
- Server
|
||||
- PhoneCall
|
||||
- Folder
|
||||
- Cloud
|
||||
comment: Why pay someone to upcharge you for all of that when it’s basically a one-click experience to provision all of those yourself in today's world. You know how to <a href="/#" target="_blank">click</a>, right?
|
||||
cta: Get started for free
|
||||
url: /#
|
||||
133
pages/index.js
133
pages/index.js
@@ -1,29 +1,126 @@
|
||||
import { nanoid } from 'nanoid';
|
||||
import classNames from 'classnames';
|
||||
import Layout from '../components/layout';
|
||||
import { Hero, H6, MS } from '../components/jambonz-ui';
|
||||
import { Hero, Icon, Button, H6, H5, H2, P, MS, normalizeSubtext } from '../components/jambonz-ui';
|
||||
import { getData } from '../lib/data';
|
||||
|
||||
function Tech({data}) {
|
||||
return (
|
||||
<div className="tech wrap">
|
||||
<div className="tech__image">
|
||||
<img src={data.image} />
|
||||
</div>
|
||||
<ul className="tech__notes">
|
||||
{data.notes.map((note) => {
|
||||
return (
|
||||
<li key={nanoid()} className="tech__note">
|
||||
<H6>
|
||||
<strong>{note.title}</strong>
|
||||
</H6>
|
||||
<MS>{note.text}</MS>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Dilemma({data}) {
|
||||
data.subtext = normalizeSubtext(data.subtext);
|
||||
|
||||
return (
|
||||
<div className="bg-grey dilemma pad">
|
||||
<div className="wrap dilemma__wrap">
|
||||
<div className="dilemma__headline">
|
||||
<H2>{data.headline}</H2>
|
||||
</div>
|
||||
<div className="dilemma__subtext">
|
||||
<H5>
|
||||
{data.subtext.map((subtext) => {
|
||||
{/* Use dangerouslySetInnerHTML to render inline spans from YAML data */}
|
||||
return <div key={nanoid()} dangerouslySetInnerHTML={{ __html: subtext }} />;
|
||||
})}
|
||||
</H5>
|
||||
</div>
|
||||
<div className="dilemma__tables">
|
||||
{data.tables.map((table) => {
|
||||
const classes = {
|
||||
'dilemma__table': true,
|
||||
'dilemma__table--jambonz': table.logo ? true : false,
|
||||
};
|
||||
|
||||
return (
|
||||
<div key={nanoid()} className={classNames(classes)}>
|
||||
<div className="dilemma__table__title">
|
||||
{table.logo ? <img src={table.logo} /> : <P><strong>{table.title}</strong></P>}
|
||||
</div>
|
||||
<div className="dilemma__table__points">
|
||||
{table.points.map((point) => {
|
||||
const classes = {
|
||||
'dilemma__table__point': true,
|
||||
[point.icon.toLowerCase()]: true,
|
||||
};
|
||||
|
||||
point.text = normalizeSubtext(point.text);
|
||||
|
||||
return (
|
||||
<div key={nanoid()} className={classNames(classes)}>
|
||||
<Icon name={point.icon} />
|
||||
<MS>
|
||||
{point.text.map((text) => {
|
||||
return <div key={nanoid()}>{text}</div>;
|
||||
})}
|
||||
</MS>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function BYO({data}) {
|
||||
return (
|
||||
<div className="byo pad">
|
||||
<div className="wrap byo__wrap">
|
||||
<div className="byo__headline">
|
||||
<H2>{data.headline}</H2>
|
||||
</div>
|
||||
<div className="byo__subtext">
|
||||
<H5>{data.subtext}</H5>
|
||||
</div>
|
||||
<div className="byo__icons icons">
|
||||
{data.icons.map((icon) => {
|
||||
return <Icon key={nanoid()} name={icon} style="fill" />
|
||||
})}
|
||||
</div>
|
||||
<div className="byo__comment">
|
||||
<H5>
|
||||
{/* Use dangerouslySetInnerHTML to render inline link from YAML data */}
|
||||
<div dangerouslySetInnerHTML={{ __html: data.comment }} />
|
||||
</H5>
|
||||
</div>
|
||||
<div className="byo__cta">
|
||||
<Button href={data.url} subStyle="dark" target="_blank">{data.cta}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Home({ data }) {
|
||||
return (
|
||||
<Layout siteData={data.site}>
|
||||
<Hero data={data.home.hero} subStyle="home" />
|
||||
<div className="tech wrap">
|
||||
<div className="tech__image">
|
||||
<img src={data.home.tech.image} />
|
||||
</div>
|
||||
<ul className="tech__notes">
|
||||
{data.home.tech.notes.map((note) => {
|
||||
return (
|
||||
<li key={nanoid()} className="tech__note">
|
||||
<H6>
|
||||
<strong>{note.title}</strong>
|
||||
</H6>
|
||||
<MS>{note.text}</MS>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
<Tech data={data.home.tech} />
|
||||
<Dilemma data={data.home.dilemma} />
|
||||
<BYO data={data.home.byo} />
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
192
styles/_homepage.scss
Normal file
192
styles/_homepage.scss
Normal file
@@ -0,0 +1,192 @@
|
||||
/******************************************************************************
|
||||
* App screenshot
|
||||
*******************************************************************************/
|
||||
.tech {
|
||||
display: flex;
|
||||
padding-bottom: 96px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
flex-wrap: wrap;
|
||||
padding-bottom: 64px;
|
||||
}
|
||||
|
||||
&__image {
|
||||
max-width: 66.6666666667vw;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__notes {
|
||||
max-width: 320px;
|
||||
padding-left: 16px;
|
||||
padding-top: 16px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (max-width: $width-mobile) {
|
||||
max-width: 320px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&__note {
|
||||
margin-top: 16px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
width: 50%;
|
||||
margin: 0;
|
||||
padding: 32px 16px;
|
||||
}
|
||||
|
||||
@media (max-width: $width-mobile) {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Dilemma
|
||||
*******************************************************************************/
|
||||
.dilemma {
|
||||
text-align: center;
|
||||
|
||||
&__subtext {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 64px;
|
||||
|
||||
> div {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&__tables {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
@media (max-width: $width-tablet-2) {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
&__table {
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
margin: 0 16px;
|
||||
background-color: $white;
|
||||
border: 2px solid $charcoal;
|
||||
border-radius: 8px;
|
||||
padding: 16px 32px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
margin: 0 8px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: $width-tablet-2) {
|
||||
margin: 16px 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&--jambonz {
|
||||
border-width: 4px;
|
||||
border-color: $jambonz;
|
||||
background-color: $pink;
|
||||
}
|
||||
|
||||
&__title {
|
||||
img {
|
||||
width: 50%;
|
||||
|
||||
@media (max-width: $width-tablet-2) {
|
||||
width: 96px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__title,
|
||||
&__point {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&__point {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
text-align: left;
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
svg + div {
|
||||
width: calc(100% - 16px);
|
||||
margin-top: -6px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
&.xcircle {
|
||||
svg {
|
||||
stroke: $red;
|
||||
}
|
||||
}
|
||||
|
||||
&.checkcircle {
|
||||
svg {
|
||||
stroke: $green;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* BYO
|
||||
*******************************************************************************/
|
||||
.byo {
|
||||
text-align: center;
|
||||
|
||||
&__subtext {
|
||||
margin-top: 16px;
|
||||
|
||||
> div {
|
||||
@media (max-width: $width-mobile) {
|
||||
max-width: 320px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__icons {
|
||||
margin: 64px 0;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
margin: 48px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__comment {
|
||||
> div {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&__cta {
|
||||
margin-top: 96px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
margin-top: 64px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,9 +57,17 @@
|
||||
}
|
||||
|
||||
.icons {
|
||||
margin: 0 -1.1111111111vw;
|
||||
margin: 0 -16px;
|
||||
|
||||
@media (max-width: $width-mobile) {
|
||||
margin: 0 -8px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin: 0 1.1111111111vw;
|
||||
margin: 0 16px;
|
||||
|
||||
@media (max-width: $width-mobile) {
|
||||
margin: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,13 +42,4 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.pad {
|
||||
padding-top: 64px;
|
||||
padding-bottom: 64px;
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,19 +9,26 @@
|
||||
padding-right: $width-padding;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Above the fold
|
||||
*******************************************************************************/
|
||||
.hero {
|
||||
.pad {
|
||||
padding-top: 96px;
|
||||
padding-bottom: 96px;
|
||||
text-align: center;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
padding-top: 64px;
|
||||
padding-bottom: 64px;
|
||||
}
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Above the fold
|
||||
*******************************************************************************/
|
||||
.hero {
|
||||
text-align: center;
|
||||
|
||||
&--why {
|
||||
.hero__subtext > div {
|
||||
max-width: 870px;
|
||||
@@ -73,60 +80,4 @@
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Homepage app screenshot
|
||||
*******************************************************************************/
|
||||
.tech {
|
||||
display: flex;
|
||||
padding-bottom: 96px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
flex-wrap: wrap;
|
||||
padding-bottom: 64px;
|
||||
}
|
||||
|
||||
&__image {
|
||||
max-width: 66.6666666667vw;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__notes {
|
||||
max-width: 320px;
|
||||
padding-left: 16px;
|
||||
padding-top: 16px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (max-width: $width-mobile) {
|
||||
max-width: 320px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&__note {
|
||||
margin-top: 16px;
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
width: 50%;
|
||||
margin: 0;
|
||||
padding: 32px 16px;
|
||||
}
|
||||
|
||||
@media (max-width: $width-mobile) {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,6 +163,10 @@ em {
|
||||
font-family: 'objectivitymedium_slanted';
|
||||
}
|
||||
|
||||
span {
|
||||
color: $jambonz;
|
||||
}
|
||||
|
||||
@media (max-width: $width-tablet-1) {
|
||||
font-size: $h6-size;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ $charcoal: #231f20;
|
||||
$purple: #9662b2;
|
||||
$teal: #30beb0;
|
||||
$blue: #006dff;
|
||||
$green: #008a1a;
|
||||
$red: #e10e22;
|
||||
|
||||
/******************************************************************************
|
||||
* Font sizes
|
||||
|
||||
@@ -43,6 +43,11 @@
|
||||
*******************************************************************************/
|
||||
@import 'footer.scss';
|
||||
|
||||
/******************************************************************************
|
||||
* Homepage
|
||||
*******************************************************************************/
|
||||
@import 'homepage.scss';
|
||||
|
||||
/******************************************************************************
|
||||
* Kit of Parts
|
||||
*******************************************************************************/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export default {
|
||||
path: '/docs',
|
||||
path: 'docs',
|
||||
repository: 'https://github.com/jambonz/next-static-site',
|
||||
docsRepository: 'https://github.com/jambonz/next-static-site',
|
||||
branch: 'main',
|
||||
|
||||
Reference in New Issue
Block a user