Justin Rhee 2 лет назад
Родитель
Сommit
1f9e46dfd0

+ 9 - 0
dashboard/src/assets/add-ons-dashboard.svg

@@ -0,0 +1,9 @@
+<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1 12.875L8.5 17.25L16 12.875M1 9.125L8.5 13.5L16 9.125M1 5.375L8.5 9.75L16 5.375L8.5 1L1 5.375Z" stroke="url(#paint0_linear_851_144)" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+<defs>
+<linearGradient id="paint0_linear_851_144" x1="1" y1="1" x2="16" y2="17" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F8F8F8"/>
+<stop offset="1" stop-color="#3C3C3C"/>
+</linearGradient>
+</defs>
+</svg>

+ 9 - 0
dashboard/src/assets/applications-dashboard.svg

@@ -0,0 +1,9 @@
+<svg width="35" height="34" viewBox="0 0 35 34" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12.2654 10.332V9.23203H10.0654V10.332H12.2654ZM10.0654 31.9987V33.0987H12.2654V31.9987H10.0654ZM2 9.23398C1.39249 9.23398 0.9 9.72647 0.9 10.334C0.9 10.9415 1.39249 11.434 2 11.434V9.23398ZM33.6667 11.434C34.2742 11.434 34.7667 10.9415 34.7667 10.334C34.7667 9.72647 34.2742 9.23398 33.6667 9.23398V11.434ZM30.3333 30.9H5.33333V33.1H30.3333V30.9ZM5.33333 30.9C4.09918 30.9 3.1 29.9008 3.1 28.6667H0.9C0.9 31.1158 2.88415 33.1 5.33333 33.1V30.9ZM3.1 28.6667V5.33333H0.9V28.6667H3.1ZM3.1 5.33333C3.1 4.09918 4.09918 3.1 5.33333 3.1V0.9C2.88415 0.9 0.9 2.88415 0.9 5.33333H3.1ZM5.33333 3.1H30.3333V0.9H5.33333V3.1ZM30.3333 3.1C31.5675 3.1 32.5667 4.09918 32.5667 5.33333H34.7667C34.7667 2.88415 32.7825 0.9 30.3333 0.9V3.1ZM32.5667 5.33333V28.6667H34.7667V5.33333H32.5667ZM32.5667 28.6667C32.5667 29.9008 31.5675 30.9 30.3333 30.9V33.1C32.7825 33.1 34.7667 31.1158 34.7667 28.6667H32.5667ZM10.0654 10.332V31.9987H12.2654V10.332H10.0654ZM2 11.434H33.6667V9.23398H2V11.434Z" fill="url(#paint0_linear_813_134)"/>
+<defs>
+<linearGradient id="paint0_linear_813_134" x1="2" y1="2" x2="34" y2="32" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F8F8F8"/>
+<stop offset="1" stop-color="#484849"/>
+</linearGradient>
+</defs>
+</svg>

+ 9 - 0
dashboard/src/assets/bullet.svg

@@ -0,0 +1,9 @@
+<svg width="58" height="58" viewBox="0 0 58 58" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M25.473 2.31637C26.6158 -0.772121 30.9842 -0.772125 32.127 2.31637L37.8153 17.6888C38.1746 18.6598 38.9402 19.4254 39.9112 19.7847L55.2836 25.473C58.3721 26.6158 58.3721 30.9842 55.2836 32.127L39.9112 37.8153C38.9402 38.1746 38.1746 38.9402 37.8153 39.9112L32.127 55.2836C30.9842 58.3721 26.6158 58.3721 25.473 55.2836L19.7847 39.9112C19.4254 38.9402 18.6598 38.1746 17.6888 37.8153L2.31637 32.127C-0.772121 30.9842 -0.772125 26.6158 2.31637 25.473L17.6888 19.7847C18.6598 19.4254 19.4254 18.6598 19.7847 17.6888L25.473 2.31637Z" fill="url(#paint0_linear_881_127)"/>
+<defs>
+<linearGradient id="paint0_linear_881_127" x1="28.8" y1="0" x2="58" y2="58" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#878585"/>
+</linearGradient>
+</defs>
+</svg>

+ 9 - 0
dashboard/src/assets/database-dashboard.svg

@@ -0,0 +1,9 @@
+<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14.75 4.75C14.75 6.82107 11.672 8.5 7.875 8.5C4.07804 8.5 1 6.82107 1 4.75M14.75 4.75C14.75 2.67893 11.672 1 7.875 1C4.07804 1 1 2.67893 1 4.75M14.75 4.75V8.5M1 4.75V8.5M14.75 8.5C14.75 10.5703 11.6719 12.25 7.875 12.25C4.07813 12.25 1 10.5703 1 8.5M14.75 8.5V12.25C14.75 14.3203 11.6719 16 7.875 16C4.07813 16 1 14.3203 1 12.25V8.5" stroke="url(#paint0_linear_849_138)" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+<defs>
+<linearGradient id="paint0_linear_849_138" x1="1" y1="1" x2="20.5" y2="22" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F8F8F8"/>
+<stop offset="1" stop-color="#484849" stop-opacity="0"/>
+</linearGradient>
+</defs>
+</svg>

+ 9 - 0
dashboard/src/assets/env-groups-dashboard.svg

@@ -0,0 +1,9 @@
+<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M10.1484 4.85156L5.60156 7.77344M5.60156 10.4766L10.1484 13.3984M6 9.125C6 10.5057 4.88071 11.625 3.5 11.625C2.11929 11.625 1 10.5057 1 9.125C1 7.74429 2.11929 6.625 3.5 6.625C4.88071 6.625 6 7.74429 6 9.125ZM14.75 14.75C14.75 16.1307 13.6307 17.25 12.25 17.25C10.8693 17.25 9.75 16.1307 9.75 14.75C9.75 13.3693 10.8693 12.25 12.25 12.25C13.6307 12.25 14.75 13.3693 14.75 14.75ZM14.75 3.5C14.75 4.88071 13.6307 6 12.25 6C10.8693 6 9.75 4.88071 9.75 3.5C9.75 2.11929 10.8693 1 12.25 1C13.6307 1 14.75 2.11929 14.75 3.5Z" stroke="url(#paint0_linear_851_147)" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+<defs>
+<linearGradient id="paint0_linear_851_147" x1="1" y1="1" x2="18" y2="18.5" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F8F8F8"/>
+<stop offset="1" stop-color="#464646"/>
+</linearGradient>
+</defs>
+</svg>

+ 9 - 0
dashboard/src/assets/express.svg

@@ -0,0 +1,9 @@
+<svg width="16" height="22" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1.48901 12.4316L8.47817 1.44859C8.74673 1.02657 9.4 1.2168 9.4 1.71703V9.5C9.4 9.55523 9.44477 9.6 9.5 9.6H14.4397C14.8442 9.6 15.0813 10.0553 14.8493 10.3867L7.90962 20.3005C7.62928 20.701 7 20.5027 7 20.0138V13.3C7 13.2448 6.95523 13.2 6.9 13.2H1.91084C1.51629 13.2 1.27718 12.7644 1.48901 12.4316Z" stroke="url(#paint0_linear_880_119)" stroke-width="1.6"/>
+<defs>
+<linearGradient id="paint0_linear_880_119" x1="8.2" y1="0" x2="13" y2="19" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F6F6F6"/>
+<stop offset="1" stop-color="#878585"/>
+</linearGradient>
+</defs>
+</svg>

+ 10 - 0
dashboard/src/assets/sidebar-highlight.svg

@@ -0,0 +1,10 @@
+<svg width="4" height="44" viewBox="0 0 4 44" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 0V0C2.20914 0 4 1.79086 4 4V40C4 42.2091 2.20914 44 0 44V44V0Z" fill="url(#paint0_linear_850_140)"/>
+<defs>
+<linearGradient id="paint0_linear_850_140" x1="-1.80304e-06" y1="44" x2="4" y2="3.04119e-07" gradientUnits="userSpaceOnUse">
+<stop stop-color="#3C3C3C"/>
+<stop offset="0.322917" stop-color="#757575"/>
+<stop offset="1" stop-color="#F8F8F8"/>
+</linearGradient>
+</defs>
+</svg>

+ 9 - 0
dashboard/src/assets/standard.svg

@@ -0,0 +1,9 @@
+<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M17.8 16.95L14.2923 12.8154H12.0769L10.6 11.3385L13.5538 6.90769H18.7231M5.43077 3.21538L6.99718 4.7818C7.83888 5.62349 8.09798 6.88582 7.6559 7.99102V7.99102C7.20401 9.12075 6.10984 9.86154 4.89308 9.86154H1.73846M20.2 10.6C20.2 15.9019 15.9019 20.2 10.6 20.2C5.29807 20.2 1 15.9019 1 10.6C1 5.29807 5.29807 1 10.6 1C15.9019 1 20.2 5.29807 20.2 10.6Z" stroke="url(#paint0_linear_880_126)" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
+<defs>
+<linearGradient id="paint0_linear_880_126" x1="10.6" y1="1" x2="20" y2="20" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F6F6F6"/>
+<stop offset="1" stop-color="#878585"/>
+</linearGradient>
+</defs>
+</svg>

+ 225 - 1
dashboard/src/components/AWSCostConsent.tsx

@@ -4,6 +4,10 @@ import styled from "styled-components";
 import { Context } from "shared/Context";
 import api from "shared/api";
 
+import express from "assets/express.svg";
+import standard from "assets/standard.svg";
+import bullet from "assets/bullet.svg";
+
 import Modal from "./porter/Modal";
 import Text from "./porter/Text";
 import Spacer from "./porter/Spacer";
@@ -12,6 +16,7 @@ import Button from "./porter/Button";
 import ExpandableSection from "./porter/ExpandableSection";
 import Input from "./porter/Input";
 import Link from "./porter/Link";
+import Container from "./porter/Container";
 
 type Props = {
   setCurrentStep: (step: string) => void;
@@ -24,17 +29,184 @@ const AWSCostConsent: React.FC<Props> = ({
   setShowCostConfirmModal,
   markCostConsentComplete,
 }) => {
+  const [selectedProfile, setSelectedProfile] = useState<string>("");
   const [confirmCost, setConfirmCost] = useState("");
 
+  if (selectedProfile === "") {
+    return (
+      <>
+        <Modal
+          width="700px"
+          closeModal={() => {
+            setConfirmCost("");
+            setShowCostConfirmModal(false);
+          }}
+        >
+          <Text size={16}>Select your Porter tier</Text>
+          <Spacer y={1} />
+          <Container row>
+            <ProfileWrapper onClick={() => { setSelectedProfile("express") }}>
+              <BadgeWrapper>
+                <BadgeBg />
+                <Badge>
+                  <Icon src={express} />
+                  Express
+                </Badge>
+              </BadgeWrapper>
+              <Spacer y={1} />
+              <Text>Free forever</Text>
+              <Spacer y={2} />
+              <Text>Features:</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>Unlimited resources</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>Unlimited applications</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>Unlimited builds</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>Up to 3 users</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>One-click ejection to Standard</Text>
+            </ProfileWrapper>
+            <Spacer inline width="20px" />
+            <ProfileWrapper onClick={() => { setSelectedProfile("standard") }}>
+              <BadgeWrapper>
+                <BadgeBg />
+                <Badge>
+                  <Icon src={standard} />
+                  Standard
+                </Badge>
+              </BadgeWrapper>
+              <Spacer y={1} />
+              <Text>$6/mo <Text color="helper">per GB RAM</Text></Text>
+              <Spacer height="5px" />
+              <Text>$13/mo <Text color="helper">per vCPU</Text></Text>
+              <Spacer y={1} />
+              <Text>Features:</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>Everything in Express</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>Alerts (Slack + Email)</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>GPU support</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>Preview environments</Text>
+              <Spacer y={.5} />
+              <Text color="helper"><Bullet src={bullet}></Bullet>Team permissions</Text>
+            </ProfileWrapper>
+          </Container>
+        </Modal>
+      </>
+    )
+  }
+
+  if (selectedProfile === "express") {
+    return (
+      <>
+        <Modal
+          width="700px"
+          closeModal={() => {
+            setConfirmCost("");
+            setShowCostConfirmModal(false);
+          }}
+        >
+          <Text size={16}>Porter Express AWS cost consent</Text>
+          <Spacer height="15px" />
+          <Text color="helper">
+            Porter will create the underlying infrastructure in your own AWS
+            account. You will be separately charged by AWS for this
+            infrastructure. The cost for this base infrastructure is as follows:
+          </Text>
+          <Spacer y={1} />
+          <ExpandableSection
+            noWrapper
+            expandText="[+] Show details"
+            collapseText="[-] Hide details"
+            Header={<Cost>$150? / mo</Cost>}
+            ExpandedSection={
+              <>
+                <Spacer height="15px" />
+                <Fieldset background="#1b1d2688">
+                  • Amazon Elastic Kubernetes Service (EKS) = $73/mo
+                  <Spacer height="15px" />
+                  • Amazon EC2:
+                  <Spacer height="15px" />
+                  <Tab />+ System workloads: t3.medium instance (2) = $60.74/mo
+                  <Spacer height="15px" />
+                  <Tab />+ Monitoring workloads: t3.large instance (1) = $60.74/mo
+                  <Spacer height="15px" />
+                  <Tab />+ Application workloads: t3.medium instance (1) =
+                  $30.1/mo
+                </Fieldset>
+              </>
+            }
+          />
+          <Spacer y={1} />
+          <Text color="helper">
+            The base AWS infrastructure covers up to 2 vCPU and 4GB of RAM.
+            Separate from the AWS cost, Porter charges based on your resource
+            usage.
+          </Text>
+          <Spacer inline width="5px" />
+          <Spacer y={0.5} />
+          <Link hasunderline to="https://porter.run/pricing" target="_blank">
+            Learn more about our pricing.
+          </Link>
+          <Spacer y={0.5} />
+          <Text color="helper">
+            You can use your AWS credits to pay for the underlying infrastructure,
+            and if you are a startup with less than 5M in funding, you may qualify
+            for our startup program that gives you $10k in credits.
+          </Text>
+          <Spacer y={0.5} />
+          <Link
+            hasunderline
+            to="https://gcpjnf9adme.typeform.com/to/vUg9SDWf"
+            target="_blank"
+          >
+            You can apply here.
+          </Link>
+          <Spacer y={0.5} />
+          <Text color="helper">
+            All AWS resources will be automatically deleted when you delete your
+            Porter project. Please enter the AWS base cost ("224.58") below to
+            proceed:
+          </Text>
+          <Spacer y={1} />
+          <Input
+            placeholder="224.58"
+            value={confirmCost}
+            setValue={setConfirmCost}
+            width="100%"
+            height="40px"
+          />
+          <Spacer y={1} />
+          <Button
+            disabled={confirmCost !== "224.58"}
+            onClick={() => {
+              setShowCostConfirmModal(false);
+              setConfirmCost("");
+              markCostConsentComplete();
+              setCurrentStep("credentials");
+            }}
+          >
+            Continue
+          </Button>
+        </Modal>
+      </>
+    );
+  };
+
   return (
     <>
       <Modal
+        width="700px"
         closeModal={() => {
           setConfirmCost("");
           setShowCostConfirmModal(false);
         }}
       >
-        <Text size={16}>Base AWS cost consent</Text>
+        <Text size={16}>Porter Standard AWS cost consent</Text>
         <Spacer height="15px" />
         <Text color="helper">
           Porter will create the underlying infrastructure in your own AWS
@@ -123,6 +295,58 @@ const AWSCostConsent: React.FC<Props> = ({
 
 export default AWSCostConsent;
 
+const Bullet = styled.img`
+  height: 10px;
+  margin-right: 10px;
+  margin-left: 5px;
+`;
+
+const Icon = styled.img`
+  height: 18px;
+  margin-right: 10px;
+`;
+
+const BadgeBg = styled.div`
+  position: absolute;
+  top: -1px;
+  left: -1px;
+  width: calc(100% + 2px);
+  height: 32px;
+  border-radius: 30px;
+  z-index: -1;
+  background: linear-gradient(20deg, #444550, 90%, #BEBEC1);
+`;
+
+const BadgeWrapper = styled.div`
+  position: relative;
+  z-index: 2;
+`;
+
+const Badge = styled.div`
+  height: 30px;
+  border-radius: 30px;
+  font-size: 14px;
+  background: ${({ theme }) => theme.fg};
+  display: flex;
+  align-items: center;
+  padding: 0 10px;
+  z-index: 999;
+`;
+
+const ProfileWrapper = styled.div`
+  flex: 1;
+  padding: 25px;
+  border-radius: 10px;
+  background: ${({ theme }) => theme.clickable.bg};
+  border: 1px solid #494b4f;
+  font-size: 13px;
+  cursor: pointer;
+  :hover {
+    border: ${(props) => (props.disabled ? "" : "1px solid #7a7b80")};
+  }
+  height: 400px;
+`;
+
 const Cost = styled.div`
   font-weight: 600;
   font-size: 20px;

+ 1 - 6
dashboard/src/main/home/Home.tsx

@@ -406,7 +406,7 @@ const Home: React.FC<Props> = (props) => {
                 document.body
               )}
             {/* Render sidebar when there's at least one project */}
-            {projects?.length > 0 && baseRoute !== "new-project" ? (
+            {projects?.length > 0 && baseRoute !== "new-project" && (
               <Sidebar
                 key="sidebar"
                 forceSidebar={forceSidebar}
@@ -415,11 +415,6 @@ const Home: React.FC<Props> = (props) => {
                 forceRefreshClusters={forceRefreshClusters}
                 setRefreshClusters={setForceRefreshClusters}
               />
-            ) : (
-              <DiscordButton href="https://discord.gg/34n7NN7FJ7" target="_blank">
-                <Icon src={discordLogo} />
-                Join Our Discord
-              </DiscordButton>
             )}
             <ViewWrapper id="HomeViewWrapper">
               <Navbar

+ 1 - 1
dashboard/src/main/home/add-on-dashboard/AddOnDashboard.tsx

@@ -8,7 +8,7 @@ import React, {
 import styled from "styled-components";
 import _ from "lodash";
 
-import addOn from "assets/add-ons.svg";
+import addOn from "assets/add-ons-dashboard.svg";
 import time from "assets/time.png";
 import healthy from "assets/status-healthy.png";
 import grid from "assets/grid.png";

+ 2 - 2
dashboard/src/main/home/app-dashboard/apps/Apps.tsx

@@ -2,7 +2,7 @@ import React, { useState, useContext, useCallback } from "react";
 import styled from "styled-components";
 import _ from "lodash";
 
-import web from "assets/web.png";
+import applications from "assets/applications-dashboard.svg";
 import grid from "assets/grid.png";
 import list from "assets/list.png";
 import letter from "assets/vector.svg";
@@ -309,7 +309,7 @@ const Apps: React.FC<Props> = ({}) => {
     <StyledAppDashboard>
       {!currentDeploymentTarget?.preview && (
         <DashboardHeader
-          image={web}
+          image={applications}
           title="Applications"
           description="Web services, workers, and jobs for this project."
           disableLineBreak

+ 1 - 1
dashboard/src/main/home/cluster-dashboard/env-groups/EnvGroupDashboard.tsx

@@ -1,7 +1,7 @@
 import React, { Component, useContext, useEffect, useState } from "react";
 import styled from "styled-components";
 
-import sliders from "assets/env-groups.svg";
+import sliders from "assets/env-groups-dashboard.svg";
 
 import { Context } from "shared/Context";
 import { ClusterType } from "shared/types";

+ 1 - 1
dashboard/src/main/home/database-dashboard/DatabaseDashboard.tsx

@@ -14,7 +14,7 @@ import list from "assets/list.png";
 import healthy from "assets/status-healthy.png";
 import letter from "assets/vector.svg";
 import calendar from "assets/calendar-number.svg";
-import database from "assets/database.svg";
+import database from "assets/database-dashboard.svg";
 import notFound from "assets/not-found.png";
 
 import { Context } from "shared/Context";