Merge pull request #891 from SkynetLabs/clean-up-webapp-directory-and-update-deps

clean up webapp directory and update some deps
This commit is contained in:
Matthew Sevey 2021-06-21 17:22:25 -04:00 committed by GitHub
commit f6e1ce56fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
107 changed files with 4130 additions and 10471 deletions

View File

@ -1,47 +0,0 @@
name: Continous Integration
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 15.x
- name: Install dependencies
run: yarn
- name: "Static code analysis: handshake-api"
run: yarn workspace handshake-api prettier --check .
- name: "Static code analysis: health-check"
run: yarn workspace health-check prettier --check .
- name: "Static code analysis: website"
run: yarn workspace website prettier --check .
- name: "Static code analysis: dashboard"
run: yarn workspace dashboard prettier --check .
# - name: "Build webapp"
# run: yarn workspace webapp build
# env:
# GATSBY_API_URL: "https://siasky.net"
# - name: Cypress run
# uses: cypress-io/github-action@v2
# env:
# CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# working-directory: packages/webapp
# record: true
# start: npx http-server public --port 8000
# wait-on: "http://localhost:8000"
# - name: Cypress cache prune
# run: yarn cypress cache prune

View File

@ -0,0 +1,28 @@
name: Static Code Analysis
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- name: Install dependencies
run: yarn
- name: "Static code analysis: handshake-api"
run: yarn workspace handshake-api prettier --check .
- name: "Static code analysis: health-check"
run: yarn workspace health-check prettier --check .
- name: "Static code analysis: website"
run: yarn workspace website prettier --check .
- name: "Static code analysis: dashboard"
run: yarn workspace dashboard prettier --check .

4
.gitignore vendored
View File

@ -69,8 +69,8 @@ yarn-error.log
.yarn-integrity
# Cypress
packages/webapp/cypress/screenshots
packages/webapp/cypress/videos
packages/website/cypress/screenshots
packages/website/cypress/videos
# Docker data
docker/data

View File

@ -2,14 +2,14 @@
## Web application
Use `yarn workspace webapp start` to start the development server.
Use `yarn workspace website start` to start the development server.
Use `yarn workspace webapp build` to compile the application to `/public` directory.
Use `yarn workspace website build` to compile the application to `/public` directory.
You can use the below build parameters to customize your web application.
- development example `GATSBY_API_URL=https://siasky.dev yarn workspace webapp start`
- production example `GATSBY_API_URL=https://siasky.net yarn workspace webapp build`
- development example `GATSBY_API_URL=https://siasky.dev yarn workspace website start`
- production example `GATSBY_API_URL=https://siasky.net yarn workspace website build`
List of available parameters:
@ -36,8 +36,8 @@ Mongo needs a couple of extra steps in order to start a secure cluster.
- Manually run an initialisation `docker run` with extra environment variables that will initialise the admin user with
a password (example below).
- During the initialisation run mentioned above, we need to make two extra steps within the container:
- Change the ownership of `mgkey` to `mongodb:mongodb`
- Change its permissions to 400
- Change the ownership of `mgkey` to `mongodb:mongodb`
- Change its permissions to 400
- After these steps are done we can open a mongo shell on the primary node and run `rs.add()` in order to add the new
node to the cluster. If you don't know which node is primary, log onto any server and jump into the Mongo's container
(`docker exec -it mongo mongo -u admin -p`) and then get the status of the replica set (`rs.status()`).
@ -185,8 +185,8 @@ Before pushing your code, you should verify that it will pass our online test su
**Cypress Tests**
Verify the Cypress test suite by doing the following:
1. In one terminal screen run `GATSBY_API_URL=https://siasky.net yarn workspace webapp start`
1. In a second terminal screen run `yarn workspace webapp cypress run`
1. In one terminal screen run `GATSBY_API_URL=https://siasky.net yarn workspace website serve`
1. In a second terminal screen run `yarn workspace website cypress run`
## Setting up complete skynet server

View File

@ -3,12 +3,5 @@
"license": "SEE LICENSE IN LICENSE.md",
"workspaces": [
"packages/*"
],
"dependencies": {
"@tailwindcss/forms": "^0.2.1",
"autoprefixer": "^10.2.4",
"postcss": "^8.2.6",
"sharp": "^0.27.2",
"tailwindcss": "^2.0.4"
}
]
}

View File

@ -23,13 +23,12 @@
"http-status-codes": "2.1.4",
"ky": "0.25.1",
"next": "10.2.3",
"postcss": "8.2.14",
"postcss": "8.3.5",
"prettier": "2.3.1",
"pretty-bytes": "5.6.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"skynet-js": "3.0.2",
"square": "11.0.0",
"stripe": "8.156.0",
"superagent": "6.1.0",
"swr": "0.5.6",

View File

@ -1,22 +0,0 @@
{
"env": {
"browser": true,
"es6": true,
"cypress/globals": true,
"node": true
},
"extends": ["prettier", "eslint:recommended", "plugin:react/recommended"],
"settings": {
"react": {
"version": "detect"
}
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": ["react", "cypress"]
}

View File

@ -1,4 +0,0 @@
# gatsby files
.cache/
public
package-lock.json

View File

@ -1,5 +0,0 @@
/.cache
/package.json
/package-lock.json
/public
/docker/data

View File

@ -1,3 +0,0 @@
{
"printWidth": 120
}

View File

@ -1,24 +0,0 @@
FROM node:16.1.0-alpine
RUN apk update && apk add autoconf automake libtool gcc make g++ zlib-dev file nasm util-linux
WORKDIR /usr/app
COPY package.json .
ENV CYPRESS_INSTALL_BINARY 0
RUN yarn --no-lockfile
COPY src ./src
COPY static ./static
COPY gatsby-config.js .
ARG WITH_ACCOUNTS=0
ENV GATSBY_TELEMETRY_DISABLED 1
ENV GATSBY_WITH_ACCOUNTS $WITH_ACCOUNTS
EXPOSE 9000
CMD [ "sh", "-c", "yarn build && yarn serve --host 0.0.0.0" ]

View File

@ -1,5 +0,0 @@
{
"baseUrl": "http://127.0.0.1:8000",
"projectId": "6qp3um",
"videoUploadOnPasses": false
}

View File

@ -1,3 +0,0 @@
{
"ok": true
}

View File

@ -1,37 +0,0 @@
/// <reference types="cypress" />
context("Skynet", () => {
beforeEach(() => {
cy.visit("");
});
it("should render key website elements", () => {
cy.contains("Build a Free Internet");
cy.contains("Upload your Files");
cy.contains("Have a Skylink?");
});
it("should be able to upload a file", () => {
cy.intercept("POST", "/skynet/skyfile").as("upload");
const fileName = "check.json";
cy.wait(1000); // delay for drag-and-drop to work properly every time
cy.get('.home-upload input[type="file"]').attachFile(fileName, { subjectType: "drag-n-drop" });
cy.get(".home-upload").scrollIntoView();
cy.get(".home-uploaded-files").children().should("have.length", 1);
// wait max 2 minutes, the portal might be slow at times
cy.wait("@upload", { responseTimeout: 2 * 60 * 1000 });
cy.contains(".upload-file", fileName).within(() => {
cy.get(".url")
.invoke("text")
.should("match", /\/[a-zA-Z0-9-_]{46}/);
cy.contains("Copy Link").click();
cy.contains("Copied!").should("be.visible");
});
});
});

View File

@ -1,18 +0,0 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* @type {Cypress.PluginConfig}
*/
module.exports = () => {};

View File

@ -1,27 +0,0 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
import "cypress-file-upload";

View File

@ -1,16 +0,0 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
import "./commands";

View File

@ -1,55 +0,0 @@
const { defaultIcons } = require("gatsby-plugin-manifest/common");
module.exports = {
siteMetadata: {
title: `Skynet`,
description: `Skynet is a decentralized file sharing and content distribution protocol.`,
author: `Nebulous`,
siteUrl: `https://siasky.net`,
image: `https://siasky.net/icons/icon-512x512.png`,
},
plugins: [
`gatsby-plugin-sass`,
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
`gatsby-plugin-robots-txt`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `Skynet`,
short_name: `Skynet`,
start_url: `/`,
background_color: `#f1f7f2`,
theme_color: `#f1f7f2`,
display: `minimal-ui`,
icon: `src/images/logo.svg`, // This path is relative to the root of the site.
icons: [
...defaultIcons,
// when we're serving content from the portal on our pathnames that do not have
// favicon defined (basically all non-html content), we want the browsers to be
// able to fall back to favicon.ico (firefox does that)
{
src: `favicon.ico`,
sizes: `32x32`,
type: `image/x-icon`,
},
],
},
},
{
resolve: "gatsby-plugin-matomo",
options: {
siteId: 3,
matomoUrl: "https://surveillance.sia.tech",
siteUrl: "https://siasky.net",
},
},
`gatsby-plugin-remove-serviceworker`,
],
};

View File

@ -1,84 +0,0 @@
{
"name": "webapp",
"description": "Sia Skynet",
"version": "1.0.0",
"author": "Nebulous",
"dependencies": {
"@fontsource/metropolis": "^4.2.1",
"axios": "0.21.1",
"boolean": "^3.0.2",
"bytes": "3.1.0",
"classnames": "2.3.1",
"gatsby": "^3.0.4",
"gatsby-plugin-manifest": "^3.0.0",
"gatsby-plugin-matomo": "0.9.0",
"gatsby-plugin-react-helmet": "^4.0.0",
"gatsby-plugin-remove-serviceworker": "1.0.0",
"gatsby-plugin-robots-txt": "1.5.6",
"gatsby-plugin-sass": "^4.0.2",
"gatsby-source-filesystem": "^3.0.0",
"http-status-codes": "2.1.4",
"js-cookie": "^2.2.1",
"jsonp": "0.2.1",
"node-sass": "5.0.0",
"path-browserify": "1.0.1",
"prop-types": "15.7.2",
"react": "17.0.1",
"react-countup": "4.3.3",
"react-dom": "17.0.1",
"react-dropzone": "11.3.2",
"react-helmet": "6.1.0",
"react-mailchimp-form": "1.0.2",
"react-mailchimp-subscribe": "^2.1.3",
"react-syntax-highlighter": "15.4.3",
"react-visibility-sensor": "5.1.1",
"skynet-js": "3.0.2"
},
"devDependencies": {
"cypress": "^7.1.0",
"cypress-file-upload": "5.0.7",
"eslint": "7.26.0",
"eslint-config-prettier": "8.2.0",
"eslint-plugin-cypress": "2.11.2",
"eslint-plugin-react": "7.23.2",
"husky": "4.3.8",
"lint-staged": "10.5.4",
"prettier": "2.2.1"
},
"keywords": [
"sia",
"skynet",
"nebulous",
"blockchain",
"decentralized",
"cloud storage"
],
"license": "SEE LICENSE IN LICENSE.md",
"scripts": {
"build": "gatsby build",
"start": "gatsby develop",
"serve": "gatsby serve",
"clean": "gatsby clean"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{md,html,css,scss}": [
"prettier --write"
]
},
"repository": {
"type": "git",
"url": "https://github.com/NebulousLabs/skynet-webportal"
},
"bugs": {
"url": "https://github.com/NebulousLabs/skynet-webportal/issues"
}
}

View File

@ -1,3 +0,0 @@
import { createContext } from "react";
export default createContext(null);

View File

@ -1,34 +0,0 @@
import React from "react";
import TopSwoosh from "../../svg/TopSwoosh";
import "./App.scss";
import StickyTopMessage from "../StickyTopMessage/StickyTopMessage";
import { HomeTop, HomeUpload, HomeBuilt, HomeSamples, HomeStay, HomeNetwork, Footer } from "../";
function App() {
return (
<React.Fragment>
<StickyTopMessage />
<div className="app">
<TopSwoosh className="top-swoosh" />
<div className="width">
<HomeTop />
<HomeUpload />
<HomeBuilt />
<HomeSamples />
</div>
<div className="home-white">
<div className="width">
<HomeStay />
<HomeNetwork />
</div>
</div>
<Footer />
</div>
</React.Fragment>
);
}
export default App;

View File

@ -1,30 +0,0 @@
@import "../../variables.scss";
.app {
position: relative;
overflow-x: hidden;
max-width: 100%;
}
.top-swoosh {
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
margin-left: 340px;
width: 622px;
max-width: none;
@media (min-width: $largebp) {
margin-left: 380px;
}
}
.home-white {
background: $white;
padding: 80px 0;
@media (min-width: $largebp) {
padding: 120px 0;
}
}

View File

@ -1,28 +0,0 @@
import React from "react";
import classNames from "classnames";
import "./Button.scss";
export default function Button({ href, type, children, full, className, iconLeft, iconRight, ...rest }) {
const classes = classNames("button", { iconLeft, iconRight, full }, className);
if (href) {
return (
<a href={href} className={classes} {...rest}>
{children}
</a>
);
} else if (type) {
return (
<button type={type} className={classes} {...rest}>
{children}
</button>
);
} else {
return (
<button type="button" className={classes} {...rest}>
{children}
</button>
);
}
}

View File

@ -1,36 +0,0 @@
@import "../../variables.scss";
.button {
display: inline-block;
background: $green;
color: $white;
border-radius: 4px;
box-shadow: 0 0 16px 0 rgba(87, 181, 96, 0.1);
line-height: 48px;
font-weight: bold;
padding: 0 32px;
transition: 0.2s background-color, 0.2s color, 0.2s transform;
@media (min-width: $largebp) {
font-size: 18px;
}
&:hover {
background-color: $greenHover;
transform: translateY(-2px);
}
svg {
display: inline-block;
vertical-align: middle;
margin-top: -2px;
}
&.iconLeft svg {
margin-right: 12px;
}
&.iconRight svg {
margin-left: 12px;
}
}

View File

@ -1,11 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import "./CircleIcon.scss";
export default function CircleIcon({ children }) {
return <div className="circle-icon">{children}</div>;
}
CircleIcon.propTypes = {
children: PropTypes.node,
};

View File

@ -1,10 +0,0 @@
.circle-icon {
width: 64px;
height: 64px;
border-radius: 32px;
box-shadow: 0 0 8px 0 rgba(23, 25, 23, 0.2);
border: solid 2px currentColor;
display: flex;
align-items: center;
justify-content: center;
}

View File

@ -1,80 +0,0 @@
export const curl = `# upload
curl -X POST "https://siasky.net/skynet/skyfile" -F "file=@src.jpg"
# download
curl "https://siasky.net/[skylink]" -o dst.jpg`;
export const browserjs = `import { SkynetClient } from "skynet-js";
// create a client
const client = new SkynetClient();
// Assume we have a file from an input form.
async function example() {
try {
// upload
const { skylink } = await client.uploadFile(file);
console.log(\`Upload successful, skylink: \${skylink}\`);
// download
await client.downloadFile(skylink);
console.log('Download successful');
} catch (error) {
console.log(error)
}
}`;
export const python = `import siaskynet as skynet
# create a client
client = skynet.SkynetClient()
# upload
skylink = client.upload_file("./src.jpg")
print("Upload successful, skylink: " + skylink)
# download
client.download_file("./dst.jpg", skylink)
print("Download successful")`;
export const node = `const { SkynetClient } = require('@nebulous/skynet');
// create a client
const client = new SkynetClient();
(async () => {
// upload
const skylink = await client.uploadFile("./src.jpg");
console.log(\`Upload successful, skylink: \${skylink}\`);
// download
await client.downloadFile("./dst.jpg", skylink);
console.log('Download successful');
})()`;
export const go = `package main
import (
"fmt"
skynet "github.com/NebulousLabs/go-skynet/v2"
)
// create a client
var client = skynet.New()
func main() {
// upload
skylink, err := client.UploadFile("./src.jpg", skynet.DefaultUploadOptions)
if err != nil {
panic("Unable to upload: " + err.Error())
}
fmt.Printf("Upload successful, skylink: %v\\n", skylink)
// download
err = client.DownloadFile("./dst.jpg", skylink, skynet.DefaultDownloadOptions)
if err != nil {
panic("Something went wrong, please try again.\\nError: " + err.Error())
}
fmt.Println("Download successful")
}`;

View File

@ -1,74 +0,0 @@
import React, { useState, useContext } from "react";
import classNames from "classnames";
import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
import { javascript, go, python, bash } from "react-syntax-highlighter/dist/esm/languages/hljs";
import Colors from "./Colors";
import * as snippets from "./Code";
import "./CodeExamples.scss";
import AppContext from "../../AppContext";
SyntaxHighlighter.registerLanguage("javascript", javascript);
SyntaxHighlighter.registerLanguage("go", go);
SyntaxHighlighter.registerLanguage("python", python);
SyntaxHighlighter.registerLanguage("bash", bash);
export default function CodeExamples() {
const [active, setActive] = useState(1);
const { apiUrl } = useContext(AppContext);
const interpolateRegExp = new RegExp("https://siasky.net", "g");
const interpolateSnippet = (snippet) => snippet.replace(interpolateRegExp, apiUrl);
return (
<div className="code-examples">
<div className="code-examples-tabs">
<button type="button" onClick={() => setActive(1)} className={classNames({ active: active === 1 })}>
CURL
</button>
<button type="button" onClick={() => setActive(2)} className={classNames({ active: active === 2 })}>
BrowserJS
</button>
<button type="button" onClick={() => setActive(3)} className={classNames({ active: active === 3 })}>
Python
</button>
<button type="button" onClick={() => setActive(4)} className={classNames({ active: active === 4 })}>
Node.js
</button>
<button type="button" onClick={() => setActive(5)} className={classNames({ active: active === 5 })}>
Go
</button>
</div>
<div className="code-examples-body">
{active === 1 && (
<SyntaxHighlighter wrapLines showLineNumbers={true} language="bash" style={Colors}>
{interpolateSnippet(snippets.curl)}
</SyntaxHighlighter>
)}
{active === 2 && (
<SyntaxHighlighter wrapLines showLineNumbers={true} language="javascript" style={Colors}>
{interpolateSnippet(snippets.browserjs)}
</SyntaxHighlighter>
)}
{active === 3 && (
<SyntaxHighlighter wrapLines showLineNumbers={true} language="python" style={Colors}>
{interpolateSnippet(snippets.python)}
</SyntaxHighlighter>
)}
{active === 4 && (
<SyntaxHighlighter wrapLines showLineNumbers={true} language="javascript" style={Colors}>
{interpolateSnippet(snippets.node)}
</SyntaxHighlighter>
)}
{active === 5 && (
<SyntaxHighlighter wrapLines showLineNumbers={true} language="go" style={Colors}>
{interpolateSnippet(snippets.go)}
</SyntaxHighlighter>
)}
</div>
</div>
);
}

View File

@ -1,69 +0,0 @@
@import "../../variables.scss";
.code-examples-tabs {
border-top-left-radius: 12px;
border-top-right-radius: 12px;
display: flex;
align-items: flex-end;
height: 65px;
button {
display: block;
flex: 1;
color: $white60;
line-height: 57px;
padding: 0 16px;
cursor: pointer;
user-select: none;
background-color: #343734;
transition: 0.2s line-height, 0.2s background-color, 0.2s color;
text-align: center;
font-size: 14px;
@media (min-width: 360px) {
font-size: 16px;
}
@media (min-width: $largebp) {
padding: 0 32px;
font-size: 18px;
}
}
button:hover,
button.active {
color: $white;
background-color: #171917;
line-height: 65px;
}
button:first-child {
border-top-left-radius: 12px;
}
button:last-child {
border-top-right-radius: 12px;
}
button.filler,
button.filler:hover {
flex: 1;
height: 57px;
border-top-right-radius: 12px;
background-color: #343734;
cursor: default;
}
}
.code-examples-body {
padding: 24px;
background-color: #171917;
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
font-size: 14px;
}
.react-syntax-highlighter-line-number {
color: $white50;
margin-right: 16px;
}

View File

@ -1,108 +0,0 @@
export default {
hljs: {
display: "block",
overflowX: "auto",
padding: "0.5em",
background: "#171917",
color: "#e6e1dc",
},
"hljs-comment": {
color: "#bc9458",
fontStyle: "italic",
},
"hljs-quote": {
color: "#bc9458",
fontStyle: "italic",
},
"hljs-keyword": {
color: "#c26230",
},
"hljs-selector-tag": {
color: "#c26230",
},
"hljs-string": {
color: "#a5c261",
},
"hljs-number": {
color: "#a5c261",
},
"hljs-regexp": {
color: "#a5c261",
},
"hljs-variable": {
color: "#a5c261",
},
"hljs-template-variable": {
color: "#a5c261",
},
"hljs-subst": {
color: "#519f50",
},
"hljs-tag": {
color: "#e8bf6a",
},
"hljs-name": {
color: "#e8bf6a",
},
"hljs-type": {
color: "#da4939",
},
"hljs-symbol": {
color: "#6d9cbe",
},
"hljs-bullet": {
color: "#6d9cbe",
},
"hljs-built_in": {
color: "#6d9cbe",
},
"hljs-builtin-name": {
color: "#6d9cbe",
},
"hljs-attr": {
color: "#6d9cbe",
},
"hljs-link": {
color: "#6d9cbe",
textDecoration: "underline",
},
"hljs-params": {
color: "#d0d0ff",
},
"hljs-attribute": {
color: "#cda869",
},
"hljs-meta": {
color: "#9b859d",
},
"hljs-title": {
color: "#ffc66d",
},
"hljs-section": {
color: "#ffc66d",
},
"hljs-addition": {
backgroundColor: "#144212",
color: "#e6e1dc",
display: "inline-block",
width: "100%",
},
"hljs-deletion": {
backgroundColor: "#600",
color: "#e6e1dc",
display: "inline-block",
width: "100%",
},
"hljs-selector-class": {
color: "#9b703f",
},
"hljs-selector-id": {
color: "#8b98ab",
},
"hljs-emphasis": {
fontStyle: "italic",
},
"hljs-strong": {
fontWeight: "bold",
},
};

View File

@ -1,20 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import "./FAQ.scss";
export default function FAQ({ title, children }) {
return (
<div className="faq">
<div className="faq-dash" />
<div className="faq-text">
<h3>{title}</h3>
{children}
</div>
</div>
);
}
FAQ.propTypes = {
title: PropTypes.string,
children: PropTypes.node,
};

View File

@ -1,41 +0,0 @@
@import "../../variables.scss";
.faq {
display: flex;
margin-bottom: 30px;
}
.faq-text {
flex: 1;
margin-left: 16px;
h3 {
font-weight: 700;
color: $gray;
margin-bottom: 10px;
line-height: 1.78;
font-size: 16px;
@media (min-width: $largebp) {
font-size: 18px;
}
}
p {
color: $lightGray;
line-height: 1.7;
font-size: 13px;
@media (min-width: $largebp) {
font-size: 14px;
}
}
}
.faq-dash {
height: 2px;
width: 32px;
background: $green;
box-shadow: 0 0 8px 0 rgba(87, 181, 96, 0.3);
margin-top: 16px;
}

View File

@ -1,135 +0,0 @@
import React from "react";
import { FooterOrb, FooterCube, Built } from "../../svg";
import "./Footer.scss";
import { Mailing } from "..";
export default function Footer() {
return (
<footer className="footer" id="footer">
<div className="width">
<div className="footer-column">
<Built width={120} height={120} preserveAspectRatio={"xMinYMin"} />
</div>
<div className="footer-column">
<h2>Skynet Webportals</h2>
<ul>
<li>
<a href="https://skydrain.net" target="_blank" rel="noopener noreferrer">
skydrain.net
</a>
</li>
<li>
<a href="https://skyportal.xyz" target="_blank" rel="noopener noreferrer">
skyportal.xyz
</a>
</li>
</ul>
</div>
<div className="footer-column">
<h2>For Developers</h2>
<ul>
<li>
<a href="https://blog.sia.tech/skynet-bdf0209d6d34" target="_blank" rel="noopener noreferrer">
Skynet Overview
</a>
</li>
<li>
<a href="https://siasky.net/docs" target="_blank" rel="noopener noreferrer">
API Docs
</a>
</li>
<li>
<a
href="https://github.com/NebulousLabs/skynet-webportal/blob/master/setup-scripts/README.md"
target="_blank"
rel="noopener noreferrer"
>
Portal Setup
</a>
</li>
<li>
<a
href="https://support.siasky.net/key-concepts/skynet-portals/using-a-sia-node-as-a-portal"
target="_blank"
rel="noopener noreferrer"
>
Accessing Skynet Locally
</a>
</li>
</ul>
</div>
<div className="footer-column">
<h2>Social</h2>
<ul>
<li>
<a href="https://twitter.com/siatechhq" target="_blank" rel="noopener noreferrer">
Twitter
</a>
</li>
<li>
<a href="https://discord.gg/sia" target="_blank" rel="noopener noreferrer">
Discord
</a>
</li>
<li>
<a href="https://www.reddit.com/r/siacoin" target="_blank" rel="noopener noreferrer">
Reddit
</a>
</li>
<li>
<a href="https://blog.sia.tech" target="_blank" rel="noopener noreferrer">
Blog
</a>
</li>
</ul>
</div>
<div className="footer-column">
<h2>Links</h2>
<ul>
<li>
<a href="https://sia.tech/" target="_blank" rel="noopener noreferrer">
Sia.tech
</a>
</li>
<li>
<a href="https://jobs.lever.co/SkynetLabs" target="_blank" rel="noopener noreferrer">
Jobs
</a>
</li>
<li>
<a href="https://support.siasky.net" target="_blank" rel="noopener noreferrer">
Support
</a>
</li>
<li>
<a href="terms.pdf" target="_blank" rel="noopener noreferrer">
Terms
</a>
</li>
<li>
<a href="privacy.pdf" target="_blank" rel="noopener noreferrer">
Privacy
</a>
</li>
</ul>
</div>
<div className="footer-column">
<h2>Stay up to date with Skynet updates</h2>
<Mailing id="mailing-bottom" light />
</div>
</div>
<FooterCube className="footer-cube" />
<FooterOrb className="footer-orb" />
</footer>
);
}

View File

@ -1,102 +0,0 @@
@import "../../variables.scss";
.footer {
background-color: #171917;
padding: 60px 0 100px;
overflow: hidden;
position: relative;
@media (min-width: $largebp) {
padding: 60px 0 140px;
}
.width {
max-width: 1200px;
@media (min-width: $largebp) {
display: flex;
justify-content: space-between;
}
}
.footer-column + .footer-column {
margin-top: 40px;
@media (min-width: $largebp) {
margin: 0 0 0 60px;
}
}
h2 {
font-size: 16px;
color: $white;
margin-bottom: 25px;
@media (min-width: $largebp) {
font-size: 18px;
}
}
li + li {
margin-top: 5px;
}
ul + h2 {
margin-top: 40px;
}
a {
color: $green;
display: inline-flex;
align-items: center;
transition: 0.2s color;
font-size: 13px;
@media (min-width: $largebp) {
font-size: 14px;
}
&:hover {
color: $white;
}
svg {
margin-left: 10px;
}
}
}
.footer-orb {
position: absolute;
right: 10px;
bottom: 100px;
margin-top: -13px;
margin-left: -13px;
animation: 8s floatLarge infinite;
@media (min-width: $largebp) {
margin-left: 180px;
right: auto;
left: 50%;
bottom: 90px;
}
}
.footer-cube {
position: absolute;
right: 30px;
top: 100%;
margin-top: -109px;
margin-left: -163px;
animation: 8s float infinite;
@media (min-width: $largebp) {
margin-left: -100px;
right: auto;
left: 50%;
}
}
.footer-built {
margin-top: 30px;
}

View File

@ -1,32 +0,0 @@
import React from "react";
import "./HomeBuilt.scss";
import { CircleIcon, CodeExamples } from "../";
import { Cylinder, SmallOrb } from "../../svg";
export default function HomeBuilt() {
return (
<div className="home-built">
<header className="home-built-header">
<div className="home-built-divider">
<div className="small-divider" />
<div className="divider" />
<SmallOrb className="small-orb" />
<CircleIcon>
<Cylinder />
</CircleIcon>
<SmallOrb className="small-orb" />
<div className="divider" />
<div className="small-divider" />
</div>
<h2>
Infrastructure built for
<br />
<strong>application developers</strong>
</h2>
</header>
<CodeExamples />
</div>
);
}

View File

@ -1,53 +0,0 @@
@import "../../variables.scss";
.home-built {
padding-top: 80px;
@media (min-width: $largebp) {
padding-top: 150px;
}
}
.home-built-header {
text-align: center;
h2 {
text-align: center;
font-size: 32px;
margin-bottom: 50px;
@media (min-width: $largebp) {
margin-bottom: 70px;
}
}
}
.home-built-divider {
display: inline-flex;
align-items: center;
margin: 0 auto 32px;
@media (min-width: $largebp) {
margin-bottom: 40px;
}
.circle-icon {
margin: 0 14px;
}
.small-orb:first-of-type {
margin-left: 14px;
}
.small-orb:last-of-type {
margin-right: 14px;
}
.small-divider:first-of-type {
margin-right: 8px;
}
.small-divider:last-of-type {
margin-left: 8px;
}
}

View File

@ -1,177 +0,0 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import CountUp from "react-countup";
import VisibilitySensor from "react-visibility-sensor";
import useStats, { AVAILABLE_STATS } from "./useStats";
import "./HomeNetwork.scss";
import { CircleIcon, FAQ } from "../";
import { SmallOrb, LogoSolid, Deco6, Deco7, Deco8 } from "../../svg";
const STATS_MAP = [
{ name: "TB Used", key: AVAILABLE_STATS.STORAGE_USED_TB },
{ name: "TB Capacity", key: AVAILABLE_STATS.NETWORK_CAPACITY_TB },
{ name: "Hosts", key: AVAILABLE_STATS.ONLINE_HOSTS_COUNT },
{ name: "Storage/TB", key: AVAILABLE_STATS.STORAGE_COST_USD, currency: true },
{ name: "Bandwidth/TB", key: AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD, currency: true },
];
export default function HomeNetwork() {
const [visible, setVisible] = useState(false);
const stats = useStats();
const onChange = (isVisible) => {
if (isVisible && !visible) {
setVisible(true);
}
};
return (
<div className="home-network">
<header className="home-network-header">
<div className="home-network-divider">
<CircleIcon>
<LogoSolid />
</CircleIcon>
<SmallOrb />
<div className="divider"></div>
<div className="small-divider"></div>
</div>
<h2>
Sia
<br />
<strong>Network</strong>
</h2>
</header>
<VisibilitySensor onChange={onChange} partialVisibility offset={{ bottom: 100 }} scrollThrottle={50}>
<React.Fragment>
<div className="home-network-stats">
{STATS_MAP.map((stat, i) => (
<React.Fragment key={i}>
<div key={i} className="home-network-stat">
<div className="inner">
{visible && <StatValue stat={stat} value={stats[stat.key]} />}
<span className="network-stat-name">{stat.name}</span>
</div>
</div>
{i !== 4 && <div className="divider" />}
</React.Fragment>
))}
<Deco6 className="deco-6" />
<Deco7 className="deco-7" />
<Deco8 className="deco-8" />
</div>
<div className="home-network-stats-provider">
stats provided by{" "}
<a href="https://siastats.info" target="_blank" rel="noopener noreferrer">
siastats.info
</a>
</div>
</React.Fragment>
</VisibilitySensor>
<div className="home-network-columns">
<div className="home-network-column left">
<p>
<strong>Skynet Webportals</strong> are low cost servers that sit between Skynet and everyday users, enabling
them to access Skynet content without needing to operate any special software. As Skylinks are generated,
they can be shared with anyone to retrieve data from any Webportal. The original uploader does not need to
stay online in order for the file to remain available. The Sia network serves as the backend storage layer
for Skynet and handles all of the pinning, guaranteeing both high speeds and excellent uptime.
</p>
<p>
<strong>Sia</strong> is the leading decentralized cloud storage platform. No signups, no servers, no trusted
third parties. Sia leverages blockchain technology to create a data storage marketplace that is more robust
and more affordable than traditional cloud storage providers.
</p>
<p>
<a className="more" href="https://sia.tech/" target="_blank" rel="noopener noreferrer">
Learn more about Sia
</a>
</p>
</div>
<div className="home-network-column">
<FAQ title="How do I use Skynet?">
<p>
Anyone can access files that have been uploaded to Skynet as long as they possess the corresponding
Skylinks. You can use any Webportal to download files!
<a
href="https://support.siasky.net/using-skynet"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</FAQ>
<FAQ title="How do I integrate Skynet into my app?">
<p>
Applications can be deployed in under a minute and be immediately available globally. Skynet includes an
API and SDKs which integrate seamlessly with existing applications.
<a
href="https://support.siasky.net/the-technology/developing-on-skynet"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</FAQ>
<FAQ title="How fast is Skynet?">
<p>
Skynet&apos;s speeds rival centralized providers and surpass all decentralized offerings. A typical Skynet
download starts in under 500 ms and can stream at rates as high as 1 Gbps!
<a
href="https://support.siasky.net/key-concepts/faqs#how-fast-is-skynet"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</FAQ>
<FAQ title="How much does it cost to run a Webportal?">
<p>
Storage costs 10x lower than centralized providers and bandwidth costs are 100x lower without
sacrificing performance or reliability.
</p>
</FAQ>
<a className="more more-faq" href="https://support.siasky.net" target="_blank" rel="noopener noreferrer">
View more FAQ
</a>
</div>
</div>
</div>
);
}
function StatValue({ stat, value }) {
const displayDollars = stat.currency && value >= 1;
const displayCents = stat.currency && value < 1;
return (
<h3>
{displayDollars && "$"}
<CountUp end={displayCents ? value * 100 : value} duration={3.2} decimals={displayDollars ? 2 : 0} />
{displayCents && "¢"}
</h3>
);
}
StatValue.propTypes = {
stat: PropTypes.shape({
key: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
currency: PropTypes.bool,
}).isRequired,
value: PropTypes.number.isRequired,
};

View File

@ -1,211 +0,0 @@
@import "../../variables.scss";
.home-network {
padding: 80px 0;
@media (min-width: $largebp) {
padding: 120px 0;
}
}
.home-network-header {
h2 {
font-size: 32px;
margin-bottom: 36px;
}
}
.home-network-divider {
display: flex;
align-items: center;
color: $green;
margin-bottom: 32px;
@media (min-width: $largebp) {
margin-bottom: 40px;
}
.circle-icon {
box-shadow: 0 0 8px 0 rgba(87, 181, 96, 0.3);
margin-right: 14px;
}
.divider {
margin: 0 8px 0 14px;
}
}
.home-network-stats {
background: $green;
border-radius: 12px;
box-shadow: 0 4px 24px 0 rgba(87, 181, 96, 0.3);
padding: 32px 24px;
position: relative;
@media (min-width: $largebp) {
display: flex;
align-items: center;
padding: 40px 30px;
}
@media (min-width: $largebp) {
padding: 50px 20px;
}
.divider {
height: 2px;
width: 240px;
background: $black10;
margin: 20px auto;
@media (min-width: $largebp) {
height: 56px;
width: 2px;
}
}
}
.home-network-stats-provider {
text-align: right;
color: $green;
font-size: 13px;
margin-right: 12px; // keep the same as the border radius of .home-network-stats
a {
color: $green;
&:hover {
color: $black;
}
}
}
.deco-6 {
position: absolute;
top: -185px;
right: 10px;
animation: 8s float infinite;
}
.deco-7 {
position: absolute;
top: -130px;
right: 35px;
animation: 6s float infinite;
}
.deco-8 {
position: absolute;
top: -65px;
right: -95px;
animation: 10s float infinite;
}
.home-network-stat {
text-align: center;
@media (min-width: $largebp) {
text-align: center;
width: calc(20% - 2px);
}
.inner {
@media (min-width: $largebp) {
margin: 0 auto;
display: inline-block;
text-align: left;
min-width: 110px;
}
}
h3 {
font-weight: 700;
color: $white;
font-size: 32px;
min-width: 10px;
@media (min-width: $largebp) {
font-size: 40px;
}
}
}
.network-stat-name {
font-size: 14px;
color: $white50;
}
.home-network-columns {
margin-top: 40px;
@media (min-width: $largebp) {
display: flex;
margin-top: 60px;
}
}
.home-network-column {
@media (min-width: $largebp) {
flex: 1;
display: flex;
flex-direction: column;
}
& + & {
margin-top: 40px;
@media (min-width: $largebp) {
margin: 0 0 0 30px;
}
}
&.left p {
color: $gray;
@media (min-width: $largebp) {
font-size: 18px;
}
}
&.left p + p {
margin-top: 30px;
@media (min-width: $largebp) {
margin-top: 40px;
}
}
.more {
color: $green;
font-size: 13px;
display: inline-flex;
align-items: center;
transition: 0.2s color;
&:hover {
color: $black;
}
@media (min-width: $largebp) {
font-size: 14px;
}
svg {
margin-left: 10px;
transition: 0.2s transform, 0.2s color;
}
&:hover svg {
transform: translateX(2px);
color: $black;
}
}
.more-faq {
margin-left: 48px;
}
.read-more {
display: block;
}
}

View File

@ -1,68 +0,0 @@
import { useEffect, useState } from "react";
import axios from "axios";
export const AVAILABLE_STATS = {
ONLINE_HOSTS_COUNT: "onlineHostsCount",
STORAGE_USED_TB: "storageUsedTB",
NETWORK_CAPACITY_TB: "networkCapacityTB",
STORAGE_COST_USD: "storageCostUSD",
BANDWIDTH_DOWN_COST_USD: "bandwidthDownCostUSD",
};
export default function useStats() {
const [stats, setStats] = useState({
[AVAILABLE_STATS.ONLINE_HOSTS_COUNT]: null,
[AVAILABLE_STATS.STORAGE_USED_TB]: null,
[AVAILABLE_STATS.NETWORK_CAPACITY_TB]: null,
[AVAILABLE_STATS.STORAGE_COST_USD]: null,
[AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD]: null,
});
useEffect(() => {
async function fetchData() {
const [bandwidth, storage, price] = await Promise.all([getBandwidthStats(), getStorageStats(), getPriceStats()]);
setStats({ ...bandwidth, ...storage, ...price });
}
fetchData();
}, [setStats]);
return stats;
}
async function getBandwidthStats() {
// { up: 76.09, down: 102.66, upusd: 0.23, downusd: 0.32 }
const { data } = await axios.get("https://siastats.info/dbs/bandwidthpricesdb.json");
// some entries do not contain the required property so make sure to get one that does
const current = data.reverse().find((entry) => "downusd" in entry);
return {
[AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD]: current.downusd,
};
}
async function getPriceStats() {
// { price: 504.59, newcontractformation: 30.79, usd: 1.55, sfperfees: 8.98 }
const { data } = await axios.get("https://siastats.info/dbs/storagepricesdb.json");
// some entries do not contain the required property so make sure to get one that does
const current = data.reverse().find((entry) => "usd" in entry);
return {
[AVAILABLE_STATS.STORAGE_COST_USD]: current.usd,
};
}
async function getStorageStats() {
// { block_height: 247816, block_timestamp: 1582285828, hashrate: 6212581269715416,
// difficulty: 3501953420754597000, coin_supply: 43638591164, coin_price_USD: 0.003,
// market_cap_USD: 130915773, used_storage_TB: 725.26, network_capacity_TB: 2270.96,
// online_hosts: 360, active_contracts: 62997 }
const { data } = await axios.get("https://siastats.info/dbs/network_status.json");
return {
[AVAILABLE_STATS.ONLINE_HOSTS_COUNT]: data.online_hosts,
[AVAILABLE_STATS.STORAGE_USED_TB]: data.used_storage_TB,
[AVAILABLE_STATS.NETWORK_CAPACITY_TB]: data.network_capacity_TB,
};
}

View File

@ -1,52 +0,0 @@
import React from "react";
import "./HomeSamples.scss";
import { Sample } from "../";
const samples = [
{ type: "HTML", url: "/PAL0w4SdA5rFCDGEutgpeQ50Om-YkBabtXVOJAkmedslKw" },
{ type: "PDF", url: "/XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg" },
{ type: "Image", url: "/IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ" },
{ type: "Audio", url: "/_A2zt5SKoqwnnZU4cBF8uBycSKULXMyeg1c5ZISBr2Q3dA" },
{ type: "Video", url: "/CACqf4NlIMlA0CCCieYGjpViPGyfyJ4v1x3bmuCKZX8FKA" },
{ type: "JSON", url: "/AAC0uO43g64ULpyrW0zO3bjEknSFbAhm8c-RFP21EQlmSQ" },
{ type: "Dapp", url: "/hns/marstorage/" },
];
export default function HomeSamples() {
return (
<div className="home-samples">
<p>Above are some code snippets for uploading and retrieving data.</p>
<p>
Skynet includes{" "}
<a href="https://siasky.net/docs" target="_blank" rel="noopener noreferrer" className="link">
SDKs
</a>{" "}
for popular programming languages and{" "}
<a href="https://siasky.net/docs/" target="_blank" rel="noopener noreferrer" className="link">
APIs
</a>{" "}
that integrate seamlessly with your existing apps. You can follow these guides to start using Skynet with{" "}
<a href="https://github.com/NebulousLabs/skynet-cli" target="_blank" rel="noopener noreferrer" className="link">
the Skynet CLI
</a>{" "}
and{" "}
<a
href="https://blog.sia.tech/the-skynet-sdks-751b35578b20"
target="_blank"
rel="noopener noreferrer"
className="link"
>
integrate Skynet
</a>{" "}
into your application.
</p>
<div className="home-samples-samples">
{samples.map((sample, i) => (
<Sample key={`${i}-${sample.url}`} {...sample} />
))}
</div>
</div>
);
}

View File

@ -1,40 +0,0 @@
@import "../../variables.scss";
.home-samples {
text-align: center;
margin: 0;
padding: 60px 0;
@media (min-width: $largebp) {
padding: 65px 0 100px;
}
p {
margin: 0 auto 24px;
max-width: 460px;
@media (min-width: $largebp) {
font-size: 18px;
max-width: 600px;
}
&:last-of-type {
margin-bottom: 48px;
}
}
.sample {
display: inline-block;
margin: 10px;
min-width: 124px;
text-align: center;
@media (min-width: $tinybp) {
margin: 10px 20px;
}
@media (min-width: $smallbp) {
margin: 10px 40px;
}
}
}

View File

@ -1,64 +0,0 @@
import React, { Component } from "react";
import "./HomeStay.scss";
import { SocialLink, CircleIcon, Mailing } from "../";
import { SmallOrb, Pyramid } from "../../svg";
export default class HomeStay extends Component {
render() {
return (
<div className="home-stay">
<header className="home-stay-header">
<div className="home-stay-divider">
<CircleIcon>
<Pyramid />
</CircleIcon>
<SmallOrb />
<div className="divider" />
<div className="small-divider" />
</div>
</header>
<div className="home-stay-flex">
<div className="home-stay-left">
<header className="home-stay-header">
<h2>
Stay up to date with
<br />
<strong>Skynet updates</strong>
</h2>
</header>
<Mailing id="mailing-top" />
</div>
<ul className="home-stay-right">
<li>
<SocialLink
icon="github"
url="https://github.com/NebulousLabs/skynet-webportal"
greenText="View project on Github"
title={<strong>/Skynet-Webportal</strong>}
/>
</li>
<li>
<SocialLink
icon="discord"
url="https://discord.gg/sia"
greenText="View project on Discord"
title={<strong>/Sia</strong>}
/>
</li>
<li>
<SocialLink
icon="twitter"
url="https://twitter.com/SiaTechHQ"
greenText="View project on Twitter"
title={<strong>@SiaTechHQ</strong>}
/>
</li>
</ul>
</div>
</div>
);
}
}

View File

@ -1,73 +0,0 @@
@import "../../variables.scss";
.home-stay-header {
h2 {
font-size: 32px;
margin-bottom: 36px;
}
}
.home-stay-divider {
display: flex;
align-items: center;
color: $green;
margin-bottom: 32px;
@media (min-width: $largebp) {
margin-bottom: 40px;
}
.circle-icon {
box-shadow: 0 0 8px 0 rgba(87, 181, 96, 0.3);
margin-right: 14px;
}
.divider {
margin: 0 8px 0 14px;
}
}
.home-stay-flex {
@media (min-width: $largebp) {
display: flex;
}
}
.home-stay-left {
@media (min-width: $largebp) {
flex: 1;
margin-right: 60px;
}
p {
max-width: 553px;
@media (min-width: $largebp) {
font-size: 18px;
}
}
.disclaimer-text {
font-size: 13px;
color: $lightGray;
line-height: 1.7;
max-width: 438px;
@media (min-width: $largebp) {
font-size: 14px;
}
}
}
.home-stay-right {
margin-top: 40px;
@media (min-width: $largebp) {
width: 305px;
margin-top: 0;
}
li + li {
margin-top: 24px;
}
}

View File

@ -1,35 +0,0 @@
import React from "react";
import { boolean } from "boolean";
import logo from "../../images/logo.svg";
import "./HomeTop.scss";
import { Skynet, Deco1, Deco2 } from "../../svg";
export default function HomeTop() {
return (
<div className="home-top">
<img src={logo} alt="Skynet logo" className="logo" />
<Skynet className="wordmark" />
<h1>Build a Free Internet.</h1>
<p>
The decentralized CDN and file sharing platform for devs. Skynet is the storage foundation for a Free Internet!
</p>
{boolean(process.env.GATSBY_WITH_ACCOUNTS) && (
<p className="auth-links">
<a href="/account/auth/registration" className="link">
Sign up now!
</a>{" "}
Already have an account? Go to your{" "}
<a href="/account/" className="link">
dashboard
</a>
</p>
)}
<Deco1 className="deco-1" />
<Deco2 className="deco-2" />
</div>
);
}

View File

@ -1,80 +0,0 @@
@import "../../variables.scss";
.home-top {
text-align: center;
padding: 60px 0 50px;
position: relative;
@media (min-width: $largebp) {
padding: 60px 0 70px;
}
.logo {
display: inline-block;
width: 85px;
margin-bottom: 5px;
margin-right: 10px; // move it 10px so it looks like it's centered
}
.wordmark {
margin: 0 auto 35px;
}
h1 {
font-size: 44px;
line-height: 1.14;
margin-bottom: 38px;
@media (min-width: $largebp) {
font-size: 56px;
}
}
p {
font-size: 21px;
line-height: 1.33;
max-width: 560px;
margin: 0 auto;
&.auth-links {
font-size: 18px;
.link {
font-weight: bold;
}
}
@media (min-width: $largebp) {
font-size: 24px;
max-width: 670px;
}
& + p {
margin-top: 24px;
}
}
}
.deco-1 {
position: absolute;
left: 100%;
bottom: 25%;
margin-left: 20px;
animation: 6s float infinite;
@media (min-width: 591px) {
margin-left: 100px;
}
}
.deco-2 {
position: absolute;
left: 100%;
bottom: 5%;
margin-left: -15px;
animation: 8s float infinite;
@media (min-width: 591px) {
margin-left: 50px;
}
}

View File

@ -1,248 +0,0 @@
import React, { useState, useContext, useEffect } from "react";
import bytes from "bytes";
import classNames from "classnames";
import { getReasonPhrase, StatusCodes } from "http-status-codes";
import path from "path-browserify";
import { useDropzone } from "react-dropzone";
import { Button, UploadFile } from "../";
import { Deco3, Deco4, Deco5, Folder, DownArrow } from "../../svg";
import "./HomeUpload.scss";
import AppContext from "../../AppContext";
import { SkynetClient, parseSkylink } from "skynet-js";
const isValidSkylink = (skylink) => {
try {
parseSkylink(skylink); // try to parse the skylink, it will throw on error
} catch (error) {
return false;
}
return true;
};
const getFilePath = (file) => file.webkitRelativePath || file.path || file.name;
const getRelativeFilePath = (file) => {
const filePath = getFilePath(file);
const { root, dir, base } = path.parse(filePath);
const relative = path.normalize(dir).slice(root.length).split(path.sep).slice(1);
return path.join(...relative, base);
};
const getRootDirectory = (file) => {
const filePath = getFilePath(file);
const { root, dir } = path.parse(filePath);
return path.normalize(dir).slice(root.length).split(path.sep)[0];
};
const createUploadErrorMessage = (error) => {
// The request was made and the server responded with a status code that falls out of the range of 2xx
if (error.response) {
if (error.response.data.message) {
return `Upload failed with error: ${error.response.data.message}`;
}
const statusCode = error.response.status;
const statusText = getReasonPhrase(error.response.status);
return `Upload failed, our server received your request but failed with status code: ${statusCode} ${statusText}`;
}
// The request was made but no response was received. The best we can do is detect whether browser is online.
// This will be triggered mostly if the server is offline or misconfigured and doesn't respond to valid request.
if (error.request) {
if (!navigator.onLine) {
return "You are offline, please connect to the internet and try again";
}
// TODO: We should add a note "our team has been notified" and have some kind of notification with this error.
return "Server failed to respond to your request, please try again later.";
}
// TODO: We should add a note "our team has been notified" and have some kind of notification with this error.
return `Critical error, please refresh the application and try again. ${error.message}`;
};
export default function HomeUpload() {
const [files, setFiles] = useState([]);
const [skylink, setSkylink] = useState("");
const { apiUrl } = useContext(AppContext);
const [directoryMode, setDirectoryMode] = useState(false);
const client = new SkynetClient(apiUrl);
useEffect(() => {
if (directoryMode) {
inputRef.current.setAttribute("webkitdirectory", "true");
} else {
inputRef.current.removeAttribute("webkitdirectory");
}
}, [directoryMode]);
const handleDrop = async (acceptedFiles) => {
if (directoryMode && acceptedFiles.length) {
const rootDir = getRootDirectory(acceptedFiles[0]); // get the file path from the first file
acceptedFiles = [{ name: rootDir, directory: true, files: acceptedFiles }];
}
setFiles((previousFiles) => [...acceptedFiles.map((file) => ({ file, status: "uploading" })), ...previousFiles]);
const onFileStateChange = (file, state) => {
setFiles((previousFiles) => {
const index = previousFiles.findIndex((f) => f.file === file);
return [
...previousFiles.slice(0, index),
{
...previousFiles[index],
...state,
},
...previousFiles.slice(index + 1),
];
});
};
acceptedFiles.forEach((file) => {
const onUploadProgress = (progress) => {
const status = progress === 1 ? "processing" : "uploading";
onFileStateChange(file, { status, progress });
};
// Reject files larger than our hard limit of 1 GB with proper message
if (file.size > bytes("1 GB")) {
onFileStateChange(file, { status: "error", error: "This file size exceeds the maximum allowed size of 1 GB." });
return;
}
const upload = async () => {
try {
let response;
if (file.directory) {
const directory = file.files.reduce((acc, file) => ({ ...acc, [getRelativeFilePath(file)]: file }), {});
response = await client.uploadDirectory(directory, encodeURIComponent(file.name), { onUploadProgress });
} else {
response = await client.uploadFile(file, { onUploadProgress });
}
onFileStateChange(file, { status: "complete", url: client.getSkylinkUrl(response.skylink) });
} catch (error) {
if (error.response && error.response.status === StatusCodes.TOO_MANY_REQUESTS) {
onFileStateChange(file, { progress: -1 });
return new Promise((resolve) => setTimeout(() => resolve(upload()), 3000));
}
onFileStateChange(file, { status: "error", error: createUploadErrorMessage(error) });
}
};
upload();
});
};
const { getRootProps, getInputProps, isDragActive, inputRef } = useDropzone({ onDrop: handleDrop });
const handleSkylink = (event) => {
event.preventDefault();
// only try to open a valid skylink
if (isValidSkylink(skylink)) {
client.openFile(skylink);
}
};
return (
<div className="home-upload">
<div className="home-upload-white">
<div className="home-upload-split">
<div className="home-upload-box ">
<div
className={classNames("home-upload-dropzone", {
"drop-active": isDragActive,
})}
{...getRootProps()}
>
<span className="home-upload-text">
<h3>Upload your {directoryMode ? "Directory" : "Files"}</h3>
Drop your {directoryMode ? "directory" : "files"} here to pin to Skynet
</span>
<Button iconLeft>
<Folder />
Browse
</Button>
</div>
<input {...getInputProps()} className="offscreen" />
<button
type="button"
className="home-upload-mode-switch link"
onClick={() => setDirectoryMode(!directoryMode)}
>
{directoryMode ? "⇐ Switch back to uploading files" : "Do you want to upload an entire directory?"}
</button>
{directoryMode && (
<p className="home-upload-directory-mode-notice">
Please note that directory upload is not a standard browser feature and the browser support is limited.
To check whether your browser is compatible, visit{" "}
<a
href="https://caniuse.com/#feat=mdn-api_htmlinputelement_webkitdirectory"
target="_blank"
rel="noopener noreferrer"
className="link"
>
caniuse.com
</a>
.
</p>
)}
</div>
<div className="home-upload-retrieve">
<div className="home-upload-text">
<h3 id="skylink-retrieve-title">Have a Skylink?</h3>
<p>Paste the link to retrieve your file</p>
<form
className={classNames("home-upload-retrieve-form", { invalid: skylink && !isValidSkylink(skylink) })}
onSubmit={handleSkylink}
>
<input
name="skylink"
type="text"
placeholder="sia://"
aria-labelledby="skylink-retrieve-title"
onChange={(event) => setSkylink(event.target.value)}
/>
<button type="submit" aria-label="Retrieve file">
<DownArrow />
</button>
</form>
</div>
</div>
</div>
{files.length > 0 && (
<div className="home-uploaded-files">
{files.map((file, i) => {
return <UploadFile key={i} {...file} />;
})}
</div>
)}
</div>
<p className="bottom-text">
Upon uploading a file, Skynet generates a 46 byte link called a <strong>Skylink</strong>. This link can then be
shared with anyone to retrieve the file on any Skynet Webportal.
</p>
<Deco3 className="deco-3" />
<Deco4 className="deco-4" />
<Deco5 className="deco-5" />
</div>
);
}

View File

@ -1,269 +0,0 @@
@import "../../variables.scss";
.home-upload {
position: relative;
.bottom-text {
color: $lightGray;
font-size: 16px;
text-align: center;
max-width: 590px;
margin: 25px auto 0;
@media (min-width: $largebp) {
font-size: 16px;
}
}
}
.home-upload-white {
background: $white;
border-radius: 12px;
box-shadow: 0 8px 24px 0 rgba(90, 94, 91, 0.15), 0 2px 4px 0 rgba(0, 0, 0, 0.05);
padding: 16px;
}
.home-upload-split {
border: 1px dashed #c5cec7;
border-radius: 4px;
padding: 20px;
@media (min-width: $largebp) {
display: flex;
}
}
.home-upload-box {
padding-bottom: 20px;
@media (min-width: $largebp) {
width: 50%;
padding-bottom: 0;
padding-right: 20px;
}
}
.home-upload-dropzone {
border-radius: 4px;
height: 200px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
outline: none;
&:hover {
background-color: rgba(0, 0, 0, 0.03);
cursor: pointer;
}
&:hover .button {
background-color: $greenHover;
transform: translateY(-2px);
}
&.drop-active {
background-color: $green;
border: 1px solid $green;
h3 {
color: $white;
}
.button {
display: none;
}
}
.button {
margin-top: 20px;
@media (min-width: $largebp) {
margin-top: 30px;
}
}
}
.home-upload-mode-switch {
display: block;
font-size: 13px;
margin: 10px auto 0;
@media (min-width: $largebp) {
font-size: 14px;
}
}
.home-upload-directory-mode-notice {
color: $lightGray;
font-size: 13px;
line-height: 1.2em;
margin-top: 20px;
text-align: center;
}
.home-upload-text {
color: $gray;
display: block;
transition: 0.2s color;
font-size: 13px;
@media (min-width: $largebp) {
font-size: 14px;
}
.drop-active & {
color: $white;
}
h3 {
font-size: 16px;
margin-bottom: 5px;
color: $darkGray;
@media (min-width: $largebp) {
font-size: 18px;
}
}
}
.deco-3 {
position: absolute;
top: -70px;
left: -5px;
animation: 8s float infinite;
}
.deco-4 {
position: absolute;
top: -32px;
left: -90px;
animation: 6s float infinite;
}
.deco-5 {
position: absolute;
top: 52px;
left: -56px;
animation: 10s float infinite;
}
.home-uploaded-files {
border: solid 1px #c5cec7;
padding: 0 20px;
margin-top: 10px;
border-radius: 4px;
@media (min-width: $largebp) {
padding: 0 40px;
}
.upload-file + .upload-file {
border-top: 1px solid rgba(197, 206, 199, 0.4);
}
}
.home-upload-retrieve {
align-items: center;
text-align: center;
display: flex;
flex-direction: column;
text-align: center;
justify-content: center;
border-top: 1px dashed #c5cec7;
height: 200px;
padding: 40px 20px;
@media (min-width: $largebp) {
width: 50%;
padding: 20px 40px;
border-top: 0;
border-left: 1px dashed #c5cec7;
}
.home-upload-text {
width: 100%;
}
}
.home-upload-retrieve-form {
width: 100%;
margin-top: 3px;
position: relative;
margin-top: 20px;
@media (min-width: $largebp) {
margin-top: 30px;
}
input {
border: 1px solid #cbd3cd;
border-radius: 4px;
line-height: 46px;
transition: 0.2s border-color;
padding: 0 64px 0 16px;
font-size: 13px;
@media (min-width: $largebp) {
font-size: 14px;
}
}
input:hover,
input:hover + button {
border-color: rgb(143, 143, 143);
}
input:focus,
input:focus + button {
border-color: $green;
}
button {
border-left: 1px solid #cbd3cd;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
width: 46px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
right: 0;
color: #cbd3cd;
transition: 0.2s background-color, 0.2s border-color, 0.2s color;
&:hover {
background: $green;
color: $white;
border-color: $green;
}
}
&.invalid {
input {
border-color: $red;
}
input:hover,
input:hover + button {
border-color: $red;
}
input:focus,
input:focus + button {
border-color: $red;
}
button {
border-color: $red;
&:hover {
background: $red;
border-color: $red;
}
}
}
}

View File

@ -1,12 +0,0 @@
import React from "react";
import "./LoadingSpinner.scss";
import { Loading } from "../../svg";
export default function LoadingSpinner() {
return (
<div className="loading-spinner">
<Loading />
</div>
);
}

View File

@ -1,19 +0,0 @@
@import "../../variables.scss";
@-webkit-keyframes spin {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spin {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.loading-spinner {
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;
}

View File

@ -1,76 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import MailchimpSubscribe from "react-mailchimp-subscribe";
import classNames from "classnames";
import "./Mailing.scss";
const url = "https://tech.us11.list-manage.com/subscribe/post?u=5df238d9e852f9801b5f2c92e&amp;id=ab6bea4cc2";
const CustomForm = ({ status, message, onValidated, light, id }) => {
let email, user;
const checkboxId = `${id}-check`;
const submitId = `${id}-submit`;
const submit = () => {
if ((email, user, email.value.indexOf("@") > -1)) {
onValidated({
EMAIL: email.value,
USER: user.checked ? "Yes" : "No",
});
}
};
return (
<form className={classNames("home-stay-form", { light })} onSubmit={(e) => e.preventDefault()}>
<input
ref={(node) => (email = node)}
type="email"
placeholder="Email Address"
validate="true"
aria-labelledby={submitId}
/>
<div className="home-form-stay-existing">
<input ref={(node) => (user = node)} type="checkbox" id={checkboxId} />
<label htmlFor={checkboxId}>I have previous experience using Sia</label>
</div>
<button className="button" onClick={submit} id={submitId}>
Get Updates
</button>
{status === "sending" && <p className="message">sending...</p>}
{status === "error" && <p className="message red-text" dangerouslySetInnerHTML={{ __html: message }} />}
{status === "success" && <p className="message" dangerouslySetInnerHTML={{ __html: message }} />}
</form>
);
};
CustomForm.propTypes = {
status: PropTypes.string,
message: PropTypes.string,
onValidated: PropTypes.func,
light: PropTypes.bool,
id: PropTypes.string,
};
export default function Mailing({ light, id }) {
return (
<MailchimpSubscribe
url={url}
render={({ subscribe, status, message }) => (
<CustomForm
id={id}
status={status}
message={message}
light={light}
onValidated={(formData) => subscribe(formData)}
/>
)}
/>
);
}
Mailing.propTypes = {
light: PropTypes.bool,
id: PropTypes.string,
};

View File

@ -1,109 +0,0 @@
@import "../../variables.scss";
.home-stay-form {
max-width: 342px;
margin: 36px 0 24px;
.relative {
position: relative;
}
.message {
font-size: 12px;
margin-top: 10px;
color: $lightGray;
&.red-text {
color: $red;
}
}
input[type="email"] {
border-radius: 4px;
box-shadow: 0 2px 4px 0 rgba(90, 94, 91, 0.1);
border: solid 1px #cbd3cd;
padding: 12px 0 12px 16px;
transition: 0.2s border-color;
&:hover {
border-color: rgb(143, 143, 143);
}
&:focus {
border-color: $green;
}
}
input[type="checkbox"] {
width: 20px;
height: 20px;
border-radius: 3px;
border: 1px solid #cbd3cd;
margin-right: 8px;
display: inline-block;
vertical-align: middle;
margin: -2px 8px 0 0;
background-image: url("../../images/green-check.svg");
background-repeat: no-repeat;
background-size: 28px;
background-position: top -300px center;
&:checked {
background-position: top -3px center;
}
}
button {
font-weight: 400;
@media (min-width: $largebp) {
font-size: 16px;
}
}
.email-error {
font-size: 12px;
margin-top: 8px;
color: $red;
}
}
.home-stay-form.light {
input[type="email"] {
box-shadow: 0 2px 4px 0 rgba(90, 94, 91, 0.1);
border-color: $white50;
color: $white;
&:hover {
border-color: $white;
}
&:focus {
border-color: $green;
}
}
input[type="checkbox"] {
border-color: $white50;
}
label {
color: $white50;
}
.message {
color: $white30;
&.red-text {
color: $red;
}
}
}
.home-form-stay-existing {
margin: 15px 0 20px 0;
label {
color: $darkGray;
}
}

View File

@ -1,25 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import "./Sample.scss";
import { Download } from "../../svg";
export default function Sample({ type, url, className }) {
return (
<div className={classNames("sample", className)}>
<a href={url} target="_blank" rel="noopener noreferrer">
<Download />
<span className="sample-name">
<strong>{type}</strong> Sample
</span>
<span className="sample-download">Download</span>
</a>
</div>
);
}
Sample.propTypes = {
type: PropTypes.string,
url: PropTypes.string,
className: PropTypes.string,
};

View File

@ -1,48 +0,0 @@
@import "../../variables.scss";
.sample {
display: block;
text-align: center;
a {
transition: 0.2s transform;
display: block;
}
a:hover {
transform: translateY(5px);
}
svg {
margin: 0 auto;
width: 34px;
height: 46px;
}
}
.sample-name {
color: $darkGray;
display: block;
@media (min-width: $largebp) {
font-size: 18px;
}
a:hover & {
color: $black;
}
}
.sample-download {
display: block;
color: $green;
font-size: 13px;
@media (min-width: $largebp) {
font-size: 14px;
}
a:hover & {
color: $greenHover;
}
}

View File

@ -1,33 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import "./SocialLink.scss";
import { Github, Discord, Twitter } from "../../svg";
export default function SocialLink({ icon, title, greenText, url }) {
const getIcon = () => {
if (icon === "github") {
return <Github />;
} else if (icon === "discord") {
return <Discord />;
} else if (icon === "twitter") {
return <Twitter />;
}
};
return (
<a href={url} className="social-link">
<span className="social-link-icon">{getIcon(icon)}</span>
<span className="social-link-text">
<span className="social-link-title">{title}</span>
<span className="social-link-green">{greenText}</span>
</span>
</a>
);
}
SocialLink.propTypes = {
icon: PropTypes.string,
title: PropTypes.node,
greenText: PropTypes.string,
url: PropTypes.string,
};

View File

@ -1,42 +0,0 @@
@import "../../variables.scss";
.social-link {
display: flex;
color: $darkGray;
}
.social-link-icon {
width: 32px;
transition: 0.2s transform;
a:hover & {
transform: scale(1.07);
}
svg {
width: 32px;
height: 32px;
}
}
.social-link-text {
flex: 1;
margin-left: 16px;
transition: 0.2s color;
}
.social-link-title {
display: block;
}
.social-link-green {
color: $green;
font-size: 14px;
display: inline-flex;
transition: 0.2s color;
a:hover & {
color: $darkGray;
}
}

View File

@ -1,14 +0,0 @@
// import React from "react";
// import "./StickyTopMessage.scss";
export default function StickyTopMessage() {
return null; // returns nothing, uncomment when we need a new message
// return (
// <div className="sticky-top-message" role="alert">
// <p>
// We are working on improved performance as part of the upcoming Sia v1.5.0 release. In the meantime, you can try
// other webportals listed at the <a href="#footer">bottom</a>.
// </p>
// </div>
// );
}

View File

@ -1,24 +0,0 @@
@import "../../variables.scss";
.sticky-top-message {
position: sticky;
top: 0;
font-size: 14px;
text-align: center;
padding: 10px;
font-weight: bold;
z-index: 999;
background-color: #fbe6e6;
border-bottom: 1px solid #e65c5c;
color: $red;
a {
color: $red;
text-decoration: underline;
&:hover {
color: darken($red, 15%);
transition: color 0.2s ease;
}
}
}

View File

@ -1,92 +0,0 @@
import React, { useState, useRef, useEffect } from "react";
import PropTypes from "prop-types";
import "./UploadFile.scss";
import { LoadingSpinner } from "../";
import { File, FileCheck, FileError, Copy } from "../../svg";
export default function UploadFile({ file, url, status, progress, error }) {
const [copied, setCopied] = useState(false);
const urlRef = useRef(null);
useEffect(() => {
if (copied) {
const timeoutId = setTimeout(() => {
setCopied(false);
}, 1500);
return () => clearTimeout(timeoutId);
}
}, [copied, setCopied]);
const getIcon = () => {
if (status === "uploading" || status === "processing") {
return <File />;
} else if (status === "error") {
return <FileError />;
} else {
return <FileCheck />;
}
};
const copyToClipboard = (e) => {
urlRef.current.select();
document.execCommand("copy");
e.target.focus();
setCopied(true);
};
const copyText = copied ? "Copied!" : "Copy to clipboard";
const getProgressText = (progress) => {
if (progress === -1) {
return "Waiting...";
} else if (progress > 0) {
return `Uploading ${Math.round(progress * 100)}%`;
}
return "Uploading...";
};
return (
<div className="upload-file">
<div className="upload-file-icon">{getIcon()}</div>
<div className="upload-file-text">
<h3>{file.name}</h3>
<p>
{status === "uploading" && getProgressText(progress)}
{status === "processing" && "Processing..."}
{status === "error" && <span className="red-text">{error || "Upload failed."}</span>}
{status === "complete" && (
<a href={url} className="url green-text" target="_blank" rel="noopener noreferrer">
{url}
</a>
)}
</p>
</div>
{(status === "uploading" || status === "processing") && (
<div className="upload-file-loading">
<LoadingSpinner />
</div>
)}
{status === "complete" && (
<button onClick={copyToClipboard} className="upload-file-copy">
<p className="upload-file-copy-tooltip">{copyText}</p>
<div className="upload-file-copy-button">
Copy Link
<Copy />
</div>
<textarea value={url} ref={urlRef} readOnly={true} />
</button>
)}
</div>
);
}
UploadFile.propTypes = {
file: PropTypes.shape({
name: PropTypes.string.isRequired,
}),
status: PropTypes.string.isRequired,
url: PropTypes.string,
progress: PropTypes.number,
error: PropTypes.string,
};

View File

@ -1,143 +0,0 @@
@import "../../variables.scss";
.upload-file {
display: flex;
align-items: center;
padding: 20px 0;
flex-wrap: wrap;
}
.upload-file-icon {
display: none;
@media (min-width: $largebp) {
display: block;
min-width: 36px;
width: 36px;
max-width: 36px;
}
}
.upload-file-text {
display: block;
margin: 0 18px;
flex: 1;
h3 {
margin-bottom: 5px;
font-size: 16px;
font-weight: 400;
word-break: break-all;
@media (min-width: $largebp) {
font-size: 18px;
}
}
p {
font-size: 14px;
color: $lightGray;
}
a {
color: $green;
}
.url {
word-break: break-all;
&:hover {
text-decoration: underline;
}
}
}
.upload-file-loading,
.upload-file-copy {
margin-left: auto;
}
.upload-file-copy {
position: relative;
@media (max-width: $largebp) {
flex-basis: 100%;
text-align: right;
}
&:hover {
color: $green;
}
textarea {
position: absolute;
left: -999em;
}
}
.upload-file-copy-tooltip {
position: absolute;
bottom: 100%;
margin-bottom: 10px;
transform: translateX(-50%);
color: $white;
background: rgba(23, 25, 23, 0.9);
font-size: 14px;
white-space: nowrap;
line-height: 32px;
box-shadow: 0 2px 8px 0 rgba(23, 25, 23, 0.2);
border-radius: 4px;
width: 140px;
text-align: center;
opacity: 0;
left: -9999em;
transition: $fadeOff;
.upload-file-copy:hover & {
left: 50%;
opacity: 1;
transition: $fadeOn;
}
&::after {
width: 0;
height: 0;
border-style: solid;
border-width: 6px 6px 0 6px;
border-color: rgba(23, 25, 23, 0.9) transparent transparent transparent;
top: 100%;
left: 50%;
margin-left: -6px;
content: "";
position: absolute;
box-shadow: 0 2px 8px 0 rgba(23, 25, 23, 0.2);
}
}
.upload-file-copy-button {
border: 1px solid $green;
border-radius: 3px;
color: $green;
line-height: 40px;
font-size: 13px;
padding: 0 10px;
display: inline-flex;
align-items: center;
font-weight: 700;
transition: 0.2s color, 0.2s background-color;
@media (min-width: $largebp) {
font-size: 14px;
padding: 0 15px;
line-height: 46px;
}
&:hover {
background-color: $green;
color: $white;
}
svg {
margin-left: 10px;
}
}

View File

@ -1,38 +0,0 @@
import App from "./App/App";
import Button from "./Button/Button";
import CodeExamples from "./CodeExamples/CodeExamples";
import Sample from "./Sample/Sample";
import SocialLink from "./SocialLink/SocialLink";
import CircleIcon from "./CircleIcon/CircleIcon";
import FAQ from "./FAQ/FAQ";
import UploadFile from "./UploadFile/UploadFile";
import LoadingSpinner from "./LoadingSpinner/LoadingSpinner";
import Footer from "./Footer/Footer";
import Mailing from "./Mailing/Mailing";
import HomeTop from "./HomeTop/HomeTop";
import HomeUpload from "./HomeUpload/HomeUpload";
import HomeBuilt from "./HomeBuilt/HomeBuilt";
import HomeSamples from "./HomeSamples/HomeSamples";
import HomeStay from "./HomeStay/HomeStay";
import HomeNetwork from "./HomeNetwork/HomeNetwork";
export {
App,
HomeTop,
HomeUpload,
Button,
HomeBuilt,
CodeExamples,
Sample,
HomeSamples,
HomeStay,
SocialLink,
CircleIcon,
HomeNetwork,
FAQ,
UploadFile,
LoadingSpinner,
Footer,
Mailing,
};

View File

@ -1,88 +0,0 @@
/**
* SEO component that queries for data with
* Gatsby's useStaticQuery React hook
*
* See: https://www.gatsbyjs.org/docs/use-static-query/
*/
import React from "react";
import PropTypes from "prop-types";
import { Helmet } from "react-helmet";
import { useStaticQuery, graphql } from "gatsby";
function SEO({ lang, meta }) {
const { site } = useStaticQuery(
graphql`
query {
site {
siteMetadata {
title
author
description
image
}
}
}
`
);
return (
<Helmet
htmlAttributes={{
lang,
}}
title={site.siteMetadata.title}
meta={[
{
name: `description`,
content: site.siteMetadata.description,
},
{
property: `og:title`,
content: site.siteMetadata.title,
},
{
property: `og:description`,
content: site.siteMetadata.description,
},
{
property: `og:type`,
content: `website`,
},
{
property: `og:image`,
content: site.siteMetadata.image,
},
{
name: `twitter:card`,
content: `summary`,
},
{
name: `twitter:creator`,
content: site.siteMetadata.author,
},
{
name: `twitter:title`,
content: site.siteMetadata.title,
},
{
name: `twitter:description`,
content: site.siteMetadata.description,
},
].concat(meta)}
/>
);
}
SEO.defaultProps = {
lang: `en`,
meta: [],
description: ``,
};
SEO.propTypes = {
lang: PropTypes.string,
meta: PropTypes.arrayOf(PropTypes.object),
};
export default SEO;

View File

@ -1,148 +0,0 @@
@import "./variables.scss";
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-size: 16px;
font-weight: 400;
line-height: 1.78;
font-family: $font;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: $greenBg;
color: $darkGray;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 500;
line-height: 1.25;
}
a {
text-decoration: none;
}
li {
list-style: none;
}
input,
select,
button,
textarea {
appearance: none;
border: none;
background: transparent;
outline: none;
font-family: $font;
font-size: 16px;
}
input[type="email"],
input[type="text"],
input[type="password"],
input[type="search"] {
display: block;
width: 100%;
}
a,
button,
label,
input[type="submit"],
input[type="checkbox"],
input[type="radio"] {
cursor: pointer;
}
img,
svg {
display: block;
max-width: 100%;
}
.red-text {
color: $red;
}
.green-text {
color: $green;
}
.dark-gray-text {
color: $darkGray;
}
.link {
color: $green;
transition: 0.2s color;
&:hover {
color: $black;
}
}
.truncate {
width: 250px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: block;
}
.offscreen {
position: absolute;
left: -999em;
}
.width {
width: 90%;
max-width: 900px;
margin: 0 auto;
}
.divider {
width: 48px;
height: 2px;
background: currentColor;
}
.small-divider {
width: 8px;
height: 2px;
background: currentColor;
}
@keyframes float {
0% {
transform: translate(0, 0);
}
50% {
transform: translate(0, -20%);
}
100% {
transform: translate(0, 0);
}
}
@keyframes floatLarge {
0% {
transform: translate(0, 0);
}
50% {
transform: translate(0, -40%);
}
100% {
transform: translate(0, 0);
}
}

View File

@ -1,29 +0,0 @@
<svg width="24px" height="22px" viewBox="0 0 24 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<polyline id="path-1" points="0 36 3 39 8 34"></polyline>
<filter x="-167.7%" y="-268.3%" width="435.4%" height="628.3%" filterUnits="objectBoundingBox" id="filter-2">
<feMorphology radius="1" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
<feOffset dx="0" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
<feMorphology radius="1" operator="erode" in="SourceAlpha" result="shadowInner"></feMorphology>
<feOffset dx="0" dy="0" in="shadowInner" result="shadowInner"></feOffset>
<feComposite in="shadowOffsetOuter1" in2="shadowInner" operator="out" result="shadowOffsetOuter1"></feComposite>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.341176471 0 0 0 0 0.709803922 0 0 0 0 0.376470588 0 0 0 0.3 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="Homepage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linejoin="round">
<g id="State---Multiple" transform="translate(-319.000000, -358.000000)">
<g id="Group" transform="translate(271.000000, 80.000000)">
<g id="Group-4" transform="translate(16.000000, 240.000000)">
<g id="Group-5" transform="translate(40.000000, 12.000000)">
<g id="Rectangle-2">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use stroke="#57B560" stroke-width="2" xlink:href="#path-1"></use>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,8 +0,0 @@
<svg viewBox="19.88800048828125 37.1175193787 132.07760620117188 132.07760620117188" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>.cls-1,.cls-2{fill:#0071bc;}.cls-1{fill-rule:evenodd;}.cls-2{font-size:87px;font-family:Karbon-Light, Karbon;font-weight:300;letter-spacing:-0.05em;}.cls-3{letter-spacing:-0.05em;}.cls-4{letter-spacing:-0.05em;}</style>
</defs>
<path class="cls-1" d="M 116.388 139.371 C 92.969 148.816 66.759 134.5 62.048 109.691 L 46.308 98.821 C 43.843 141.32 88.308 170.55 126.346 151.435 C 130.805 149.195 134.94 146.361 138.638 143.011 L 138.698 143.011 C 141.248 140.637 140.685 136.456 137.598 134.841 L 19.888 72.671 Z" style="fill: rgb(88, 181, 96);"></path>
<path class="cls-1" d="M 149.398 127.121 L 149.398 127.021 C 150.067 124.651 148.83 122.161 146.538 121.261 L 67.478 90.011 L 142.478 130.011 C 145.178 131.489 148.552 130.08 149.398 127.121 Z" style="fill: rgb(88, 181, 96);"></path>
<path class="cls-1" d="M 151.848 109.801 C 152.508 94.561 150.578 79.801 141.228 67.721 C 130.128 53.411 111.498 47.801 96.588 49.081 C 95.428 49.181 94.268 49.351 93.108 49.451 C 77.448 50.901 62.598 59.941 53.728 75.301 C 52.968 76.621 52.278 77.971 51.638 79.301 C 51.238 79.841 50.838 80.371 50.458 80.931 L 63.838 88.061 C 64.463 86.395 65.194 84.772 66.028 83.201 C 80.584 55.935 119.197 54.651 135.532 80.889 C 140.199 88.386 142.264 97.212 141.408 106.001 L 91.518 92.621 L 145.258 113.861 C 148.274 115.053 151.585 112.994 151.848 109.761 Z" style="fill: rgb(88, 181, 96);"></path>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,27 +0,0 @@
import React, { useMemo } from "react";
import PropTypes from "prop-types";
import SEO from "../components/seo";
import { App } from "../components";
import "../global.scss";
import AppContext from "../AppContext";
import "@fontsource/metropolis/all.css"; // import Metropolis typeface
export default function IndexPage({ location }) {
const context = useMemo(
() => ({
apiUrl: process.env.GATSBY_API_URL || location.origin,
}),
[location.origin]
);
return (
<AppContext.Provider value={context}>
<SEO />
<App />
</AppContext.Provider>
);
}
IndexPage.propTypes = {
location: PropTypes.object.isRequired,
};

View File

@ -1,14 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function Arrow({ className }) {
return (
<svg className={className} viewBox="0 0 15 7" width={15} height={7} xmlns="http://www.w3.org/2000/svg">
<path d="M0 6h12L7 1" stroke="currentColor" strokeWidth="2" fill="none" fillRule="evenodd" />
</svg>
);
}
Arrow.propTypes = {
className: PropTypes.string,
};

View File

@ -1,23 +0,0 @@
import React from "react";
export default function Built(props) {
return (
<svg width="74" height="65" viewBox="0 0 74 65" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M70.723 64.302a7.37 7.37 0 01-1.284-.378c-.773-.31-1.922-.92-2.798-1.486-1.213-.783-3.053-2.198-4.377-3.366-.197-.174-.5-.44-.675-.591a30.765 30.765 0 01-.6-.54l-.697-.645c-1.56-1.439-4.53-4.45-5.93-6.012a130.07 130.07 0 00-.74-.815c-.78-.853-1.041-1.162-1.034-1.223.006-.053.031-.057.397-.065l.391-.008.106.094c.059.052.287.301.508.554.386.442.631.71 1.102 1.207.12.126.358.385.529.574.695.773 2.875 2.99 3.775 3.84l.773.728c2.248 2.122 4.849 4.165 6.701 5.264.977.58 1.39.776 2.212 1.053.665.225.984.288 1.441.288.315 0 .407-.011.604-.073.656-.203 1.032-.63 1.236-1.404.227-.863.18-1.9-.156-3.475-.407-1.902-1.404-4.676-2.618-7.284l-.48-1.034a102.853 102.853 0 00-1.512-3.031l-.435-.804a102.52 102.52 0 00-1.62-2.902c-.849-1.456-1.166-1.992-1.27-2.14-.185-.263-.25-.411-.265-.604-.01-.135-.004-.182.03-.211.1-.082.099-.083 1.212 1.791a151.95 151.95 0 011.618 2.83c.154.277.322.574.373.661.05.087.218.397.371.69.153.292.372.706.486.919 2.905 5.452 4.814 10.273 5.253 13.263.137.933.157 1.79.057 2.457a2.6 2.6 0 01-.287.887c-.103.207-.17.297-.371.492-.424.413-.778.543-1.46.538a4.251 4.251 0 01-.566-.04zm-35.6-38.46l-.167-.267c-.05-.078-.212-.352-.361-.61-.428-.738-1.288-2.173-1.341-2.236a4.831 4.831 0 01-.225-.366l-.176-.309.007-.953.008-.953.183.342c.101.189.317.586.48.884.164.298.353.647.42.776.122.232.505.899.788 1.37.081.133.226.38.323.545.096.166.217.363.269.438.124.18.385.632.386.669 0 .026-.435.704-.495.77-.012.014-.056-.029-.1-.1zm12.844-7.816a15.927 15.927 0 01-.397-.454 46.908 46.908 0 00-.6-.69l-.894-1.005A102.4 102.4 0 0043 12.545c-1.017-1.063-3.083-3.11-3.403-3.37-.062-.05-.298-.267-.524-.48-.225-.214-.64-.589-.921-.833l-.77-.672c-.241-.21-.842-.701-1.5-1.228-1.467-1.172-3.393-2.41-4.442-2.857-1.46-.621-2.446-.748-3.135-.403-.473.237-.808.689-.977 1.317-.123.462-.164 1.581-.074 2.018.017.08.058.361.092.627.055.423.057.49.021.526-.045.044-1.114.5-1.173.499-.08-.001-.116-.066-.267-.476-.297-.805-.465-1.339-.54-1.717a10.455 10.455 0 00-.115-.522c-.038-.137-.135-.79-.186-1.25a13.667 13.667 0 01-.028-.905c-.003-.608.003-.723.058-.976.15-.702.369-1.111.759-1.423.366-.294.714-.4 1.308-.401.55 0 .946.077 1.605.318 1.856.676 4.035 2.07 6.575 4.205.32.27.662.554.758.633.097.08.404.35.683.604.28.252.555.498.614.546.17.138 1.753 1.635 2.5 2.365.378.368.993.989 1.368 1.379.375.39.73.754.789.81.059.054.342.352.63.66l.927.991c.222.237.589.637.815.89.226.252.508.563.625.69.203.219.786.879 1.255 1.42a95.017 95.017 0 011.823 2.12c.194.23.32.404.314.433-.007.04-.047.051-.195.058-.183.008-.185.008-.302-.115z"
fill="#8B8C8B"
/>
<g fill="#57B560">
<path d="M10.955 47.843c-3.147-.218-5.926-1.194-8.708-3.057a18.634 18.634 0 01-.64-.455 21.592 21.592 0 00-.406-.3 35.55 35.55 0 01-1.031-.848l-.13-.112.26-.267c.306-.313.935-.953 1.1-1.119l.825-.84a4399.636 4399.636 0 011.623-1.66c.047-.05.068-.034.509.4 1.054 1.037 2.124 1.78 3.564 2.472.306.147.57.267.588.267.017 0 .073.022.124.048.312.158 1.476.511 1.96.594l.52.088c.335.057 1.562.083 1.93.042.766-.086 1.517-.283 2.07-.543a4.835 4.835 0 001.2-.77c.665-.56 1.04-1.157 1.113-1.774.078-.653-.073-1.318-.415-1.828a3.3 3.3 0 00-.39-.443c-.363-.345-.711-.557-1.309-.8-.352-.142-.818-.26-1.708-.434l-1.086-.213-1.071-.212c-1.24-.242-2.214-.456-2.809-.617-1.057-.286-2.059-.616-2.692-.887l-.435-.185c-.4-.172-.97-.486-1.418-.783-.612-.405-1.24-1.016-1.626-1.584-.443-.65-.648-1.117-.907-2.063-.155-.57-.208-1.908-.107-2.745.11-.916.459-2.015.88-2.775.279-.503.385-.666.714-1.095.97-1.267 2.307-2.315 3.695-2.895.908-.38 1.885-.654 2.721-.762l.695-.09c.45-.057 2.034-.083 2.563-.042 1.672.132 2.948.401 4.458.941.526.188 1.62.69 2.244 1.032.29.157.548.306.782.45.135.083.272.165.304.182.198.107 1.55 1.03 1.642 1.12.053.053.077.018-.411.618-.279.344-.544.674-.637.795a44.636 44.636 0 00-.565.697l-.478.597c-.071.088-.215.268-.318.399-.104.13-.234.292-.29.358-.055.066-.178.218-.272.337a1.43 1.43 0 01-.192.218c-.012 0-.182-.136-.38-.303-.302-.256-.926-.73-1.182-.9-.966-.64-1.63-.972-2.592-1.295a11.186 11.186 0 00-2.156-.49c-.361-.042-1.381-.035-1.723.013-1.295.183-2.325.624-3.048 1.306a2.68 2.68 0 00-.872 1.779c-.05.522.072 1.098.31 1.478.136.215.465.58.61.677.057.038.156.107.22.153.308.223 1.21.592 1.694.692l.535.113c.32.068.596.124 1.998.408l.97.195c.263.054.712.144.999.201.287.057.697.142.912.187.215.046.495.101.623.123 1.097.19 2.707.695 3.402 1.066l.245.13c1.846.978 2.981 2.441 3.37 4.344.135.657.159.9.159 1.647 0 .533-.012.771-.052 1.01-.32 1.95-1.058 3.45-2.385 4.853-1.045 1.105-2.265 1.868-3.929 2.459-1.064.377-2.259.603-3.706.7-.466.03-1.588.03-2.055-.003zM25.88 33.702v-14.17h5.733v28.341H25.88zM28.326 16.627a4.613 4.613 0 01-.432-.111c-.955-.29-1.7-1.068-1.93-2.016-.402-1.65.727-3.245 2.45-3.462.326-.04.369-.04.728.012 1.161.169 2.062.954 2.374 2.071.068.243.079.333.08.705.001.399-.005.448-.092.748-.23.786-.691 1.351-1.426 1.748a3.68 3.68 0 01-.93.306 3.288 3.288 0 01-.822-.001zm19.67 31.215a20.2 20.2 0 01-1.921-.256c-.954-.198-1.92-.491-2.664-.81a2.324 2.324 0 00-.255-.098c-.042 0-1.005-.482-1.349-.675a14.43 14.43 0 01-3.826-3.124 10.298 10.298 0 01-.52-.628 30.045 30.045 0 00-.238-.33c-.303-.415-.573-.814-.573-.849a.283.283 0 00-.053-.088c-.147-.187-.579-1.008-.881-1.676-.546-1.207-.938-2.705-1.124-4.297-.043-.367-.043-2.24 0-2.618.218-1.903.66-3.419 1.462-5.008.205-.405.254-.496.49-.896a16.639 16.639 0 011.104-1.576c.314-.413 1.152-1.29 1.666-1.744.268-.237.846-.7 1.135-.91a20.14 20.14 0 011.109-.724c1.055-.594 1.854-.954 2.826-1.274.787-.259 1.748-.486 2.429-.573l.695-.089c.186-.024.705-.05 1.18-.059.855-.016 1.314.005 1.99.094.175.023.42.054.545.068.664.077 2.155.467 2.826.74.117.047.224.086.238.086.022 0 .304.119.72.304 1.104.493 2.243 1.208 3.27 2.051.19.157.889.801 1.076.992 1.531 1.566 2.728 3.55 3.367 5.588.261.83.486 1.837.542 2.427.015.16.042.392.06.518.025.166.037 2.282.044 7.846l.01 7.62-7.536-.005c-4.145-.002-7.675-.014-7.845-.027zm9.645-9.965c0-5.097.002-5.045-.24-6.081a8.79 8.79 0 00-1.259-2.829c-.725-1.062-1.812-2.064-2.907-2.68a13.402 13.402 0 00-1.21-.565c-.725-.254-1.163-.367-1.797-.463-.453-.068-.584-.076-1.272-.076-.685 0-.823.009-1.274.076-1.203.18-2.33.59-3.33 1.21-1.069.662-1.94 1.506-2.688 2.601-.082.12-.15.23-.15.245a.263.263 0 01-.053.094c-.059.075-.355.634-.466.88a8.535 8.535 0 00-.58 1.919c-.194 1.1-.196 1.826-.01 2.917.076.454.27 1.168.399 1.482.04.098.074.188.074.2 0 .026.195.44.34.723.672 1.305 1.758 2.485 3.033 3.293 1.297.823 2.705 1.28 4.3 1.397.07.005 2.146.011 4.61.014l4.48.005v-4.362z" />
</g>
<g fill="#8B8C8B">
<path d="M12.858 15.565a1.32 1.32 0 01-.906-.946c-.035-.14-.043-.398-.043-1.377v-1.205h-.647v-1.023h.647V9.776h1.264v1.238h1.012v1.023h-1.012v1.085c0 1.07.001 1.086.063 1.204a.56.56 0 00.16.18c.133.086.367.084.547-.003.09-.043.137-.055.145-.034l.153.403.142.372-.064.051a2.122 2.122 0 01-.602.28c-.236.058-.652.053-.859-.01zm-11.01-2.282l-.8-2.255.629-.007a9.34 9.34 0 01.641.004c.007.006.21.633.45 1.393.24.76.445 1.39.455 1.401.01.011.226-.613.482-1.386l.464-1.405H5.26l.464 1.406c.255.773.471 1.397.481 1.386.01-.01.192-.57.405-1.244l.44-1.393.055-.169h1.28l-.802 2.262-.804 2.261-.588-.007-.59-.007-.436-1.418c-.24-.78-.442-1.412-.45-1.405-.009.008-.212.646-.453 1.419l-.437 1.404-.589.007-.588.007-.8-2.254zM9.127 13.275v-2.261h1.32v4.522h-1.32v-2.261zM15.253 12.481V9.426h1.292v1.063c0 .585.01 1.064.024 1.064.013 0 .065-.05.116-.11.123-.147.45-.349.691-.427.267-.087.789-.108 1.052-.043a1.692 1.692 0 011.225 1.16c.045.143.051.327.06 1.782l.01 1.621h-1.265l-.008-1.433c-.008-1.43-.008-1.434-.073-1.588a.892.892 0 00-.498-.476.819.819 0 00-.392-.05c-.395.02-.675.188-.835.5l-.093.18-.008 1.433-.008 1.434h-1.29v-3.055zm-5.79-2.187c-.428-.207-.52-.728-.187-1.057.447-.44 1.198-.145 1.198.472 0 .505-.538.816-1.012.585z" />
</g>
<g fill="#8B8C8B">
<path d="M9.392 6.591a1.669 1.669 0 01-1.225-1.185c-.053-.195-.057-.303-.057-1.791V2.03h1.282v1.408c0 1.356.002 1.414.06 1.574a.919.919 0 00.442.49c.12.058.178.067.41.067.237 0 .292-.01.445-.076a.902.902 0 00.552-.68c.015-.087.028-.75.028-1.471V2.031h1.31v4.522h-1.31V6.27c0-.155-.003-.282-.008-.282-.004 0-.104.088-.22.195-.35.32-.717.452-1.251.449a2.547 2.547 0 01-.458-.04zm10.761-.01a1.329 1.329 0 01-.918-.946c-.035-.14-.044-.398-.044-1.377V3.054h-.655V2.03h.655V.793h1.281V2.03h1.026v1.023h-1.026v1.084c0 1.071.001 1.086.065 1.204a.562.562 0 00.16.181c.136.085.373.084.556-.004.09-.043.139-.054.147-.033l.155.403.144.371-.065.052a2.163 2.163 0 01-.61.279c-.24.058-.662.054-.87-.01zM13.836 4.292V2.031h1.338v4.522h-1.338V4.292zM16.342 3.498V.443h1.339v6.11h-1.339V3.498zM14.176 1.31c-.434-.207-.527-.728-.19-1.056.454-.441 1.216-.146 1.216.471 0 .504-.543.815-1.026.586zM2.043.444h1.34v1.103c0 .607.002 1.104.006 1.104s.098-.082.21-.182c.394-.355.734-.49 1.296-.511.447-.017.694.029 1.047.196.555.263.96.763 1.148 1.414.057.197.066.29.066.711 0 .548-.048.792-.23 1.167-.283.582-.848 1.03-1.45 1.148-.18.036-.708.05-.855.023-.45-.088-.832-.287-1.095-.57l-.143-.153v.66h-1.34V.443zm2.926 5.1c.44-.123.765-.459.876-.904.179-.716-.201-1.41-.876-1.599a1.68 1.68 0 00-.707-.002c-.374.107-.641.35-.796.721-.086.204-.108.673-.044.909.118.432.397.736.794.864.187.06.558.066.753.011z" />
</g>
</g>
</svg>
);
}

View File

@ -1,16 +0,0 @@
import React from "react";
export default function Copy(props) {
return (
<svg width={12} height={14} viewBox="0 0 12 14" {...props}>
<path
d="M8 1H4a3 3 0 00-3 3v6h0m4-6h5a1 1 0 011 1v7a1 1 0 01-1 1H5a1 1 0 01-1-1V5a1 1 0 011-1z"
stroke="currentColor"
strokeWidth={2}
fill="none"
fillRule="evenodd"
strokeLinejoin="round"
/>
</svg>
);
}

View File

@ -1,21 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function Cylinder({ className }) {
return (
<svg className={className} viewBox="0 0 34 34" width={34} height={34} xmlns="http://www.w3.org/2000/svg">
<path
d="M17 13c8.837 0 16-2.686 16-6s-7.163-6-16-6S1 3.686 1 7s7.163 6 16 6zm0 20c8.837 0 16-2.686 16-6s-7.163-6-16-6-16 2.686-16 6 7.163 6 16 6zM33 7v20M1 27V7m7 25V12"
stroke="currentColor"
strokeWidth="2"
fill="none"
fillRule="evenodd"
strokeLinejoin="round"
/>
</svg>
);
}
Cylinder.propTypes = {
className: PropTypes.string,
};

View File

@ -1,20 +0,0 @@
import React from "react";
export default function Deco1(props) {
return (
<svg viewBox="0 0 108 90" width={108} height={90} xmlns="http://www.w3.org/2000/svg" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M2.503 60.68C17.967 87.463 52.216 96.64 79 81.176c26.784-15.464 35.961-49.713 20.497-76.498m-96.994 56C17.967 87.464 52.216 96.641 79 81.177c-24.689 4.287-42.188-2.498-52.497-20.354M59 46.536c26.784-15.464 44.916-34.204 40.497-41.857C95.08-2.973 69.784 3.36 43 18.823S-1.916 53.027 2.503 60.68C6.92 68.332 32.216 62 59 46.536z"
stroke="#57B560"
strokeWidth="2"
strokeLinejoin="round"
/>
<path
d="M2.503 60.68c2.507 4.343 11.738 4.181 24.15.403C36.983 78.745 54.431 85.443 79 81.177 52.216 96.64 17.967 87.464 2.503 60.679z"
fill="#57B560"
/>
</g>
</svg>
);
}

View File

@ -1,20 +0,0 @@
import React from "react";
export default function Deco2(props) {
return (
<svg width={54} height={41} viewBox="0 0 54 41" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M16.37 15.835l4.977 23.803a5.993 5.993 0 01-3.932-3.067L3.382 9.611c2.529 2.237 7.161 4.467 12.988 6.224z"
fill="#57B560"
/>
<path
d="M25.53 17.995c14.141 2.493 26.225.999 26.99-3.338.764-4.338-10.08-9.875-24.22-12.368-14.142-2.494-26.226-1-26.99 3.338C.545 9.964 11.389 15.5 25.53 17.995zM1.31 5.627L17.419 36.58a6 6 0 009.376 1.653L52.52 14.657h0M1.31 5.627L17.415 36.57a5.993 5.993 0 003.932 3.067l-5.005-23.941"
stroke="#57B560"
strokeWidth={2}
strokeLinejoin="round"
/>
</g>
</svg>
);
}

View File

@ -1,20 +0,0 @@
import React from "react";
export default function Deco3(props) {
return (
<svg width={27} height={27} viewBox="0 0 27 27" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M2.485 9.73c-1.134 3.12 2.996 7.482 9.224 9.749 6.228 2.267 12.195 1.58 13.328-1.534a11.921 11.921 0 01-3.562 5.088c-5.077 4.26-12.646 3.598-16.906-1.479A11.995 11.995 0 012.485 9.73z"
fill="#57B560"
/>
<path
d="M21.475 23.033c5.076-4.26 5.739-11.829 1.479-16.906C18.694 1.05 11.124.388 6.048 4.648.97 8.908.308 16.478 4.568 21.554c4.26 5.077 11.83 5.74 16.907 1.48zm3.562-5.088c-1.133 3.114-7.1 3.8-13.328 1.534-6.228-2.267-10.358-6.629-9.224-9.743"
stroke="#57B560"
strokeWidth={2}
strokeLinejoin="round"
/>
</g>
</svg>
);
}

View File

@ -1,20 +0,0 @@
import React from "react";
export default function Deco4(props) {
return (
<svg width={51} height={51} viewBox="0 0 51 51" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M7.389 10.392l-.013.022c-4.26 5.077.518 16.1 10.672 24.62 10.153 8.52 21.838 11.31 26.098 6.234l.016-.013a23.89 23.89 0 01-10.192 7.138C21.514 52.927 7.742 46.505 3.208 34.05c-3.04-8.355-1.152-17.303 4.18-23.657z"
fill="#57B560"
/>
<path
d="M33.97 48.393c12.455-4.533 18.877-18.305 14.344-30.76C43.78 5.176 30.008-1.246 17.553 3.287 5.097 7.822-1.325 21.594 3.208 34.05 7.742 46.505 21.514 52.927 33.97 48.393zm10.176-7.125c-4.26 5.077-15.945 2.285-26.098-6.235-10.154-8.52-14.932-19.542-10.672-24.62"
stroke="#57B560"
strokeWidth={2}
strokeLinejoin="round"
/>
</g>
</svg>
);
}

View File

@ -1,41 +0,0 @@
import React from "react";
export default function Deco5(props) {
return (
<svg width={97} height={95} viewBox="0 0 97 95" {...props}>
<defs>
<filter id="prefix__a" width="133.3%" height="136.1%" x="-16.7%" y="-18.1%" filterUnits="objectBoundingBox">
<feMorphology in="SourceAlpha" operator="dilate" radius={1} result="shadowSpreadOuter1" />
<feOffset in="shadowSpreadOuter1" result="shadowOffsetOuter1" />
<feMorphology in="SourceAlpha" radius={1} result="shadowInner" />
<feOffset in="shadowInner" result="shadowInner" />
<feComposite in="shadowOffsetOuter1" in2="shadowInner" operator="out" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation={4} />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.341176471 0 0 0 0 0.709803922 0 0 0 0 0.376470588 0 0 0 0.3 0"
/>
</filter>
<path
id="prefix__b"
d="M34.5 24c18.225 0 33-5.373 33-12S52.725 0 34.5 0s-33 5.373-33 12 14.775 12 33 12zm0 48c18.225 0 33-5.373 33-12s-14.775-12-33-12-33 5.373-33 12 14.775 12 33 12zm33-60v48m-66 0V12m12 9v48"
/>
</defs>
<g fill="none" fillRule="evenodd">
<path
fill="#FFF"
fillOpacity={0.8}
d="M9.782 36.669l-.064-.188c-1.961-6.242 10.014-16.204 26.97-22.375 17.126-6.234 32.847-6.238 35.114-.01L88.219 59.2c2.266 6.228-9.78 16.33-26.906 22.563-17.126 6.233-32.847 6.238-35.114.01L9.782 36.67z"
/>
<path
fill="#57B560"
d="M9.782 36.669c1.287 3.536 6.911 5.063 14.667 4.581l16.417 45.105c-7.756.482-13.38-1.045-14.667-4.58L9.782 36.668z"
/>
<g strokeLinejoin="round" transform="rotate(-20 75.593 .85)">
<use fill="#000" filter="url(#prefix__a)" xlinkHref="#prefix__b" />
<use stroke="#57B560" strokeWidth={2} xlinkHref="#prefix__b" />
</g>
</g>
</svg>
);
}

View File

@ -1,20 +0,0 @@
import React from "react";
export default function Deco6(props) {
return (
<svg width={26} height={26} viewBox="0 0 26 26" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M2.604 18.997c1.66 2.873 7.656 2.513 13.396-.8C21.74 14.881 25.05 9.87 23.392 7A11.919 11.919 0 0125 13c0 6.627-5.373 12-12 12a11.995 11.995 0 01-10.396-6.003z"
fill="#171917"
/>
<path
d="M25 13c0-6.627-5.373-12-12-12S1 6.373 1 13s5.373 12 12 12 12-5.373 12-12zm-1.608-6C25.05 9.87 21.74 14.882 16 18.196S4.265 21.87 2.608 19"
stroke="#171917"
strokeWidth={2}
strokeLinejoin="round"
/>
</g>
</svg>
);
}

View File

@ -1,17 +0,0 @@
import React from "react";
export default function Deco7(props) {
return (
<svg width={57} height={52} viewBox="0 0 57 52" {...props}>
<g fill="none" fillRule="evenodd">
<path fill="#171917" d="M29 26L1.66 30.947l18.447 19.485 26.657-3.068z" />
<path
d="M37.893 1.568L10.78 5.888l-9.12 25.06 18.447 19.484 26.657-3.068 9.12-25.058L37.894 1.568zm17.992 20.738L29 26 10.78 5.889m35.984 41.475L29 26 1.66 30.947"
stroke="#171917"
strokeWidth={2}
strokeLinejoin="round"
/>
</g>
</svg>
);
}

View File

@ -1,21 +0,0 @@
import React from "react";
export default function Deco8(props) {
return (
<svg width={146} height={146} viewBox="0 0 146 146" {...props}>
<g transform="translate(1 1)" fill="none" fillRule="evenodd">
<circle fillOpacity={0.8} fill="#FFF" cx={72} cy={72} r={72} />
<path
d="M72 144c39.765 0 72-32.235 72-72S111.765 0 72 0 0 32.235 0 72s32.235 72 72 72zm36-9.646C90.781 144.295 60.705 124.437 40.823 90 20.941 55.563 18.781 19.587 36 9.646"
stroke="#171917"
strokeWidth={2}
strokeLinejoin="round"
/>
<path
d="M36.094 9.578L36 9.646C18.781 19.587 20.94 55.563 40.823 90c19.882 34.437 49.958 54.295 67.177 44.354l.045-.013C97.445 140.484 85.133 144 72 144c-39.765 0-72-32.235-72-72C0 45.311 14.521 22.014 36.094 9.578z"
fill="#171917"
/>
</g>
</svg>
);
}

View File

@ -1,18 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function Discord({ className }) {
return (
<svg className={className} viewBox="0 0 32 36" width={32} height={36} xmlns="http://www.w3.org/2000/svg">
<path
d="M3.746 0h24.49a3.768 3.768 0 013.757 3.524l.007.198V36l-3.947-3.395-2.212-2.015-2.339-2.142.969 3.322H3.746c-1.998 0-3.637-1.564-3.74-3.524L0 28.048V3.722C0 1.736 1.575.108 3.548.005L3.746 0h24.49zm9.613 8.623l-.236-.217c-.374.005-2.658.111-5.064 1.887 0 0-2.631 4.702-2.631 10.494 0 0 1.535 2.614 5.574 2.741 0 0 .676-.799 1.224-1.489-2.32-.69-3.198-2.124-3.198-2.124s.183.127.512.309c.018 0 .036.018.073.036.055.037.11.055.164.091.457.254.914.454 1.334.617.75.309 1.645.581 2.687.78 1.37.255 2.979.346 4.733.019.86-.163 1.736-.4 2.65-.78.64-.237 1.352-.582 2.102-1.072 0 0-.914 1.47-3.308 2.142.548.672 1.206 1.453 1.206 1.453 4.039-.127 5.574-2.741 5.574-2.723 0-5.792-2.632-10.494-2.632-10.494-2.389-1.776-4.687-1.882-5.063-1.887h-.054l-.256.29c3.107.926 4.551 2.287 4.551 2.287a15.265 15.265 0 00-5.5-1.724 15.565 15.565 0 00-3.692.036c-.11 0-.202.018-.311.036-.64.073-2.193.29-4.149 1.144-.676.29-1.078.508-1.078.508l.017-.015c.166-.152 1.585-1.391 4.477-2.26l.294-.085-.183-.218zm5.995 6.481c1.023 0 1.864.89 1.864 1.997 0 1.108-.823 1.997-1.864 1.997-1.024 0-1.865-.89-1.865-1.997 0-1.107.823-1.997 1.865-1.997zm-6.671 0c1.042 0 1.882.89 1.864 1.997 0 1.108-.822 1.997-1.864 1.997-1.023 0-1.864-.89-1.864-1.997 0-1.107.822-1.997 1.864-1.997z"
fill="currentColor"
fillRule="nonzero"
/>
</svg>
);
}
Discord.propTypes = {
className: PropTypes.string,
};

View File

@ -1,21 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function DoubleRight({ className }) {
return (
<svg className={className} viewBox="0 0 12 12" width={12} height={12} xmlns="http://www.w3.org/2000/svg">
<path
d="M1 1l5 5-5 5M6 1l5 5-5 5"
stroke="currentColor"
strokeWidth="2"
fill="none"
fillRule="evenodd"
strokeLinejoin="round"
/>
</svg>
);
}
DoubleRight.propTypes = {
className: PropTypes.string,
};

View File

@ -1,17 +0,0 @@
import React from "react";
export default function DownArrow(props) {
return (
<svg width={12} height={13} viewBox="0 0 12 13" {...props}>
<path
d="M6 1v11M1 7l5 5 5-5"
stroke="currentColor"
strokeWidth={2}
fill="none"
fillRule="evenodd"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}

View File

@ -1,28 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function Download({ className }) {
return (
<svg className={className} viewBox="0 0 34 46" width={34} height={46} xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<path
d="M5 33H3a2 2 0 01-2-2V3a2 2 0 012-2h16l14 14v16a2 2 0 01-2 2h-2 0"
stroke="#171917"
strokeWidth="2"
strokeLinejoin="round"
/>
<path
d="M17 45c6.627 0 12-5.373 12-12s-5.373-12-12-12S5 26.373 5 33s5.373 12 12 12zm-5-12l5 5 5-5m-5 5V27"
stroke="#57B560"
strokeWidth="2"
strokeLinejoin="round"
/>
<path d="M19 1l14 14H21a2 2 0 01-2-2V1z" fill="#171917" />
</g>
</svg>
);
}
Download.propTypes = {
className: PropTypes.string,
};

View File

@ -1,16 +0,0 @@
import React from "react";
export default function File(props) {
return (
<svg viewBox="0 0 36 40" width="36" height="40" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M35.5 16.207L19.793.5H2A1.5 1.5 0 00.5 2v36A1.5 1.5 0 002 39.5h32a1.5 1.5 0 001.5-1.5V16.207z"
stroke="#C5CEC7"
fill="#FFF"
/>
<path d="M20 1l15 15H22a2 2 0 01-2-2V1z" fill="#C5CEC7" />
</g>
</svg>
);
}

View File

@ -1,17 +0,0 @@
import React from "react";
export default function FileCheck(props) {
return (
<svg width={38} height={42} viewBox="0 0 38 42" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M3 1h18l16 16v22a2 2 0 01-2 2H3a2 2 0 01-2-2V3a2 2 0 012-2zm12 24l3 3 5-5"
stroke="#57B560"
strokeWidth={2}
strokeLinejoin="round"
/>
<path d="M21 2l15 15H23a2 2 0 01-2-2V2z" fill="#57B560" />
</g>
</svg>
);
}

View File

@ -1,17 +0,0 @@
import React from "react";
export default function FileError(props) {
return (
<svg width={38} height={42} viewBox="0 0 38 42" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M3 1h18l16 16v22a2 2 0 01-2 2H3a2 2 0 01-2-2V3a2 2 0 012-2zm15 21v7m0 2v2"
stroke="#E65C5C"
strokeWidth={2}
strokeLinejoin="round"
/>
<path d="M21 2l15 15H23a2 2 0 01-2-2V2z" fill="#E65C5C" />
</g>
</svg>
);
}

View File

@ -1,15 +0,0 @@
import React from "react";
export default function Folder(props) {
return (
<svg width={14} height={12} viewBox="0 0 14 12" {...props}>
<path
d="M2 1h3.586a1 1 0 01.707.293l1.414 1.414A1 1 0 008.414 3H12a1 1 0 011 1v6a1 1 0 01-1 1H2a1 1 0 01-1-1V2a1 1 0 011-1z"
stroke="currentColor"
strokeWidth={2}
fill="none"
fillRule="evenodd"
/>
</svg>
);
}

View File

@ -1,17 +0,0 @@
import React from "react";
export default function FooterCube(props) {
return (
<svg width={263} height={258} viewBox="0 0 263 258" {...props}>
<g fill="none" fillRule="evenodd">
<path fill="#343734" d="M132 129L1.726 176.77l-.058.329 107.758 79.926 128.596-38.25.057-.329z" />
<path
d="M154.574.975L24.821 45.791 1.668 177.1l107.758 79.926 128.596-38.25 23.153-131.308L154.575.975zm106.6 86.492L132 129 24.82 45.791m213.202 172.983L132 129 1.668 177.099"
stroke="#343734"
strokeWidth={2}
strokeLinejoin="round"
/>
</g>
</svg>
);
}

View File

@ -1,20 +0,0 @@
import React from "react";
export default function FooterOrb(props) {
return (
<svg width={26} height={26} viewBox="0 0 26 26" {...props}>
<g fill="none" fillRule="evenodd">
<path
d="M2.604 18.997c1.66 2.873 7.656 2.513 13.396-.8C21.74 14.881 25.05 9.87 23.392 7A11.919 11.919 0 0125 13c0 6.627-5.373 12-12 12a11.995 11.995 0 01-10.396-6.003z"
fill="#343734"
/>
<path
d="M25 13c0-6.627-5.373-12-12-12S1 6.373 1 13s5.373 12 12 12 12-5.373 12-12zm-1.608-6C25.05 9.87 21.74 14.882 16 18.196S4.265 21.87 2.608 19"
stroke="#343734"
strokeWidth={2}
strokeLinejoin="round"
/>
</g>
</svg>
);
}

View File

@ -1,18 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function Github({ className }) {
return (
<svg viewBox="0 0 32 32" width={32} height={32} className={className} xmlns="http://www.w3.org/2000/svg">
<path
d="M0 16.406c0 7.247 4.584 13.397 10.942 15.566.8.151 1.092-.356 1.092-.79 0-.39-.013-1.422-.021-2.79-4.45.99-5.39-2.2-5.39-2.2-.728-1.895-1.777-2.4-1.777-2.4-1.452-1.018.11-.997.11-.997 1.606.116 2.451 1.691 2.451 1.691 1.428 2.507 3.745 1.783 4.657 1.363.145-1.06.559-1.783 1.015-2.194-3.552-.414-7.288-1.82-7.288-8.107 0-1.792.624-3.256 1.647-4.403-.164-.415-.713-2.083.158-4.34 0 0 1.343-.443 4.399 1.68A14.975 14.975 0 0116 7.933c1.36.006 2.728.188 4.007.552 3.054-2.123 4.395-1.68 4.395-1.68.873 2.257.324 3.925.16 4.34 1.025 1.147 1.644 2.611 1.644 4.403 0 6.301-3.74 7.688-7.305 8.095.575.507 1.085 1.508 1.085 3.038 0 2.193-.018 3.963-.018 4.5 0 .44.288.949 1.1.789C27.42 29.797 32 23.652 32 16.406 32 7.345 24.836 0 15.999 0 7.164 0 0 7.345 0 16.406z"
fill="currentColor"
fillRule="evenodd"
/>
</svg>
);
}
Github.propTypes = {
className: PropTypes.string,
};

View File

@ -1,16 +0,0 @@
import React from "react";
export default function Loading(props) {
return (
<svg width={26} height={26} viewBox="0 0 26 26" {...props}>
<path
d="M13 25c6.627 0 12-5.373 12-12S19.627 1 13 1 1 6.373 1 13"
stroke="#171917"
strokeWidth={2}
fill="none"
fillRule="evenodd"
strokeLinejoin="round"
/>
</svg>
);
}

View File

@ -1,20 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function Logo({ className }) {
return (
<svg viewBox="0 0 66 66" width={66} height={66} className={className} xmlns="http://www.w3.org/2000/svg">
<path
d="M52 52V33.287C52 22.784 43.599 14.052 33.096 14 22.544 13.948 13.948 22.543 14 33.096 14.052 43.599 22.784 52 33.287 52H52zM33 1c17.673 0 32 14.326 32 32v32H33C15.326 65 1 50.673 1 33 1 15.326 15.326 1 33 1z"
fillRule="nonzero"
stroke="currentColor"
strokeWidth="2"
fill="none"
/>
</svg>
);
}
Logo.propTypes = {
className: PropTypes.string,
};

View File

@ -1,18 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function LogoSolid({ className }) {
return (
<svg className={className} width={32} height={32} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path
d="M26 26v-9.849C26 10.623 21.578 6.027 16.05 6 10.497 5.973 5.973 10.496 6 16.05 6.028 21.578 10.623 26 16.151 26H26zM16 0c8.837 0 16 7.163 16 16v16H16C7.163 32 0 24.837 0 16S7.163 0 16 0z"
fill="currentColor"
fillRule="nonzero"
/>
</svg>
);
}
LogoSolid.propTypes = {
className: PropTypes.string,
};

View File

@ -1,22 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function Pyramid({ className }) {
return (
<svg className={className} viewBox="0 0 38 38" width={38} height={38} xmlns="http://www.w3.org/2000/svg">
<g fill="none" fillRule="evenodd">
<path fill="currentColor" d="M19 25L1 31l18 6 18-6z" />
<path
d="M19 1L1 31l18 6 18-6L19 1zm0 0v36m18-6l-18-6-18 6"
stroke="currentColor"
strokeWidth="2"
strokeLinejoin="round"
/>
</g>
</svg>
);
}
Pyramid.propTypes = {
className: PropTypes.string,
};

View File

@ -1,13 +0,0 @@
import React from "react";
export default function Skynet(props) {
return (
<svg width={169} height={39} viewBox="0 0 169 39" {...props}>
<path
d="M160.701 31.245c-2.736 0-4.788-.706-6.156-2.118-1.369-1.411-2.053-3.424-2.053-6.039V2.674h7.487v6.33H169v6.15h-9.02v7.355c0 1.753.886 2.63 2.66 2.63h6.134v6.106h-8.073zm-24.942 0c-1.744 0-3.352-.268-4.826-.803-1.473-.535-2.751-1.292-3.833-2.273a10.275 10.275 0 01-2.526-3.521c-.602-1.367-.902-2.882-.902-4.546 0-1.635.3-3.135.902-4.502a10.275 10.275 0 012.526-3.521c1.082-.98 2.36-1.738 3.833-2.273 1.474-.535 3.082-.803 4.826-.803h5.728c1.293 0 2.42.179 3.383.535.962.357 1.767.847 2.413 1.471a5.823 5.823 0 011.443 2.251c.316.877.474 1.835.474 2.875 0 1.961-.571 3.432-1.714 4.412-1.143.981-3.022 1.471-5.638 1.471h-8.028v-4.056h6.45c1.172 0 1.759-.52 1.759-1.56 0-1.1-.572-1.649-1.714-1.649h-4.6c-1.354 0-2.451.46-3.293 1.382-.842.921-1.263 2.228-1.263 3.922s.42 2.964 1.263 3.811c.842.847 1.94 1.27 3.292 1.27h12.268v6.107H135.76zm-22.867 0V19.567c0-2.526-1.308-3.789-3.924-3.789h-7.532v15.467H93.86V9.003h15.29c3.728 0 6.54.922 8.434 2.764 1.894 1.842 2.841 4.457 2.841 7.844v11.634h-7.532zM67.293 39v-6.418h2.39c.963 0 1.715-.193 2.256-.58a4.58 4.58 0 001.308-1.426L62.422 9.003h7.623l6.675 14.263 6.855-14.263h7.668L78.749 33.43c-.48.95-.984 1.775-1.51 2.473a7.85 7.85 0 01-1.782 1.739 7.11 7.11 0 01-2.233 1.025c-.827.223-1.781.334-2.864.334h-3.067zm-14.207-7.755l-7.713-9.316a4.647 4.647 0 01-.54-.914 2.306 2.306 0 01-.181-.913v-.535c0-.654.225-1.278.676-1.872l7.487-8.692h8.48l-9.02 10.787 9.47 11.455h-8.66zm-17.41 0V0h7.532v31.245h-7.532zm-35.315 0v-7.488h21.92c.571 0 1.037-.171 1.398-.513.36-.342.541-.825.541-1.449 0-.624-.18-1.114-.541-1.47-.36-.357-.827-.535-1.398-.535H9.38c-1.353 0-2.608-.216-3.766-.647-1.157-.43-2.15-1.025-2.976-1.782a8.005 8.005 0 01-1.94-2.742C.233 13.55 0 12.361 0 11.054 0 9.746.233 8.55.7 7.466A8.184 8.184 0 012.638 4.68c.826-.773 1.819-1.367 2.976-1.783 1.158-.416 2.413-.624 3.766-.624h22.281v7.444H9.742c-.571 0-1.03.163-1.375.49-.346.327-.52.802-.52 1.426 0 .594.174 1.07.52 1.426.345.357.804.535 1.375.535h12.9c1.383 0 2.646.216 3.788.647a9.097 9.097 0 012.977 1.805 8.038 8.038 0 011.962 2.785c.466 1.085.7 2.266.7 3.544 0 1.337-.234 2.548-.7 3.632a8.267 8.267 0 01-1.962 2.808 8.62 8.62 0 01-2.977 1.806c-1.142.416-2.405.624-3.788.624H.36z"
fill="#57B560"
fillRule="evenodd"
/>
</svg>
);
}

View File

@ -1,21 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function SmallOrb({ className }) {
return (
<svg className={className} viewBox="0 0 18 18" width={18} height={18} xmlns="http://www.w3.org/2000/svg">
<path
d="M9 17A8 8 0 109 1a8 8 0 000 16zm4-1.072C11.087 17.033 7.745 14.826 5.536 11 3.326 7.174 3.086 3.176 5 2.072"
stroke="currentColor"
strokeWidth="2"
fill="none"
fillRule="evenodd"
strokeLinejoin="round"
/>
</svg>
);
}
SmallOrb.propTypes = {
className: PropTypes.string,
};

View File

@ -1,47 +0,0 @@
import React from "react";
export default function TopSwoosh({ ...props }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
width="622"
viewBox="0 0 622 151"
{...props}
>
<defs>
<filter id="a" width="103.4%" height="103.4%" x="-1.7%" y="-1.7%" filterUnits="objectBoundingBox">
<feMorphology in="SourceAlpha" operator="dilate" radius="1" result="shadowSpreadOuter1"></feMorphology>
<feOffset in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
<feMorphology in="SourceAlpha" radius="1" result="shadowInner"></feMorphology>
<feOffset in="shadowInner" result="shadowInner"></feOffset>
<feComposite
in="shadowOffsetOuter1"
in2="shadowInner"
operator="out"
result="shadowOffsetOuter1"
></feComposite>
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="4"></feGaussianBlur>
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.341176471 0 0 0 0 0.709803922 0 0 0 0 0.376470588 0 0 0 0.3 0"
></feColorMatrix>
</filter>
<path
id="b"
d="M384 768c212.077 0 384-171.923 384-384S596.077 0 384 0 0 171.923 0 384s171.923 384 384 384zm192-51.446c-91.832 53.02-252.238-52.89-358.277-236.554C111.684 296.336 100.168 104.466 192 51.446"
></path>
</defs>
<g fill="none" fillRule="evenodd">
<g strokeLinejoin="round" transform="translate(-73 -626)">
<use fill="#000" filter="url(#a)" xlinkHref="#b"></use>
<use stroke="#57B560" strokeWidth="2" xlinkHref="#b"></use>
</g>
<path
fill="#57B560"
d="M119.706-574.998l-.78.524C27.13-521.461 38.642-329.612 144.64-145.968 250.637 37.676 410.982 143.572 502.779 90.559l.218-.052C446.488 123.254 380.859 142 310.853 142 98.857 142-73-29.904-73-241.957c0-142.44 77.542-266.765 192.706-333.04z"
></path>
</g>
</svg>
);
}

View File

@ -1,18 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
export default function Twitter({ className }) {
return (
<svg className={className} viewBox="0 0 32 32" width={32} height={36} xmlns="http://www.w3.org/2000/svg">
<path
d="M28 0a4 4 0 014 4v24a4 4 0 01-4 4H4a4 4 0 01-4-4V4a4 4 0 014-4h24zm-8.7 10.182c-1.73 0-3.131 1.48-3.131 3.304 0 .26.026.512.08.753-2.604-.138-4.912-1.452-6.459-3.453a3.436 3.436 0 00-.424 1.662c0 1.146.554 2.158 1.394 2.751a3.021 3.021 0 01-1.42-.413v.04c0 1.603 1.08 2.938 2.515 3.241-.264.078-.54.116-.827.116-.201 0-.398-.02-.589-.058.399 1.312 1.556 2.269 2.927 2.294a6.083 6.083 0 01-4.639 1.37 8.544 8.544 0 004.803 1.484c5.765 0 8.915-5.036 8.915-9.403 0-.144-.002-.286-.008-.427A6.55 6.55 0 0024 11.73a6.005 6.005 0 01-1.8.52 3.28 3.28 0 001.378-1.827 6.076 6.076 0 01-1.99.802 3.05 3.05 0 00-2.287-1.044z"
fill="currentColor"
fillRule="evenodd"
/>
</svg>
);
}
Twitter.propTypes = {
className: PropTypes.string,
};

View File

@ -1,64 +0,0 @@
import Logo from "./Logo";
import Download from "./Download";
import DoubleRight from "./DoubleRight";
import Github from "./Github";
import Twitter from "./Twitter";
import Discord from "./Discord";
import Arrow from "./Arrow";
import Cylinder from "./Cylinder";
import SmallOrb from "./SmallOrb";
import Pyramid from "./Pyramid";
import LogoSolid from "./LogoSolid";
import File from "./File";
import FileCheck from "./FileCheck";
import FileError from "./FileError";
import Loading from "./Loading";
import Skynet from "./Skynet";
import Copy from "./Copy";
import FooterOrb from "./FooterOrb";
import FooterCube from "./FooterCube";
import Built from "./Built";
import DownArrow from "./DownArrow";
import Folder from "./Folder";
import Deco1 from "./Deco1";
import Deco2 from "./Deco2";
import Deco3 from "./Deco3";
import Deco4 from "./Deco4";
import Deco5 from "./Deco5";
import Deco6 from "./Deco6";
import Deco7 from "./Deco7";
import Deco8 from "./Deco8";
export {
Logo,
Download,
DoubleRight,
Github,
Twitter,
Discord,
Arrow,
Cylinder,
SmallOrb,
Pyramid,
LogoSolid,
File,
FileCheck,
FileError,
Loading,
Copy,
Skynet,
FooterOrb,
FooterCube,
Built,
DownArrow,
Folder,
Deco1,
Deco2,
Deco3,
Deco4,
Deco5,
Deco6,
Deco7,
Deco8,
};

View File

@ -1,47 +0,0 @@
// Colors
$white: #fff;
$white90: rgba(255, 255, 255, 0.9);
$white80: rgba(255, 255, 255, 0.8);
$white70: rgba(255, 255, 255, 0.7);
$white60: rgba(255, 255, 255, 0.6);
$white50: rgba(255, 255, 255, 0.5);
$white40: rgba(255, 255, 255, 0.4);
$white30: rgba(255, 255, 255, 0.3);
$white20: rgba(255, 255, 255, 0.2);
$white10: rgba(255, 255, 255, 0.1);
$black: #000;
$black90: rgba(0, 0, 0, 0.9);
$black80: rgba(0, 0, 0, 0.8);
$black70: rgba(0, 0, 0, 0.7);
$black60: rgba(0, 0, 0, 0.6);
$black50: rgba(0, 0, 0, 0.5);
$black40: rgba(0, 0, 0, 0.4);
$black30: rgba(0, 0, 0, 0.3);
$black20: rgba(0, 0, 0, 0.2);
$black10: rgba(0, 0, 0, 0.1);
$greenBg: #f1f7f2;
$green: #57b560;
$greenHover: #4ea156;
$darkGray: #171917;
$gray: #5a5e5b;
$lightGray: #969a97;
$red: #e65c5c;
// fonts
$font: "Metropolis", Helvetica, Arial, Sans-Serif;
$font2: "Metropolis", Helvetica, Arial, Sans-Serif;
// Breakpoints
$tinybp: 374px;
$smallbp: 500px;
$smbp: 640px;
$mediumbp: 680px;
$largebp: 840px;
$xlargebp: 1100px;
// Transitions
$fadeOff: left 0s 0.15s, opacity 0.15s;
$fadeOn: left 0s, opacity 0.15s;

Some files were not shown because too many files have changed in this diff Show More