diff --git a/gatsby-config.js b/gatsby-config.js index b20f29952..5c25f77df 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -36,7 +36,7 @@ module.exports = { { // Exclude pages from the page build -- https://www.gatsbyjs.org/packages/gatsby-plugin-exclude/ resolve: 'gatsby-plugin-exclude', - options: { paths: ['/docs/README'] } + options: { paths: ['/docs/README', '/extension-uninstall'] } }, { resolve: 'gatsby-transformer-remark', diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index d8403c6be..5646a16c5 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -216,7 +216,7 @@ const Footer: React.SFC<{}> = () => (
-

Copyright © Gitpod

+

Copyright © Gitpod

Imprint | Terms of Service | Privacy Policy
diff --git a/src/components/MinimalFooter.tsx b/src/components/MinimalFooter.tsx new file mode 100644 index 000000000..282d2b69c --- /dev/null +++ b/src/components/MinimalFooter.tsx @@ -0,0 +1,45 @@ +import React from 'react' + +import styled from '@emotion/styled' +import { Link } from 'gatsby' +import { colors } from '../styles/variables' + +const StyledMinimalFooter = styled.footer` + padding: 5rem 0 6rem; + text-align: center; + color: ${colors.lightGrey}; + background: ${colors.offWhite}; + + p { + margin-bottom: 2rem; + } + + a, + .link { + color: inherit; + font-weight: 400; + } + + .link { + padding: 0 1rem; + + &:not(:last-child) { + border-right: 1px solid; + } + } +` + +const MinimalFooter = () => ( + +
+

Copyright © Gitpod

+
+ Imprint + Terms of Service + Privacy Policy +
+
+
+) + +export default MinimalFooter diff --git a/src/components/MoreInfo.tsx b/src/components/MoreInfo.tsx index 04fa41e4d..60fbaba9f 100644 --- a/src/components/MoreInfo.tsx +++ b/src/components/MoreInfo.tsx @@ -5,6 +5,12 @@ import { borders, sizes } from '../styles/variables' import { Link } from 'gatsby' import MapGrey from '../resources/map-grey.svg' +const StyledMoreInfo = styled.div<{negativeSpaceTop?: string}>` + @media(min-width: calc(${sizes.breakpoints.md} + 1px)) { + margin-top: ${({negativeSpaceTop}) => negativeSpaceTop }; + } +` + const StyledPricingLinks = styled.section` max-width: 850px; display: flex; @@ -62,9 +68,10 @@ export interface PricingLinksProps { text?: JSX.Element links?: JSX.Element backgroundShouldBeWhite?: boolean + negativeSpaceTop?: string } -const PricingLinks = ({ img, title, text, links, backgroundShouldBeWhite }: PricingLinksProps) => { +const PricingLinks = ({ img, title, text, links, backgroundShouldBeWhite, negativeSpaceTop }: PricingLinksProps) => { let Img = img let Title = title let Text = text @@ -89,9 +96,10 @@ const PricingLinks = ({ img, title, text, links, backgroundShouldBeWhite }: Pric ) } return ( -
@@ -103,7 +111,7 @@ const PricingLinks = ({ img, title, text, links, backgroundShouldBeWhite }: Pric
- + ) } diff --git a/src/components/Nav.tsx b/src/components/Nav.tsx index 1faa0e029..a87c30e8d 100644 --- a/src/components/Nav.tsx +++ b/src/components/Nav.tsx @@ -5,6 +5,8 @@ import { Link } from 'gatsby' import GitpodLogoDark from '../resources/gitpod-logo-dark.svg' import { colors, sizes, borders } from '../styles/variables' import { Global, css } from '@emotion/core' +import { getBrowser } from '../utils/helpers' +import { getBrowserString } from './gitpod-vs-codespaces/Difference' const StyledNav = styled.nav` display: flex; @@ -207,8 +209,9 @@ const StyledNav = styled.nav` } ` -const Nav = () => { +const Nav = ({ isAFlowPage, showReInstallExtensionButton }: { isAFlowPage?: boolean; showReInstallExtensionButton?: boolean }) => { const [isNavRendered, setIsNavRendered] = useState(false) + const [browser, setBrowser] = useState() const unLock = () => { if (window.innerWidth >= 1040) { @@ -218,6 +221,8 @@ const Nav = () => { useEffect(() => { window.addEventListener('resize', unLock) + let usersBrowser = getBrowser(window.navigator.userAgent) + setBrowser(getBrowserString(usersBrowser)) return () => { window.removeEventListener('resize', unLock) @@ -239,51 +244,70 @@ const Nav = () => { />
-
+
Gitpod Logo -
- Log In -
- -
-
+ + close menu icon + + + + hamburger menu icon + + + +
+
: null + } + { + showReInstallExtensionButton ? + Reinstall Extension + : null + }
- + { + !isAFlowPage ? ( + + ) : null + } diff --git a/src/components/careers/ExpandableJob.tsx b/src/components/careers/ExpandableJob.tsx index 2c32aee6b..92cb2d404 100644 --- a/src/components/careers/ExpandableJob.tsx +++ b/src/components/careers/ExpandableJob.tsx @@ -1,9 +1,11 @@ -import React, { useState } from 'react' +import React, { useState, useEffect } from 'react' import styled from '@emotion/styled' import { colors, borders } from '../../styles/variables' import Arrow from '../Arrow' import GitpodLogo from '../../resources/gitpod-logo-dark.svg' +// @ts-ignore +import hyphenate from '../../utils/hyphenate' const StyledExpandableJob = styled.div` position: relative; @@ -84,6 +86,13 @@ export interface ExpandableJobProps { const ExpandableJob = ({ title, intro, paragraphs, lists, textAfterTheLists, rendered, date }: ExpandableJobProps) => { const [isRendered, setIsRendered] = useState(rendered || false) + const hash = hash + + useEffect(() => { + if (window.location.hash === hash) { + setIsRendered(true) + } + }) const toggleIsRendered = () => { setIsRendered(!isRendered) @@ -152,7 +161,7 @@ const ExpandableJob = ({ title, intro, paragraphs, lists, textAfterTheLists, ren } return ( - + + + ) : ( +
+ Tick +

Thanks for your Feedback

+
+ ) + } + + ) +} + +export default Form diff --git a/src/components/extension-uninstall/Message.tsx b/src/components/extension-uninstall/Message.tsx new file mode 100644 index 000000000..3a0163613 --- /dev/null +++ b/src/components/extension-uninstall/Message.tsx @@ -0,0 +1,47 @@ +import React from 'react' +import Sven from '../../resources/sven.png' +import SvenName from '../../resources/sven-signature-style-name.svg' +import styled from '@emotion/styled' +import { colors } from '../../styles/variables' + +const StyledMessage = styled.blockquote` + padding: 4rem 5rem; + background: ${colors.offWhite}; + + @media(min-width: 1001px) { + min-width: 400px; + } + + .sig { + display: block; + margin-top: 1.5rem; + } + + .ceo { + display: flex; + align-items: center; + margin-top: 5rem; + + img { + height: 6rem; + margin-right: 1rem; + } + } +` + +const Message = () => ( + +

Hey there,

+

It’d be great if you could shortly let us know why you uninstalled the browser extension.

+

We’d like your feedback to understand how we can make Gitpod more useful. We’re committed to improving it, and we’re hoping to see you soon again. +

+

Best,

+ Sven +
+ Sven Efftinge +

Co-Founder & CEO

+
+
+) + +export default Message diff --git a/src/components/gitpod-vs-codespaces/Difference.tsx b/src/components/gitpod-vs-codespaces/Difference.tsx index 279f4fe04..57ab5de09 100644 --- a/src/components/gitpod-vs-codespaces/Difference.tsx +++ b/src/components/gitpod-vs-codespaces/Difference.tsx @@ -1,20 +1,11 @@ import React, { useEffect, useState } from 'react' import styled from '@emotion/styled' +import Chrome from '../../resources/chrome-logo.svg' +import Firefox from '../../resources/firefox-logo.svg' +import { getBrowser } from '../../utils/helpers' -const getBrowser = (userAgent: string) => { - const browsers = ['Opera', 'Chrome', 'Firefox', 'IE'] - let browser - - browsers.forEach((b) => { - if (userAgent.indexOf(b) !== -1) { - browser = b - } - }) - - return browser -} - -const StyledDifference = styled.section` +const StyledDifference = styled.section<{spacing?: 'small'}>` + padding: ${({spacing}) => spacing === 'small' ? '6rem 0' : ''}; text-align: center; p { @@ -22,28 +13,53 @@ const StyledDifference = styled.section` } h2 + p { - margin: 3rem 0 2rem; + max-width: 700px; + margin: 3rem auto 2rem; } .btn { - margin-bottom: 5rem; + margin: 2.5rem 0 5rem; + padding-left: 1.5rem; + + span { + display: flex; + align-items: center; + } + + img { + width: 4rem; + margin-right: 2.5rem; + } } ` -const Difference = () => { - const [browser, setBrowser] = useState() +interface DifferenceProps { + title?: string + spacing?: 'small' +} + +export const getBrowserString = (browser: any) => { + if ( browser === 'Firefox') { + return 'Firefox' + } + return 'Chrome' + } + +const Difference = ({title, spacing}: DifferenceProps) => { + const [browser, setBrowser] = useState() useEffect(() => { - setBrowser(getBrowser(window.navigator.userAgent)) + let usersBrowser = getBrowser(window.navigator.userAgent) + setBrowser(getBrowserString(usersBrowser)) }) return ( - +

- Want to See the Difference for Yourself? + {title ? title : 'Want to See the Difference for Yourself?'}

-

Add a Gitpod button to your repository.

+

Install the browser extension which adds a Gitpod button to your GitLab, GitHub and Bitbucket projects to easily spin up a dev environment with a single click.

{ target="_blank" className="btn btn--big btn--cta" > - Install Browser Extension + + {browser} + Add to {browser} +

Or prefix any GitLab, GitHub or Bitbucket URL with gitpod.io/# diff --git a/src/components/index/GetStarted.tsx b/src/components/index/GetStarted.tsx index d0e55af16..a1b74d364 100644 --- a/src/components/index/GetStarted.tsx +++ b/src/components/index/GetStarted.tsx @@ -4,7 +4,7 @@ import styled from '@emotion/styled' import { sizes } from '../../styles/variables' import { projects } from '../../contents/projects' import Project from './Project' -import PrefixInput from './PrefixInput' +import Difference from '../gitpod-vs-codespaces/Difference' const StyledGetStarted = styled.div` /* ------------------------------------------- */ @@ -12,25 +12,6 @@ const StyledGetStarted = styled.div` /* ------------------------------------------- */ .get-started { - padding-top: 0; - text-align: center; - - h3 { - font-weight: 400; - } - - &__prefix { - display: flex; - margin-bottom: 12rem; - text-align: left; - } - - h2 + p { - font-size: 2rem; - } - - /* ----- Projects ----- */ - &__projects { display: flex; justify-content: center; @@ -52,38 +33,41 @@ const StyledGetStarted = styled.div` } } } + + h3 { + text-align: center; + font-weight: 400; + } ` const GetStarted = () => ( - -

-

- Get Started -

-

- Prefix any GitLab, GitHub, or Bitbucket URL with gitpod.io/# -

- -
- -
- -

Or Try an Example Project

- -
- {projects.map((project, i) => ( - - ))} -
+
+ +
+ +

Or Try an Example Project

+
+ {projects.map((project, i) => ( + + ))} +
+
+
- ) export default GetStarted diff --git a/src/components/index/PrefixInput.tsx b/src/components/index/PrefixInput.tsx deleted file mode 100644 index 877486d2f..000000000 --- a/src/components/index/PrefixInput.tsx +++ /dev/null @@ -1,334 +0,0 @@ -import React, { useState } from 'react' - -import styled from '@emotion/styled' -import Close from '../../resources/close.svg' -import Plus from '../../resources/plus.svg' -import World from '../../resources/world.svg' -import ArrowPointer from '../../resources/arrow-pointer.svg' -import { colors, sizes } from '../../styles/variables' - -const Styled = styled.label` - display: flex; - flex-direction: column; - flex: 1; - background: #252629; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - - .header { - display: flex; - align-items: center; - padding-top: .8rem; - } - - .dots { - display: flex; - align-items: center; - padding: 0 1.5rem; - height: 100%; - - span { - display: block; - height: 15px; - width: 15px; - background: #fff; - border-radius: 50%; - - &:not(:last-of-type) { - margin-right: .7rem; - } - - &:nth-of-type(1) { - background: #FF5A52; - } - - &:nth-of-type(2) { - background: #E6C029; - } - - &:nth-of-type(3) { - background: #54C22C; - } - } - } - - .tab, - .main { - background: #36393b; - } - - .tab { - display: flex; - justify-content: space-around; - padding: 1rem; - flex: 0 0 45%; - height: 4rem; - border-top-left-radius: 10px; - border-top-right-radius: 10px; - - .bar { - flex: 0 0 85%; - } - } - - .bar { - background: #4e4e4e; - border-radius: 10rem; - } - - .new-tab { - display: flex; - margin-left: 2rem; - color: #bdbfc3; - } - - .main { - display: flex; - align-items: center; - padding: .8rem 0; - - .bar { - height: 2rem; - width: 2.8rem; - - &-container { - display: flex; - padding-left: 1.5rem; - margin-right: 1rem; - - @media(max-width: 640px) { - display: none; - } - } - - &:last-of-type { - width: 3.2rem; - } - - &:not(:last-of-type) { - margin-right: 1.2rem; - } - - } - - .input-container { - display: flex; - padding: .8rem; - flex: 1; - color: ${colors.offWhite0}; - line-height: 1; - border: 1px solid #aaa; - border-top-left-radius: 10rem; - border-bottom-left-radius: 10rem; - border-right: none; - - @media(max-width: 640px) { - margin-left: 1rem; - } - } - - .wrapper { - position: relative; - flex: 1; - - &::before { - content: url(${ArrowPointer}); - position: absolute; - bottom: -5rem; - } - - .message { - position: absolute; - bottom: -12rem; - left: 2.5rem; - display: flex; - flex-direction: column; - align-items: baseline; - - .btn { - margin-top: 2rem; - } - - @media(max-width: 829px) { - bottom: -14rem; - } - - @media(max-width: ${sizes.breakpoints.md}) { - bottom: -13rem; - } - - @media(max-width: 700px) { - bottom: -14rem; - } - - @media(max-width: 530px) { - left: -12rem; - } - - @media(max-width: 410px) { - left: -14rem; - transform: scale(.8); - } - - @media(max-width: 340px) { - left: -16rem; - bottom: -13rem; - } - } - } - - .label { - display: flex; - align-items: center; - @media(max-width: 340px) { - font-size: 90%; - } - - img { - height: 1rem; - margin: 0 1.5rem; - transform: scale(2); - } - - span { - margin-right: .3rem; - background: #3f638b; - } - } - - input { - display: block; - width: 100%; - max-width: 50rem; - padding: .3rem 0; - color: ${colors.text}; - background: ${colors.offWhite0}; - border: 2px solid ${colors.link}; - - @media(max-width: 340px) { - font-size: 90%; - } - } - - } - - .info { - height: 14rem; - background: #292c31; - border-bottom-right-radius: 3px; - } - - .btn--small { - border: 2px solid ${colors.link}; - padding: .96rem 2.3rem; - - &:hover { - border: 2px solid ${colors.lightBlue}; - } - } -` - -const errorMessage = 'Please enter a valid GitLab, GitHub, or Bitbucket repository URL' - -const PrefixInput = () => { - const [url, setUrl] = useState(`https://github.com/gitpod-io/spring-petclinic`) - const [error, setError] = useState('') - - const validateUrl = (url: string) => { - const lowerCaseUrl = url.toLowerCase() - if (lowerCaseUrl.includes('github.com')) { - return true; - } - if (lowerCaseUrl.includes('gitlab.com')) { - return true; - } - if (lowerCaseUrl.includes('bitbucket.org')) { - return true; - } - return false; - } - - const handleChange = (e: React.FormEvent) => { - const el = e.target as HTMLInputElement - if(validateUrl(el.value) || el.value == '') { - setError('') - setUrl(el.value) - } else { - setError(errorMessage) - } - } - - const handleReturn = (e: React.KeyboardEvent) => { - if(e.key === 'Enter') { - const el = e.target as HTMLInputElement - if(validateUrl(el.value)) { - window.open(`https://gitpod.io/#${el.value}`, '_blank') - setError('') - } else { - setError(errorMessage) - } - } - } - - return ( - - -
- -
-
- - https://gitpod.io/# -
- - -
- <> -

- { error ? error : 'Enter your GitLab, GitHub, or Bitbucket URL' } -

- - Start Workspace - - -
-
-
-
-
-   -
-
- ) -} - -export default PrefixInput diff --git a/src/components/index/Project.tsx b/src/components/index/Project.tsx index 969b2d586..5872f2eca 100644 --- a/src/components/index/Project.tsx +++ b/src/components/index/Project.tsx @@ -9,7 +9,7 @@ const StyledProject = styled.div` text-align: center; font-weight: 600; border: ${borders.light2}; - background: ${colors.white}; + background: ${colors.offWhite}; border-radius: 3px; min-width: 22rem; diff --git a/src/components/index/SecurityAndOSS.tsx b/src/components/index/SecurityAndOSS.tsx index d9a8ad1f7..d1ca46286 100644 --- a/src/components/index/SecurityAndOSS.tsx +++ b/src/components/index/SecurityAndOSS.tsx @@ -4,6 +4,11 @@ import TextFeature from './TextFeature' import ImageProvider from '../ImageProvider' const Styled = styled.section` + .pattern { + padding-bottom: 12rem; + margin-top: 12rem; + } + .text-container { display: flex; justify-content: center; @@ -29,7 +34,7 @@ const Styled = styled.section` const SecurityAndOSS = () => ( -
+
} diff --git a/src/components/index/TextFeature.tsx b/src/components/index/TextFeature.tsx index 133298eb0..074f2a680 100644 --- a/src/components/index/TextFeature.tsx +++ b/src/components/index/TextFeature.tsx @@ -6,7 +6,7 @@ import { colors, borders } from '../../styles/variables' const StyledTextFeature = styled.div` max-width: 600px; padding: 4rem 6rem; - background: ${colors.offWhite}; + background: ${colors.white}; border: ${borders.light}; border-radius: 3px; max-width: 450px; @@ -14,12 +14,12 @@ const StyledTextFeature = styled.div` @media (max-width: 500px) { padding: 5rem 2rem; - h3 { + .h3 { text-align: center; } } - h3 + p { + .h3 + p { margin: 0; } @@ -50,9 +50,9 @@ const TextFeature = ({ img, title, text, btnText, href }: TextFeatureProps) => (
{img}
-

+

{title} -

+

{text}

{btnText ? ( diff --git a/src/functions/submit-form.ts b/src/functions/submit-form.ts index faa1f458b..4cec7894c 100644 --- a/src/functions/submit-form.ts +++ b/src/functions/submit-form.ts @@ -6,17 +6,19 @@ export interface Email { email: string, name?: string }, - from: { + from?: { email: string, name?: string } subject: string, - message: string + message?: string, + feedback?: string, + otherFeedback?: string } async function sendEmail(client: client.MailService, email: Email): Promise<{statusCode: number, errorMessage?: string}> { const data: client.MailDataRequired = { - from: email.from, + from: email.from || '', subject: email.subject, to: [ email.to! @@ -24,7 +26,7 @@ async function sendEmail(client: client.MailService, email: Email): Promise<{sta content: [ { type: "text/plain", - value: email.message + value: `${email.message ? email.message : `${email.feedback}\n${email.otherFeedback}`}` } ] } diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index e6fdc602e..d956ea7e0 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -12,6 +12,7 @@ import LayoutRoot from '../components/LayoutRoot' import LayoutMain from '../components/LayoutMain' import Nav from '../components/Nav' import Footer from '../components/Footer' +import MinimalFooter from '../components/MinimalFooter' // import AnnoucementBanner from '../components/AnnouncementBanner' type StaticQueryProps = { @@ -24,7 +25,7 @@ type StaticQueryProps = { } } -class IndexLayout extends React.Component<{ title?: string; canonical?: string; description?: string, ogImage?:string }, {}> { +class IndexLayout extends React.Component<{ title?: string; canonical?: string; description?: string, isAFlowPage?: boolean, showReInstallExtensionButton?: boolean, ogImage?:string}, {}> { handleFirstTab = (e: any) => { if (e.key === 'Tab') { // the "I am a keyboard user" key @@ -90,7 +91,7 @@ class IndexLayout extends React.Component<{ title?: string; canonical?: string; {/* */} -