├── .dockerignore ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .travis.yml ├── Dockerfile ├── Jenkinsfile ├── LICENSE ├── README.md ├── blog └── advanced-2.0 │ └── en │ ├── admin-quick-start.md │ ├── app-template.md │ ├── canary-release.md │ ├── cicd-jenkinsfile.md │ ├── hpa.md │ ├── ingress-demo.md │ ├── job-quick-start.md │ ├── mysql-statefulset.md │ ├── s2i.md │ └── wordpress-deployment.md ├── content ├── blog │ ├── en │ │ └── monitoring-k8s-control-plane.md │ └── zh-CN │ │ ├── benlai-devops.md │ │ ├── console-opensource.md │ │ ├── devops-automatic-testing.md │ │ ├── install-cert-managner-on-k8s.md │ │ ├── kubernetes-kubesphere-ha.md │ │ ├── kubesphere-orion.md │ │ ├── kubesphere-release-note-post.md │ │ ├── kubesphere-values.md │ │ ├── microservice-blog.md │ │ ├── netapp.md │ │ ├── nodejs-app.md │ │ ├── openpitrix-insight.md │ │ ├── prow.md │ │ ├── release-210.md │ │ └── skywalking-kubesphere.md ├── conference │ ├── en │ │ ├── admin-quick-start.md │ │ ├── app-template.md │ │ ├── canary-release.md │ │ ├── cicd-jenkinsfile.md │ │ ├── csi.md │ │ ├── hpa.md │ │ ├── logging.md │ │ └── porter.md │ └── zh-CN │ │ ├── csi.md │ │ ├── jenkins-x.md │ │ ├── logging.md │ │ └── porter.md └── install │ ├── en │ ├── all-in-one.md │ └── kubesphere-on-k8s.md │ └── zh-CN │ ├── all-in-one.md │ └── kubesphere-on-k8s.md ├── docker_push ├── gatsby-config.js ├── gatsby-node.js ├── nginx-server-rules.conf ├── package.json ├── src ├── assets │ ├── advanced.svg │ ├── app-install-left.svg │ ├── app-install-right.svg │ ├── arrow.svg │ ├── banner-bg.svg │ ├── bg-1.svg │ ├── bg-2.svg │ ├── bg-3.svg │ ├── building.svg │ ├── case-icon.png │ ├── certified.svg │ ├── check.svg │ ├── close.svg │ ├── cloud-native.png │ ├── community.svg │ ├── dashboard-en.png │ ├── dashboard.png │ ├── date.svg │ ├── download-bg.svg │ ├── download.svg │ ├── earth.svg │ ├── easyuse.svg │ ├── efficient.svg │ ├── email.svg │ ├── express.svg │ ├── facebook-default.svg │ ├── facebook-hover.svg │ ├── flexible.svg │ ├── fonts │ │ └── ProximaNova │ │ │ ├── ProximaNova-Bold.ttf │ │ │ ├── ProximaNova-Bold.woff │ │ │ ├── ProximaNova-Bold.woff2 │ │ │ ├── ProximaNova-Light.ttf │ │ │ ├── ProximaNova-Light.woff │ │ │ ├── ProximaNova-Light.woff2 │ │ │ ├── ProximaNova-Regular.ttf │ │ │ ├── ProximaNova-Regular.woff │ │ │ ├── ProximaNova-Regular.woff2 │ │ │ ├── ProximaNova-Regular_1.ttf │ │ │ ├── ProximaNova-Regular_1.woff │ │ │ ├── ProximaNova-Regular_1.woff2 │ │ │ ├── ProximaNova-Semibold.ttf │ │ │ ├── ProximaNova-Semibold.woff │ │ │ ├── ProximaNova-Semibold.woff2 │ │ │ ├── ProximaNova-SemiboldIt.ttf │ │ │ ├── ProximaNova-SemiboldIt.woff │ │ │ ├── ProximaNova-SemiboldIt.woff2 │ │ │ └── stylesheet.css │ ├── github-default.svg │ ├── github-hover.svg │ ├── group.svg │ ├── group_code.svg │ ├── icon-appendix.svg │ ├── icon-bug.svg │ ├── icon-chat.svg │ ├── icon-design.svg │ ├── icon-git.svg │ ├── icon-multi-node.svg │ ├── icon-node.svg │ ├── icon-roadmap.svg │ ├── icon-volume.svg │ ├── logo.svg │ ├── paging.svg │ ├── people.svg │ ├── play.svg │ ├── right-arrow.svg │ ├── slack-color.svg │ ├── slack.svg │ ├── slider-1.png │ ├── slider-2.png │ ├── slider-3.png │ ├── slider-bg.svg │ ├── star-left.svg │ ├── star-right.svg │ ├── twitter-default.svg │ ├── twitter-hover.svg │ ├── video.svg │ ├── wechat.svg │ └── wechat_code.svg ├── components │ ├── Button │ │ ├── index.js │ │ └── index.module.scss │ ├── Card │ │ ├── Contrib │ │ │ ├── index.js │ │ │ └── index.module.scss │ │ └── Install │ │ │ ├── index.js │ │ │ ├── index.module.scss │ │ │ └── select.js │ ├── Checkbox │ │ ├── index.js │ │ └── index.module.scss │ ├── Download │ │ ├── AdvancedModal │ │ │ ├── index.js │ │ │ └── index.module.scss │ │ ├── CommunityModal │ │ │ ├── index.js │ │ │ └── index.module.scss │ │ └── ExpressModal │ │ │ ├── index.js │ │ │ └── index.module.scss │ ├── Footer │ │ ├── index.js │ │ └── index.module.scss │ ├── Form │ │ ├── Form.jsx │ │ ├── Item.jsx │ │ ├── index.js │ │ └── index.module.scss │ ├── Header │ │ ├── index.js │ │ └── index.module.scss │ ├── Headings │ │ ├── index.js │ │ └── index.module.scss │ ├── Labels │ │ ├── index.js │ │ └── index.module.scss │ ├── Language │ │ ├── index.js │ │ └── index.module.scss │ ├── Logo │ │ ├── index.js │ │ └── index.module.scss │ ├── Modal │ │ ├── index.js │ │ └── index.scss │ ├── Notification │ │ ├── index.js │ │ └── index.module.scss │ ├── Pagination │ │ ├── index.js │ │ └── index.module.scss │ ├── RoadMap │ │ ├── index.js │ │ └── index.module.scss │ ├── Search │ │ ├── index.js │ │ └── index.module.scss │ ├── Select │ │ ├── index.js │ │ └── index.module.scss │ ├── Slider │ │ ├── index.js │ │ └── index.module.scss │ ├── Star │ │ ├── index.js │ │ └── index.module.scss │ ├── Tags │ │ ├── index.js │ │ └── index.module.scss │ ├── VideoModal │ │ ├── index.js │ │ └── index.module.scss │ └── withI18next │ │ └── index.js ├── data │ ├── index.js │ └── videos.json ├── html.js ├── i18n.js ├── layouts │ ├── index.js │ ├── index.scss │ ├── opensource.js │ └── opensource.scss ├── locales │ ├── en │ │ └── common.json │ └── zh-CN │ │ └── common.json ├── pages │ ├── 404.js │ ├── apply.html │ ├── blogs.js │ ├── blogs.scss │ ├── building.js │ ├── building.scss │ ├── conferences.js │ ├── conferences.scss │ ├── download.js │ ├── download.scss │ ├── index.js │ ├── index.scss │ ├── projects.js │ ├── projects.scss │ ├── trends.js │ ├── trends.scss │ ├── videos.js │ └── videos.scss ├── styles │ ├── _variables.scss │ ├── base.scss │ ├── main.scss │ ├── markdown.scss │ ├── mixins.scss │ └── utilities.scss ├── templates │ ├── b16-tomorrow-dark.scss │ ├── blog.js │ ├── blog.scss │ ├── install.js │ └── install.scss └── utils │ ├── constants.js │ ├── index.js │ ├── polifills.js │ └── swipe.js ├── static ├── 163.jpg ├── Gitlab.svg ├── Jenkins.svg ├── Kafka.svg ├── Logstash.svg ├── MongoDB.svg ├── Tensorflow.svg ├── alert.svg ├── all-in-one.json ├── asciinema-player.css ├── asciinema-player.js ├── catalog.json ├── ccidnet.jpg ├── cluster-architecture-zh.svg ├── cluster-architecture.png ├── cluster-architecture.svg ├── coredns.svg ├── devops.svg ├── doit.jpg ├── donews.jpg ├── drone.svg ├── drupal.svg ├── etcd-operator.svg ├── favicon.ico ├── fluentbit-operator.svg ├── fluentd.svg ├── hadoop.svg ├── im.svg ├── infoq.jpg ├── it168.jpg ├── jaeger-operator.svg ├── jingji.jpg ├── kibana.svg ├── kubecon-bg.svg ├── kubecon.svg ├── kubernetes-dashboard.svg ├── kubesphere-console.png ├── kubesphere.svg ├── leiphone.jpg ├── login-page-en.png ├── login-page.png ├── logo.svg ├── magento.svg ├── mariadb.svg ├── multi-node.json ├── mysql.svg ├── newstack.jpg ├── notification.svg ├── openpitrix.svg ├── owncloud.svg ├── pic01.png ├── pic02.png ├── pic03.png ├── pic04.svg ├── pic04_en.svg ├── pic05.png ├── pic06.png ├── pic07.png ├── pic08.png ├── pic09.png ├── pic10.png ├── pic11.png ├── porter.svg ├── postgresql.svg ├── qcon-bg.svg ├── qcon.svg ├── qingcloud.svg ├── qingstor.svg ├── redis.svg ├── s2i-operator.svg ├── smooth-scroll.polyfills.min.js ├── soft6.jpg ├── techweb.jpg ├── tmtpost.jpg ├── tomcat.svg ├── top.svg ├── video-bg.svg ├── weavecloud.svg ├── wordpress.svg └── zhiding.jpg └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .cache 3 | .vscode 4 | src 5 | node_modules 6 | yarn-error.log -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project dependencies 2 | .cache 3 | node_modules 4 | yarn-error.log 5 | 6 | # Build directory 7 | /public 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn.lock 3 | package-lock.json -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "trailingComma": "es5" 5 | } 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: node_js 3 | sudo: false 4 | dist: trusty 5 | node_js: 6 | - "9" 7 | 8 | services: 9 | - docker 10 | 11 | cache: 12 | yarn: true 13 | directories: 14 | - "node_modules" 15 | 16 | install: 17 | - yarn 18 | 19 | script: 20 | - yarn build 21 | 22 | before_deploy: 23 | - docker build -t kubesphere/kubesphere.github.io . 24 | 25 | deploy: 26 | provider: script 27 | script: bash docker_push 28 | on: 29 | branch: master -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM leoendlessx/gatsby:latest 2 | COPY nginx-server-rules.conf /etc/nginx/server.conf 3 | ADD public/ /pub -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent { 3 | node { 4 | label 'nodejs' 5 | } 6 | } 7 | parameters { 8 | string(name: 'BRANCH_NAME', defaultValue: 'master', description: '') 9 | string(name: 'IMAGE_NAME', defaultValue: 'user/ks-ui', description: 'dockerhub repository') 10 | string(name: 'TAG', defaultValue: 'latest', description: '') 11 | booleanParam(name: 'CODE_ANAlYSIS', defaultValue: false, description: 'is run code analysis?') 12 | string(name: 'PORJECT_KEY', defaultValue: 'ks', description: 'sonarqube project key') 13 | booleanParam(name: 'PUSH_IMAGE', defaultValue: false, description: 'is push image?') 14 | } 15 | stages { 16 | stage('get source') { 17 | steps { 18 | checkout([$class: 'GitSCM', branches: [[name: '*/$BRANCH_NAME']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/kubesphere/kubesphere.github.io.git']]]) 19 | } 20 | } 21 | stage('parallel task') { 22 | parallel { 23 | stage('get dependencies') { 24 | steps { 25 | container('nodejs') { 26 | sh 'yarn config set registry https://registry.npm.taobao.org' 27 | sh 'yarn' 28 | } 29 | } 30 | } 31 | stage('code analysis') { 32 | when { 33 | environment name: 'CODE_ANAlYSIS', value: 'true' 34 | } 35 | steps { 36 | container('nodejs') { 37 | withCredentials([string(credentialsId : 'SONAR_TOKEN' ,variable : 'SONAR_TOKEN' ,)]) { 38 | withSonarQubeEnv('sonar') { 39 | sh 'sonar-scanner -Dsonar.branch=$BRANCH_NAME -Dsonar.projectKey=$PORJECT_KEY -Dsonar.sources=. -Dsonar.login=$SONAR_TOKEN' 40 | } 41 | waitForQualityGate 'false' 42 | } 43 | } 44 | } 45 | } 46 | } 47 | } 48 | stage('build') { 49 | steps { 50 | container('nodejs') { 51 | sh 'yarn build' 52 | sh 'docker build -t ks-ui .' 53 | } 54 | } 55 | } 56 | stage('push image') { 57 | when { 58 | environment name: 'PUSH_IMAGE', value: 'true' 59 | } 60 | steps { 61 | container('nodejs') { 62 | withCredentials([usernamePassword(credentialsId : 'docker' ,passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,)]) { 63 | sh 'echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin' 64 | sh 'docker tag ks-ui $IMAGE_NAME:$TAG' 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Website for [KubeSphere](https://github.com/kubesphere/kubesphere). 2 | 3 | [![Build Status](https://travis-ci.org/kubesphere/kubesphere.github.io.svg)](https://travis-ci.org/kubesphere/kubesphere.github.io) 4 | 5 | ## Develop 6 | 7 | ### Setting up with git 8 | If you choose this way, we recommend you to install some requisites 9 | - git 10 | - node.js 11 | - yarn (or npm, `we recommend yarn`) 12 | 13 | Check your requisites: 14 | ```shell 15 | git --version 16 | node -v 17 | yarn -v 18 | ``` 19 | 20 | Then you are ready to go: 21 | ```shell 22 | git clone https://github.com/kubesphere/kubesphere.github.io.git 23 | 24 | cd kubesphere.github.io 25 | 26 | yarn 27 | 28 | yarn develop 29 | ``` 30 | -------------------------------------------------------------------------------- /blog/advanced-2.0/en/cicd-jenkinsfile.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Creating a CI/CD Pipeline to Deploy Spring Boot App to Kubernetes" 3 | --- 4 | 5 | ## Objective 6 | 7 | This tutorial shows you how to create a CI/CD Pipeline within DevOps project, which is intended for deploying a Spring Boot sample application to Kubernetes. 8 | 9 | ## Overview 10 | 11 | Based on the existing Jenkinsfile in the sample GitHub repository, we can create a pipeline to build and complete the stages and steps (e.g. unit test, sonarqube analysis), which totally consists of eight stages as shown below. 12 | 13 | ![](https://pek3b.qingstor.com/kubesphere-docs/png/20190719005547.png) 14 | 15 | ## Prerequisites 16 | 17 | You've completed all steps in [Tutorial 1](admin-quick-start.md). 18 | 19 | ## Hands-on Lab 20 | 21 | ### Step 1: Create Credentials 22 | 23 | To get started, we need to create 3 credentials, i.e. DockerHub、GitHub and kubeconfig. 24 | 25 | 1.1. Sign in with `project-regular` account and enter into the `demo-devops`, navigate to **Credentials**, then click on the **Create Credentials**. 26 | 27 | ![](https://pek3b.qingstor.com/kubesphere-docs/png/20190719010621.png) 28 | 29 | |Credential ID|Type|Username/Password/Secret|Content| 30 | |----|----|----|----| 31 | | dockerhub-id |Account Credentials | Enter your personal DockerHub account information |\| 32 | | github-id |Account Credentials | Enter your personal GitHub account information |\| 33 | | kube-config | 34 | |demo-kubeconfig|kubeconfig|\|It will be automatically filled with the kubeconfig of the cluster | 35 | |sonar-token|secret_text | You can get secret by creating SonarQube token | \ | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /content/blog/zh-CN/kubesphere-release-note-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'KubeSphere 容器平台发布 2.1.1,全面支持 Kubernetes 1.17' 3 | tag: 'Kubernetes,release,kubesphere' 4 | createTime: '2020-02-24' 5 | author: 'Feynman' 6 | snapshot: 'https://pek3b.qingstor.com/kubesphere-docs/png/20200224093525.png' 7 | --- 8 | 9 | ![](https://pek3b.qingstor.com/kubesphere-docs/png/20200224093525.png) 10 | 11 | 农历二月二,KubeSphere 开源社区激动地向大家宣布,KubeSphere 容器平台 2.1.1 正式发布! 12 | 13 | KubeSphere 作为 **开源的企业级容器平台**,对 2.1.1 版本定义的是 **进一步增强生产可用性**,修复了多个组件的 Bug,升级了内置的多个开源组件。借助 KubeSphere,您可以快速安装与管理原生的 Kubernetes,KubeSphere 2.1.1 已支持至 Kubernetes 1.17,帮助您上手 Kubernetes 新版本中新增的特性。并且,还向前兼容与支持 Kubernetes 1.17 之前的 3 个版本,您可以按需进行安装。 14 | 15 | KubeSphere 能够帮助企业快速构建一个功能丰富的容器云平台。让企业在享受 Kubernetes 的弹性伸缩与敏捷部署的同时,还可以在容器平台拥有 IaaS 平台的存储与网络能力,获得与 IaaS 平台一样稳定的用户体验。比如,我们在 KubeSphere 2.1.1 新增了对阿里云与腾讯云块存储插件的集成,支持为 Pod 挂载公有云的存储,为有状态应用提供更稳定的持久化存储的能力。 16 | 17 | 除此之外,我们还将安装步骤再一次简化。2.1.1 简化了在已有 Kubernetes 上安装的步骤,无需再像 2.1.0 安装一样,配置集群 CA 证书路径。并且,也将 etcd 监控作为了可选安装项。真正实现了一条命令即可在已有的 Kubernetes 集群上快速安装 KubeSphere。 18 | 19 | 关于 2.1.1 的更新详情,请参考 [Release Note](https://kubesphere.com.cn/docs/v2.1/zh-CN/release/release-v211/)。 20 | 21 | 下面演示两种最简单的安装方法,解锁如何最快尝鲜 KubeSphere 2.1.1。 22 | 23 | ## 如何在 Linux 快速安装 2.1.1 24 | 25 | 1. 本文将演示 All-in-One 安装,请准备一台干净的机器(虚拟机或物理机),安装前关闭防火墙,并确保您的机器符合以下的最小要求: 26 | 27 | - 机器配置: 28 | 29 | - CPU: 最小化安装需 2 Cores;完整安装需 8 Cores 30 | - Memory: 最小化安装需 4 GB;完整安装需 16 GB 31 | 32 | - 操作系统: 33 | 34 | - CentOS 7.4 ~ 7.7 (64-bit) 35 | - Ubuntu 16.04/18.04 LTS (64-bit) 36 | - RHEL 7.4 (64-bit) 37 | - Debian Stretch 9.5 (64-bit) 38 | 39 | 2. 下载 `KubeSphere 2.1.1` 安装包至待安装机器,进入安装目录。 40 | 41 | > 提示:Installer 默认仅开启最小化安装,若机器资源充足,请在 `conf/common.yaml` 中开启可选功能组件,将其设置为 true,再进行安装。 42 | 43 | ```bash 44 | curl -L https://kubesphere.io/download/stable/v2.1.1 > installer.tar.gz \ 45 | && tar -zxf installer.tar.gz && cd kubesphere-all-v2.1.1/scripts 46 | ``` 47 | 48 | 3. 建议使用 `root` 用户安装,执行 `install.sh` 脚本,输入 `1` 选择第一种即 all-in-one 模式。 49 | 50 | ```bash 51 | ./install.sh 52 | ``` 53 | 54 | 请耐心等待,当看到 `"Successful"` 的日志与登录信息提示,则说明 KubeSphere 安装成功,请使用日志提示的管理员账号登陆控制台。 55 | 56 | 57 | ## 如何在 Kubernetes 安装 2.1.1 58 | 59 | 请确保您的 Kubernetes 集群满足以下前提条件: 60 | 61 | > - `Kubernetes` 版本: `1.15.x ≤ K8s version ≤ 1.17.x`; 62 | > - `Helm`版本: `2.10.0 ≤ Helm Version < 3.0.0`(不支持 helm 2.16.0),且已安装了 Tiller,(v3.0 将支持 Helm v3); 63 | > - 集群已有默认的存储类型(StorageClass) 64 | > - 集群能够访问外网。 65 | 66 | 若您的集群可用的资源符合 CPU > 1 Core,可用内存 > 2 G,可以参考以下命令开启 KubeSphere 最小化安装: 67 | 68 | ```yaml 69 | kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-minimal.yaml 70 | ``` 71 | 72 | 若您的集群可用的资源符合 CPU ≥ 8 Core,可用内存 ≥ 16 G,建议参考以下命令开启 KubeSphere 完整安装,即开启所有功能组件的安装: 73 | 74 | ```yaml 75 | kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-complete-setup.yaml 76 | ``` 77 | 78 | 查看滚动刷新的安装日志,请耐心等待安装成功。当看到 `"Successful"` 的日志与登录信息提示,则说明 KubeSphere 安装成功,请使用日志提示的管理员账号登陆控制台。 79 | 80 | ```bash 81 | kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f 82 | ``` 83 | 84 | ## 如何升级至 2.1.1 85 | 86 | 升级前需要同步老版本的配置修改,请参考官网文档下的升级指南。 87 | -------------------------------------------------------------------------------- /content/conference/en/cicd-jenkinsfile.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Creating a CI/CD Pipeline to Deploy Spring Boot App to Kubernetes' 3 | type: 'QCon' 4 | author: 'xxx' 5 | --- 6 | 7 | ## Objective 8 | 9 | This tutorial shows you how to create a CI/CD Pipeline within DevOps project, which is intended for deploying a Spring Boot sample application to Kubernetes. 10 | 11 | ## Overview 12 | 13 | Based on the existing Jenkinsfile in the sample GitHub repository, we can create a pipeline to build and complete the stages and steps (e.g. unit test, sonarqube analysis), which totally consists of eight stages as shown below. 14 | 15 | ![](https://pek3b.qingstor.com/kubesphere-docs/png/20190719005547.png) 16 | 17 | ## Prerequisites 18 | 19 | You've completed all steps in [Tutorial 1](admin-quick-start.md). 20 | 21 | ## Hands-on Lab 22 | 23 | ### Step 1: Create Credentials 24 | 25 | To get started, we need to create 3 credentials, i.e. DockerHub、GitHub and kubeconfig. 26 | 27 | 1.1. Sign in with `project-regular` account and enter into the `demo-devops`, navigate to **Credentials**, then click on the **Create Credentials**. 28 | 29 | ![](https://pek3b.qingstor.com/kubesphere-docs/png/20190719010621.png) 30 | 31 | | Credential ID | Type | Username/Password/Secret | Content | 32 | | --------------- | ------------------- | -------------------------------------------------------------------- | ------- | 33 | | dockerhub-id | Account Credentials | Enter your personal DockerHub account information | \| | 34 | | github-id | Account Credentials | Enter your personal GitHub account information | \| | 35 | | kube-config | 36 | | demo-kubeconfig | kubeconfig | \|It will be automatically filled with the kubeconfig of the cluster | 37 | | sonar-token | secret_text | You can get secret by creating SonarQube token | \ | 38 | -------------------------------------------------------------------------------- /content/install/en/kubesphere-on-k8s.md: -------------------------------------------------------------------------------- 1 | ## Install KubeSphere on existing Kubernetes 2 | 3 | In addition to supporting deploy on virtual machine and bare metal, KubeSphere also supports installing on cloud-hosted and on-prem Kubernetes cluster. 4 | 5 | ## Deploy On Kubernetes 6 | 7 | ### Prerequisites 8 | 9 | > - `Kubernetes version`: `1.15.x, 1.16.x, 1.17.x` 10 | > - `Helm version` >= `2.10.0`,see [Install and Configure Helm in Kubernetes](https://devopscube.com/install-configure-helm-kubernetes/); 11 | > - An existing Storage Class in your Kubernetes cluster, use `kubectl get sc` to verify it. 12 | > - Your cluster can connect to an external network. 13 | > - The CSR signing feature is activated in kube-apiserver when it is started with the `--cluster-signing-cert-file` and `--cluster-signing-key-file` parameters, see [RKE installation issue](https://github.com/kubesphere/kubesphere/issues/1925#issuecomment-591698309). 14 | 15 | ### Installation 16 | 17 | Install KubeSphere using kubectl. 18 | 19 | - If there are 1 Core and 2 GB RAM available in your cluster, use the command below to trigger a default minimal installation only: 20 | 21 | ```bash 22 | kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-minimal.yaml 23 | ``` 24 | 25 | - If there are 8 Cores and 16 GB RAM available in your cluster, use the command below to install a complete KubeSphere, i.e. with all components enabled: 26 | 27 | ```yaml 28 | kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-complete-setup.yaml 29 | ``` 30 | 31 | Verify the real-time logs. When you see the following outputs, congratulation! You can access KubeSphere console in your browser now. 32 | 33 | ```bash 34 | $ kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f 35 | 36 | ##################################################### 37 | ### Welcome to KubeSphere! ### 38 | ##################################################### 39 | Console: http://10.128.0.34:30880 40 | Account: admin 41 | Password: P@88w0rd 42 | 43 | NOTE:Please modify the default password after login. 44 | ##################################################### 45 | ``` 46 | 47 | ### Enable Pluggable Components 48 | 49 | If you start with a default minimal installation, execute the following command to open the configmap in order to enable more pluggable components at your will. Make sure your cluster has enough CPU and memory, see [Enable Pluggable Components](https://kubesphere.io/docs/v2.1/en/installation/pluggable-components/). 50 | 51 | ```bash 52 | kubectl edit cm -n kubesphere-system ks-installer 53 | ``` 54 | 55 | ### FAQ 56 | 57 | If you have further questions please do not hesitate to raise issues on [GitHub](https://github.com/kubesphere/kubesphere/issues). 58 | -------------------------------------------------------------------------------- /content/install/zh-CN/kubesphere-on-k8s.md: -------------------------------------------------------------------------------- 1 | ## 在 Kubernetes 在线部署 KubeSphere 2 | 3 | KubeSphere 除了支持部署在 Linux 之上,还支持在已有 Kubernetes 集群之上部署 [KubeSphere](https://kubesphere.io/)。 4 | 5 | ## 准备工作 6 | 7 | KubeSphere 支持在已有 Kubernetes 集群之上在线安装 [KubeSphere](https://kubesphere.io/)。在安装之前,请确认您的环境满足以下前提条件: 8 | 9 | 10 | > - `Kubernetes` 版本: `1.15.x、1.16.x、1.17.x`; 11 | > - `Helm`版本: `2.10.0 ≤ Helm Version < 3.0.0`(不支持 helm 2.16.0 [#6894](https://github.com/helm/helm/issues/6894)),且已安装了 Tiller,参考 [如何安装与配置 Helm](https://devopscube.com/install-configure-helm-kubernetes/) (预计 3.0 支持 Helm v3); 12 | > - 集群已有默认的存储类型(StorageClass),若还没有准备存储请参考 [安装 OpenEBS 创建 LocalPV 存储类型](https://kubesphere.com.cn/docs/v2.1/zh-CN/appendix/install-openebs/) 用作开发测试环境。 13 | > - CSR signing 功能在 kube-apiserver 中被激活,参考 [RKE installation issue](https://github.com/kubesphere/kubesphere/issues/1925#issuecomment-591698309)。 14 | > - 集群能够访问外网 15 | 16 | 可参考 [前提条件](https://kubesphere.io/docs/v2.1/zh-CN/installation/prerequisites/) 验证,若待安装的环境满足以上条件则可以开始部署 KubeSphere。 17 | 18 | ## 最小化安装 KubeSphere 19 | 20 | - 若您的集群可用的资源符合 CPU > 1 Core,可用内存 > 2 G,可以参考以下命令开启 KubeSphere 最小化安装: 21 | 22 | ```yaml 23 | kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-minimal.yaml 24 | ``` 25 | 26 | - 若您的集群可用的资源符合 CPU ≥ 8 Core,可用内存 ≥ 16 G,建议参考以下命令开启 KubeSphere 完整安装,即开启所有功能组件的安装: 27 | 28 | ```yaml 29 | kubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-complete-setup.yaml 30 | ``` 31 | 32 | 2. 查看安装日志,请耐心等待安装成功。 33 | 34 | ```bash 35 | $ kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f 36 | ``` 37 | 38 | 3. 通过 `kubectl get pod --all-namespace` 查看 kubesphere 的 namespace 下所有 Pod 状态是否为 Running。确认 Pod 都正常运行后,可使用 `IP:30880` 访问 KubeSphere ConSole 界面,默认的集群管理员账号为 `admin / P@88w0rd`。 39 | 40 | ![](https://pek3b.qingstor.com/kubesphere-docs/png/20191020153911.png) 41 | 42 | 43 | 若遇到其它的安装问题需要协助支持,请在 [社区论坛](https://kubesphere.com.cn/forum/) 搜索解决方法或发布帖子,我们会尽快跟踪解决。 44 | -------------------------------------------------------------------------------- /docker_push: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin 4 | docker push kubesphere/kubesphere.github.io:latest -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | siteMetadata: { 3 | title: 'KubeSphere | Enterprise container platform, built on Kubernetes', 4 | siteUrl: 'https://kubesphere.io', 5 | availableLocales: [ 6 | { name: '简体中文', value: 'zh-CN' }, 7 | { name: 'English', value: 'en' }, 8 | ], 9 | defaultLocale: 'en', 10 | }, 11 | plugins: [ 12 | 'gatsby-plugin-react-helmet', 13 | 'gatsby-plugin-sass', 14 | { 15 | resolve: 'gatsby-transformer-remark', 16 | options: { 17 | plugins: ['gatsby-remark-prismjs', 'gatsby-remark-autolink-headers'], 18 | }, 19 | }, 20 | { 21 | resolve: 'gatsby-source-filesystem', 22 | options: { 23 | name: `content`, 24 | path: `${__dirname}/content/`, 25 | }, 26 | }, 27 | { 28 | resolve: 'gatsby-plugin-svgr', 29 | options: { 30 | icon: true, 31 | }, 32 | }, 33 | { 34 | resolve: 'gatsby-plugin-no-sourcemaps', 35 | }, 36 | { 37 | resolve: `gatsby-plugin-advanced-sitemap`, 38 | options: { 39 | exclude: ['/404', '/404.html'], 40 | }, 41 | }, 42 | ], 43 | } 44 | -------------------------------------------------------------------------------- /nginx-server-rules.conf: -------------------------------------------------------------------------------- 1 | location ~ /(?[a-z][a-z0-9]*) { 2 | if ($args = "go-get=1") { 3 | add_header Content-Type text/html; 4 | return 200 ''; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kubesphere.github.io", 3 | "description": "KubeSphere-以应用为中心的开源容器平台", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "@svgr/webpack": "^4.3.0", 7 | "@tippy.js/react": "^2.2.3", 8 | "async-validator": "^1.8.5", 9 | "classnames": "^2.2.6", 10 | "es6-shim": "^0.35.3", 11 | "gatsby": "^2.9.2", 12 | "gatsby-i18n": "^1.1.5", 13 | "gatsby-link": "^2.1.1", 14 | "gatsby-plugin-advanced-sitemap": "^1.3.1", 15 | "gatsby-plugin-no-sourcemaps": "^2.0.2", 16 | "gatsby-plugin-react-helmet": "^3.0.12", 17 | "gatsby-plugin-sass": "^2.0.11", 18 | "gatsby-plugin-sharp": "^2.1.5", 19 | "gatsby-plugin-svgr": "^2.0.2", 20 | "gatsby-remark-images": "^3.0.14", 21 | "gatsby-remark-prismjs": "^3.2.11", 22 | "gatsby-source-filesystem": "^2.0.39", 23 | "gatsby-transformer-remark": "^2.3.12", 24 | "i18next": "^17.0.3", 25 | "i18next-browser-languagedetector": "^3.0.1", 26 | "lodash": "^4.17.13", 27 | "moment-mini": "^2.22.1", 28 | "node-sass": "^4.12.0", 29 | "prismjs": "^1.16.0", 30 | "promise-polyfill": "^8.0.0", 31 | "react": "16.8", 32 | "react-dom": "^16.8.6", 33 | "react-helmet": "^5.2.1", 34 | "react-i18next": "^10.11.0", 35 | "react-modal": "^3.5.1", 36 | "swiped": "^0.1.4", 37 | "tippy.js": "^4.3.5", 38 | "whatwg-fetch": "^2.0.4" 39 | }, 40 | "keywords": [ 41 | "kubesphere", 42 | "微服务", 43 | "容器云", 44 | "容器管理平台", 45 | "docker", 46 | "kubernetes", 47 | "jenkins", 48 | "istio" 49 | ], 50 | "license": "Apache 2.0", 51 | "scripts": { 52 | "build": "gatsby build", 53 | "develop": "gatsby develop", 54 | "format": "prettier --write 'src/**/*.?(js|scss)'", 55 | "test": "echo \"Error: no test specified\" && exit 1" 56 | }, 57 | "devDependencies": { 58 | "gatsby-remark-autolink-headers": "^2.1.11", 59 | "prettier": "^1.12.0" 60 | }, 61 | "repository": { 62 | "type": "git", 63 | "url": "https://github.com/kubesphere/kubesphere.github.io" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/assets/advanced.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon-Standard 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/app-install-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/banner-bg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/bg-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/bg-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 22 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/assets/bg-3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Rectangle 3 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/assets/case-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/case-icon.png -------------------------------------------------------------------------------- /src/assets/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/cloud-native.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/cloud-native.png -------------------------------------------------------------------------------- /src/assets/community.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon-Premium 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/assets/dashboard-en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/dashboard-en.png -------------------------------------------------------------------------------- /src/assets/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/dashboard.png -------------------------------------------------------------------------------- /src/assets/date.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/earth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/easyuse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | timer 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/assets/efficient.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon-Qualified 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/email.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/express.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/assets/facebook-default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Facebook/default 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/assets/facebook-hover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Facebook/hover 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Bold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Bold.woff -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Bold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Light.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Light.woff -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Light.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Regular.woff -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Regular.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Regular_1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Regular_1.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Regular_1.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Regular_1.woff -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Regular_1.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Regular_1.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Semibold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Semibold.woff -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-Semibold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-Semibold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-SemiboldIt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-SemiboldIt.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-SemiboldIt.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-SemiboldIt.woff -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/ProximaNova-SemiboldIt.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/fonts/ProximaNova/ProximaNova-SemiboldIt.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/ProximaNova/stylesheet.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Proxima Nova'; 3 | src: url('./ProximaNova-Bold.woff2') format('woff2'), 4 | url('./ProximaNova-Bold.woff') format('woff'), 5 | url('./ProximaNova-Bold.ttf') format('truetype'); 6 | font-weight: bold; 7 | font-style: normal; 8 | } 9 | 10 | @font-face { 11 | font-family: 'Proxima Nova'; 12 | src: url('./ProximaNova-Light.woff2') format('woff2'), 13 | url('./ProximaNova-Light.woff') format('woff'), 14 | url('./ProximaNova-Light.ttf') format('truetype'); 15 | font-weight: 300; 16 | font-style: normal; 17 | } 18 | 19 | @font-face { 20 | font-family: 'Proxima Nova'; 21 | src: url('./ProximaNova-Regular.woff2') format('woff2'), 22 | url('./ProximaNova-Regular.woff') format('woff'), 23 | url('./ProximaNova-Regular.ttf') format('truetype'); 24 | font-weight: normal; 25 | font-style: normal; 26 | } 27 | 28 | @font-face { 29 | font-family: 'Proxima Nova'; 30 | src: url('./ProximaNova-Semibold.woff2') format('woff2'), 31 | url('./ProximaNova-Semibold.woff') format('woff'), 32 | url('./ProximaNova-Semibold.ttf') format('truetype'); 33 | font-weight: 600; 34 | font-style: normal; 35 | } 36 | 37 | @font-face { 38 | font-family: 'Proxima Nova'; 39 | src: url('./ProximaNova-SemiboldIt.woff2') format('woff2'), 40 | url('./ProximaNova-SemiboldIt.woff') format('woff'), 41 | url('./ProximaNova-SemiboldIt.ttf') format('truetype'); 42 | font-weight: 600; 43 | font-style: italic; 44 | } 45 | 46 | @font-face { 47 | font-family: 'Proxima Nova'; 48 | src: url('./ProximaNova-Regular_1.woff2') format('woff2'), 49 | url('./ProximaNova-Regular_1.woff') format('woff'), 50 | url('./ProximaNova-Regular_1.ttf') format('truetype'); 51 | font-weight: normal; 52 | font-style: normal; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/assets/github-default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GitHub/default 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/assets/github-hover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GitHub/hover 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/assets/group.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/icon-appendix.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Glyph/002.Object/076.Cluster/Black Copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/icon-bug.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon-Edit Copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/assets/icon-chat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon-Connect 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/assets/icon-design.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon-Lego Copy 3 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/assets/icon-git.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shape 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/icon-multi-node.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9CA3ED62-79F3-4465-B8DF-0DFF2C1BE950 5 | Created with sketchtool. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/icon-node.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8C75F48C-AF7D-464A-9272-2780CF7474AC 5 | Created with sketchtool. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/icon-roadmap.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Icon-Scale Copy 3 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/assets/icon-volume.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Glyph/002.Object/083.Nodes/Black Copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/assets/paging.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/people.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/right-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/slack-color.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/slack.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/slider-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/slider-1.png -------------------------------------------------------------------------------- /src/assets/slider-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/slider-2.png -------------------------------------------------------------------------------- /src/assets/slider-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere-retired/ks-website/b54d249ead72a506b1e2d8ea2a9b2531721c726e/src/assets/slider-3.png -------------------------------------------------------------------------------- /src/assets/star-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/twitter-default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Twitter/default 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/assets/twitter-hover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Twitter/hover 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/assets/video.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/wechat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/components/Button/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classnames from 'classnames' 3 | 4 | import styles from './index.module.scss' 5 | 6 | const Button = ({ 7 | className, 8 | children, 9 | size = 'normal', 10 | type = 'primary', 11 | onClick, 12 | ghost = false, 13 | disabled = false, 14 | }) => ( 15 | 28 | ) 29 | 30 | export default Button 31 | -------------------------------------------------------------------------------- /src/components/Button/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .button { 4 | font-size: 14px; 5 | line-height: 1.5; 6 | text-align: center; 7 | border: none; 8 | cursor: pointer; 9 | transition: all $transition-speed ease; 10 | box-sizing: border-box; 11 | vertical-align: middle; 12 | 13 | &:focus { 14 | outline: none; 15 | } 16 | 17 | & > svg { 18 | width: 21px; 19 | height: 21px; 20 | margin-right: 12px; 21 | vertical-align: text-top; 22 | } 23 | } 24 | 25 | .normal { 26 | height: 40px; 27 | padding: 7px 24px; 28 | border-radius: 20px; 29 | } 30 | 31 | .large { 32 | height: 48px; 33 | padding: 11px 40px; 34 | border-radius: 30px; 35 | font-size: 16px; 36 | } 37 | 38 | .small { 39 | height: 36px; 40 | padding: 6px 19px; 41 | border-radius: 18px; 42 | } 43 | 44 | .primary { 45 | color: #ffffff; 46 | background-image: linear-gradient( 47 | to bottom, 48 | rgba(0, 0, 0, 0), 49 | rgba(0, 0, 0, 0.1) 50 | ), 51 | linear-gradient(#55bc8a, #55bc8a); 52 | box-shadow: 0 10px 50px 0 rgba(85, 188, 138, 0.1), 53 | 0 8px 16px 0 rgba(85, 188, 138, 0.2); 54 | 55 | &:hover { 56 | background-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.1)), 57 | linear-gradient(#51b484, #51b484); 58 | } 59 | 60 | &:focus { 61 | background-color: darken($color: $primary, $amount: 5); 62 | box-shadow: 0 10px 24px 0 rgba(85, 188, 138, 0.1); 63 | } 64 | 65 | &.ghost { 66 | color: #62c092; 67 | background-color: #ffffff; 68 | background-image: none; 69 | box-shadow: none; 70 | border: solid 1px #55bc8a; 71 | 72 | &:hover { 73 | color: #fff; 74 | background-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.1)), 75 | linear-gradient(#51b484, #51b484); 76 | } 77 | } 78 | } 79 | 80 | .default { 81 | color: #242e42; 82 | background-color: transparent; 83 | 84 | &:hover { 85 | color: #fff; 86 | background: #242e42; 87 | 88 | & > svg { 89 | fill: #fff; 90 | } 91 | } 92 | 93 | &.ghost { 94 | border: solid 1px #242e42; 95 | } 96 | } 97 | 98 | .white { 99 | color: #36435c; 100 | border: solid 1px #ccd3db; 101 | background-color: #f5f8f9; 102 | 103 | &:hover { 104 | background: #ccd3db; 105 | } 106 | } 107 | 108 | .control { 109 | color: #fff; 110 | background-color: #242e42; 111 | box-shadow: 0 10px 50px 0 rgba(34, 43, 62, 0.1), 112 | 0 8px 16px 0 rgba(33, 43, 61, 0.2); 113 | 114 | &:hover { 115 | box-shadow: none; 116 | } 117 | } 118 | 119 | .disabled { 120 | opacity: 0.6; 121 | } 122 | -------------------------------------------------------------------------------- /src/components/Card/Contrib/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classnames from 'classnames' 3 | 4 | import styles from './index.module.scss' 5 | 6 | const ContribCard = ({ className, icon, title, children }) => ( 7 |
8 |
9 | 10 | {title} 11 |
12 |
{children}
13 |
14 | ) 15 | 16 | export default ContribCard 17 | -------------------------------------------------------------------------------- /src/components/Card/Contrib/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../styles/variables'; 2 | 3 | .card { 4 | width: 100%; 5 | padding: 40px; 6 | border-radius: 8px; 7 | background-color: #ffffff; 8 | transition: all $transition-speed ease; 9 | text-align: left; 10 | 11 | @media only screen and (max-width: $mobile-max-width) { 12 | padding: 28px 20px; 13 | } 14 | 15 | &:hover { 16 | box-shadow: 0 4px 15px 0 rgba(7, 42, 68, 0.1); 17 | } 18 | 19 | .title { 20 | margin-bottom: 12px; 21 | font-size: 18px; 22 | font-weight: 600; 23 | line-height: 1.56; 24 | color: #171c34; 25 | 26 | & > img { 27 | width: 28px; 28 | height: 28px; 29 | margin-right: 12px; 30 | vertical-align: text-top; 31 | } 32 | 33 | @media only screen and (max-width: $mobile-max-width) { 34 | margin-bottom: 20px; 35 | } 36 | } 37 | 38 | & + .card { 39 | margin-top: 24px; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/components/Card/Install/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classnames from 'classnames' 3 | import { withTranslation } from 'react-i18next' 4 | 5 | import styles from './index.module.scss' 6 | 7 | const InstallCard = ({ 8 | className, 9 | icon, 10 | type, 11 | title, 12 | desc, 13 | selected, 14 | onClick, 15 | t, 16 | }) => ( 17 |
26 | {icon} 27 |
28 |
{t(title)}
29 |

{t(desc)}

30 |
31 |
32 | ) 33 | 34 | export default withTranslation()(InstallCard) 35 | -------------------------------------------------------------------------------- /src/components/Card/Install/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../styles/variables'; 2 | 3 | .card { 4 | display: inline-block; 5 | width: 360px; 6 | height: 150px; 7 | padding: 35px 24px; 8 | border-radius: 5px; 9 | background-color: #ffffff; 10 | cursor: pointer; 11 | text-align: left; 12 | transition: all $transition-speed ease; 13 | vertical-align: top; 14 | 15 | &:hover { 16 | box-shadow: 0 4px 15px 0 rgba(7, 42, 68, 0.1); 17 | } 18 | 19 | &:active { 20 | box-shadow: 0 2px 4px 0 rgba(7, 42, 68, 0.1); 21 | } 22 | 23 | & > svg { 24 | width: 40px; 25 | height: 40px; 26 | margin-right: 24px; 27 | vertical-align: middle; 28 | } 29 | 30 | .text { 31 | display: inline-block; 32 | vertical-align: middle; 33 | width: 248px; 34 | 35 | & > :global(.h3) { 36 | font-weight: 600; 37 | line-height: 1.5; 38 | color: #171c34; 39 | margin-bottom: 7px; 40 | } 41 | 42 | & > p { 43 | line-height: 1.71; 44 | color: #8f94a1; 45 | } 46 | } 47 | 48 | &.select { 49 | box-shadow: 0 4px 15px 0 rgba(7, 42, 68, 0.1); 50 | 51 | & > svg { 52 | color: #55bc8a; 53 | } 54 | } 55 | } 56 | 57 | .cardSelect { 58 | border-radius: 8px; 59 | background-color: #fff; 60 | box-shadow: 0 4px 15px 0 rgba(7, 42, 68, 0.1); 61 | 62 | :global(.h3) { 63 | display: inline-block; 64 | vertical-align: middle; 65 | font-weight: normal; 66 | line-height: 1.5; 67 | color: #242e42; 68 | } 69 | 70 | svg { 71 | vertical-align: middle; 72 | width: 20px; 73 | height: 20px; 74 | } 75 | 76 | .cardControl { 77 | position: relative; 78 | padding: 28px 20px; 79 | cursor: pointer; 80 | 81 | & > svg { 82 | margin-right: 20px; 83 | } 84 | 85 | .arrow { 86 | position: absolute; 87 | top: 50%; 88 | right: 20px; 89 | transform: translateY(-50%); 90 | 91 | &.open { 92 | transform: translateY(-50%) rotate(180deg); 93 | } 94 | } 95 | 96 | :global(.h3) { 97 | font-weight: 600; 98 | } 99 | } 100 | 101 | .cardOptions { 102 | padding: 0 8px 20px 8px; 103 | } 104 | 105 | .cardOption { 106 | padding: 12px; 107 | border-radius: 4px; 108 | cursor: pointer; 109 | 110 | & > svg { 111 | margin-right: 20px; 112 | } 113 | 114 | &:hover, 115 | &:active, 116 | &.select { 117 | background-color: #ecf0f2; 118 | } 119 | 120 | & + .cardOption { 121 | margin-top: 4px; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/components/Card/Install/select.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classnames from 'classnames' 3 | import { withTranslation } from 'react-i18next' 4 | 5 | import { ReactComponent as Arrow } from '../../../assets/arrow.svg' 6 | 7 | import styles from './index.module.scss' 8 | 9 | const Option = ({ icon, title, type, onClick, t }) => ( 10 |
11 | {icon} 12 |
{t(title)}
13 |
14 | ) 15 | 16 | class InstallCardSelect extends React.Component { 17 | state = { 18 | open: false, 19 | } 20 | 21 | toggleShowOptions = () => { 22 | this.setState(({ open }) => ({ 23 | open: !open, 24 | })) 25 | } 26 | 27 | handleOptionClick = e => { 28 | const { onChange } = this.props 29 | 30 | onChange(e) 31 | this.setState({ 32 | open: false, 33 | }) 34 | } 35 | 36 | render() { 37 | const { value, options, t } = this.props 38 | 39 | const selectOption = options.find(option => option.type === value) 40 | 41 | return ( 42 |
43 |
44 | {selectOption.icon} 45 |
{selectOption.title}
46 | 51 |
52 | {this.state.open && ( 53 |
54 | {options.map(option => ( 55 |
63 | )} 64 |
65 | ) 66 | } 67 | } 68 | 69 | export default withTranslation()(InstallCardSelect) 70 | -------------------------------------------------------------------------------- /src/components/Checkbox/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import classnames from 'classnames' 4 | 5 | import { ReactComponent as Check } from '../../assets/check.svg' 6 | 7 | import styles from './index.module.scss' 8 | 9 | class Checkbox extends React.Component { 10 | static propTypes = { 11 | className: PropTypes.string, 12 | onChange: PropTypes.func, 13 | } 14 | 15 | static defaultProps = { 16 | className: '', 17 | onChange() {}, 18 | } 19 | 20 | state = { 21 | checked: false, 22 | } 23 | 24 | handleClick = () => { 25 | const { onChange } = this.props 26 | 27 | this.setState( 28 | ({ checked }) => { 29 | onChange(checked) 30 | return { 31 | checked: !checked, 32 | } 33 | } 34 | ) 35 | } 36 | 37 | render() { 38 | const { className, children } = this.props 39 | const { checked } = this.state 40 | 41 | return ( 42 | 53 | ) 54 | } 55 | } 56 | 57 | export default Checkbox -------------------------------------------------------------------------------- /src/components/Checkbox/index.module.scss: -------------------------------------------------------------------------------- 1 | .checkbox { 2 | cursor: pointer; 3 | 4 | .input { 5 | display: inline-block; 6 | width: 18px; 7 | height: 18px; 8 | border-radius: 4px; 9 | background-color: #ffffff; 10 | border: solid 1px #d8dee5; 11 | vertical-align: middle; 12 | 13 | & > svg { 14 | margin-top: 2px; 15 | margin-left: 2px; 16 | } 17 | } 18 | 19 | &.checked { 20 | .input { 21 | background-color: #404e68; 22 | border: 1px solid #404e68; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/components/Download/CommunityModal/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../../styles/variables'; 2 | 3 | .body { 4 | padding: 65px 0; 5 | margin: 130px auto; 6 | background-color: #fff; 7 | border-radius: 4px; 8 | 9 | @media only screen and (max-width: $mobile-max-width) { 10 | margin: 0; 11 | padding: 0; 12 | padding: 56px 20px; 13 | } 14 | 15 | a { 16 | color: $primary; 17 | } 18 | } 19 | 20 | .leftContent { 21 | display: inline-block; 22 | width: 400px; 23 | height: 400px; 24 | padding: 92px 40px; 25 | border-right: 2px solid #d8dee5; 26 | vertical-align: top; 27 | text-align: center; 28 | 29 | @media only screen and (max-width: $mobile-max-width) { 30 | display: block; 31 | width: auto; 32 | height: auto; 33 | border: none; 34 | margin-bottom: 40px; 35 | padding: 0; 36 | } 37 | 38 | svg { 39 | width: 48px; 40 | height: 48px; 41 | margin-right: 28px; 42 | vertical-align: middle; 43 | } 44 | 45 | .text { 46 | display: inline-block; 47 | vertical-align: middle; 48 | text-align: left; 49 | } 50 | } 51 | 52 | .rightContent { 53 | display: inline-block; 54 | width: 560px; 55 | height: 400px; 56 | padding: 92px 58px; 57 | vertical-align: top; 58 | 59 | @media only screen and (max-width: $mobile-max-width) { 60 | display: block; 61 | width: auto; 62 | height: auto; 63 | padding: 0; 64 | } 65 | 66 | a { 67 | color: $primary; 68 | } 69 | } 70 | 71 | 72 | .checkbox { 73 | display: block; 74 | margin-top: 12px; 75 | 76 | & > span { 77 | line-height: 1.71; 78 | color: #8f94a1; 79 | margin-left: 17px; 80 | } 81 | } 82 | 83 | .input { 84 | position: relative; 85 | height: 48px; 86 | border-radius: 24px; 87 | background-color: #f9fbfd; 88 | border: solid 2px #d8dee5; 89 | 90 | & > input { 91 | width: 440px; 92 | padding: 11px 101px 11px 51px; 93 | border-radius: 24px; 94 | line-height: 1.71; 95 | color: #36435c; 96 | font-size: 14px; 97 | font-weight: 500; 98 | border: none; 99 | background-color: transparent; 100 | box-sizing: border-box; 101 | 102 | @media only screen and (max-width: $mobile-max-width) { 103 | width: auto; 104 | } 105 | 106 | &:focus { 107 | outline: none; 108 | } 109 | 110 | &::placeholder { 111 | color: #8f94a1; 112 | font-weight: 400; 113 | } 114 | } 115 | 116 | & > svg { 117 | position: absolute; 118 | width: 24px; 119 | height: 24px; 120 | top: 10px; 121 | left: 17px; 122 | } 123 | 124 | & > button { 125 | position: absolute; 126 | top: 4px; 127 | right: 5px; 128 | } 129 | } -------------------------------------------------------------------------------- /src/components/Footer/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .footer { 4 | width: 100%; 5 | padding: 118px 0; 6 | 7 | @media only screen and (max-width: $mobile-max-width) { 8 | padding: 80px 0 40px 0; 9 | } 10 | 11 | .wrapper { 12 | width: 1160px; 13 | margin: 0 auto; 14 | 15 | @media only screen and (max-width: $mobile-max-width) { 16 | width: 100%; 17 | padding: 0 20px; 18 | } 19 | } 20 | 21 | .beian, 22 | .icp { 23 | padding-top: 8px; 24 | font-weight: 600; 25 | font-family: $font-family-id; 26 | line-height: 1.43; 27 | letter-spacing: 1.1px; 28 | color: #242e42; 29 | text-align: center; 30 | 31 | img, span { 32 | display: inline-block; 33 | vertical-align: middle; 34 | } 35 | } 36 | 37 | .logo { 38 | img { 39 | height: 32px; 40 | } 41 | } 42 | 43 | .links { 44 | display: inline-block; 45 | margin-left: 80px; 46 | font-size: 16px; 47 | vertical-align: top; 48 | width: calc(100% - 440px); 49 | 50 | @media only screen and (max-width: $mobile-max-width) { 51 | width: auto; 52 | margin-left: 0px; 53 | margin-top: 63px; 54 | } 55 | 56 | & > ul { 57 | display: flex; 58 | flex-wrap: wrap; 59 | justify-content: space-between; 60 | list-style: none; 61 | 62 | @media only screen and (max-width: $mobile-max-width) { 63 | justify-content: start; 64 | } 65 | 66 | & > li { 67 | margin-right: 32px; 68 | margin-bottom: 20px; 69 | 70 | &:last-child { 71 | margin-right: 0; 72 | } 73 | 74 | & > :global(.h3) { 75 | font-weight: 600; 76 | line-height: 1.5; 77 | color: #171c34; 78 | margin-bottom: 10px; 79 | } 80 | 81 | & > a { 82 | display: block; 83 | line-height: 2; 84 | color: #919aa3; 85 | font-family: $font-family-id; 86 | 87 | &:hover { 88 | color: $primary; 89 | } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | .logos { 97 | margin-top: 40px; 98 | text-align: center; 99 | 100 | svg { 101 | width: 32px; 102 | height: 32px; 103 | color: #b6c2cd; 104 | cursor: pointer; 105 | transition: all 0.2s ease-in-out; 106 | margin-right: 8px; 107 | } 108 | 109 | .wechat { 110 | &:hover { 111 | color: #50b674; 112 | } 113 | } 114 | 115 | .youtube { 116 | &:hover { 117 | color: #dd1829; 118 | } 119 | } 120 | } 121 | 122 | .tooltip { 123 | font-size: 12px; 124 | font-weight: 500; 125 | line-height: 1.67; 126 | color: #919aa3; 127 | 128 | img { 129 | margin-top: 6px; 130 | } 131 | 132 | small { 133 | display: block; 134 | } 135 | } 136 | 137 | .description { 138 | margin-top: 24px; 139 | width: 360px; 140 | font-size: 16px; 141 | line-height: 2; 142 | color: #919aa3; 143 | } 144 | 145 | .subscribe { 146 | display: none; 147 | margin-top: 16px; 148 | } 149 | -------------------------------------------------------------------------------- /src/components/Form/Form.jsx: -------------------------------------------------------------------------------- 1 | import set from 'lodash/set' 2 | import get from 'lodash/get' 3 | import React from 'react' 4 | import PropTypes from 'prop-types' 5 | import Schema from 'async-validator' 6 | import classnames from 'classnames' 7 | 8 | import styles from './index.module.scss' 9 | 10 | export default class Form extends React.Component { 11 | static propTypes = { 12 | className: PropTypes.string, 13 | onSubmit: PropTypes.func, 14 | data: PropTypes.object, 15 | } 16 | 17 | static defaultProps = { 18 | className: '', 19 | } 20 | 21 | static childContextTypes = { 22 | formData: PropTypes.object, 23 | registerValidate: PropTypes.func, 24 | validateResults: PropTypes.array, 25 | } 26 | 27 | getChildContext() { 28 | return { 29 | formData: this._formData, 30 | registerValidate: this.registerValidate, 31 | validateResults: this.state.errors, 32 | } 33 | } 34 | 35 | constructor(props) { 36 | super(props) 37 | this._formData = props.data || {} 38 | this.descriptor = {} 39 | 40 | this.state = { errors: [] } 41 | } 42 | 43 | handleSubmit = e => { 44 | e.preventDefault() 45 | 46 | const schema = new Schema(this.descriptor) 47 | const data = Object.keys(this.descriptor).reduce( 48 | (prev, cur) => ({ 49 | ...prev, 50 | [cur]: get(this._formData, cur), 51 | }), 52 | {} 53 | ) 54 | 55 | schema.validate(data, { firstFields: true }, errors => { 56 | if (errors) { 57 | return this.setState({ errors }) 58 | } 59 | this.props.onSubmit(this._formData) 60 | }) 61 | } 62 | 63 | registerValidate = (name, rules) => { 64 | this.descriptor[name] = rules 65 | } 66 | 67 | getData() { 68 | return this._formData 69 | } 70 | 71 | setData(name, value) { 72 | set(this._formData, name, value) 73 | } 74 | 75 | componentWillReceiveProps(nextProps) { 76 | if (nextProps.data !== this.props.data) { 77 | this._formData = nextProps.data 78 | } 79 | } 80 | 81 | render() { 82 | const { className, children } = this.props 83 | 84 | const classNames = classnames(styles.form, className) 85 | 86 | return ( 87 |
92 | {children} 93 |
94 | ) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/components/Form/index.js: -------------------------------------------------------------------------------- 1 | import Form from './Form' 2 | import Item from './Item' 3 | 4 | Form.Item = Item 5 | 6 | export default Form 7 | -------------------------------------------------------------------------------- /src/components/Form/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .item { 4 | margin-bottom: 12px; 5 | 6 | &.errorItem { 7 | :global { 8 | .input, 9 | .select-control { 10 | box-shadow: 0 4px 8px 0 rgba(202, 38, 33, 0.2); 11 | border: solid 2px #ca2621 !important; 12 | &:focus, 13 | &:hover { 14 | border: solid 2px #ca2621 !important; 15 | } 16 | } 17 | } 18 | } 19 | 20 | .label { 21 | display: block; 22 | margin-bottom: 6px; 23 | line-height: 20px; 24 | color: #6b7b95; 25 | } 26 | 27 | .control { 28 | position: relative; 29 | } 30 | 31 | .desc, 32 | .error { 33 | margin-top: 6px; 34 | font-weight: $font-thin; 35 | line-height: 20px; 36 | color: #c1c9d1; 37 | } 38 | 39 | .error { 40 | color: #a80600; 41 | } 42 | 43 | + .item { 44 | margin-top: 12px; 45 | } 46 | 47 | :global { 48 | .field { 49 | margin-bottom: 0 !important; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/components/Headings/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import classnames from 'classnames' 4 | 5 | import { formatAnchor } from '../../utils/index' 6 | 7 | import styles from './index.module.scss' 8 | 9 | export default class Headings extends React.Component { 10 | static propTypes = { 11 | title: PropTypes.string, 12 | headings: PropTypes.arrayOf( 13 | PropTypes.shape({ 14 | value: PropTypes.string, 15 | depth: PropTypes.number, 16 | }) 17 | ).isRequired, 18 | onHeadClick: PropTypes.func, 19 | current: PropTypes.string, 20 | } 21 | 22 | constructor(props) { 23 | super(props) 24 | this.state = { 25 | current: '', 26 | } 27 | } 28 | 29 | componentWillReceiveProps(nextProps) { 30 | if (nextProps.current !== this.state.current) { 31 | this.setState({ 32 | current: nextProps.current, 33 | }) 34 | } 35 | } 36 | 37 | handleClick = e => { 38 | const anchor = e.target.dataset.anchor 39 | this.setState({ 40 | current: anchor, 41 | }) 42 | this.props.onHeadClick(anchor) 43 | } 44 | 45 | render() { 46 | const { title, headings } = this.props 47 | 48 | const current = decodeURIComponent(this.state.current) 49 | 50 | return ( 51 |
52 |
{title}
53 |
54 | {headings.map(({ value, depth }) => ( 55 |
63 | {value} 64 |
65 | ))} 66 |
67 |
68 | ) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/components/Headings/index.module.scss: -------------------------------------------------------------------------------- 1 | .title { 2 | font-size: 24px; 3 | font-weight: 500; 4 | line-height: 52px; 5 | color: #36435c; 6 | border-bottom: 1px solid #ccd3db; 7 | margin-bottom: 10px; 8 | } 9 | 10 | .head { 11 | position: relative; 12 | font-size: 16px; 13 | line-height: 2; 14 | margin-top: 4px; 15 | white-space: nowrap; 16 | overflow: hidden; 17 | text-overflow: ellipsis; 18 | cursor: pointer; 19 | color: #36435c; 20 | transition: all 0.2s ease-in-out; 21 | 22 | &.selected, 23 | &:hover { 24 | color: #55bc8a; 25 | } 26 | 27 | &:first-of-type { 28 | margin-top: 0; 29 | } 30 | } 31 | 32 | :global { 33 | .level-0 { 34 | font-weight: 500; 35 | } 36 | .level-1 { 37 | padding-left: 16px; 38 | } 39 | .level-2 { 40 | padding-left: 32px; 41 | } 42 | .level-3 { 43 | padding-left: 48px; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/components/Labels/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classnames from 'classnames' 3 | import { withTranslation } from 'react-i18next' 4 | 5 | import styles from './index.module.scss' 6 | 7 | const Item = ({ value, label, selected, onClick }) => { 8 | const handleClick = () => onClick(value) 9 | return ( 10 |
  • 14 | {label || value} 15 |
  • 16 | ) 17 | } 18 | 19 | class Labels extends React.Component { 20 | render() { 21 | const { t, options, value, onChange } = this.props 22 | 23 | return ( 24 |
    25 | 42 |
    43 | ) 44 | } 45 | } 46 | 47 | export default withTranslation()(Labels) 48 | -------------------------------------------------------------------------------- /src/components/Labels/index.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | margin-top: 30px; 3 | margin-bottom: 30px; 4 | 5 | & > ul { 6 | list-style: none; 7 | 8 | & > span { 9 | font-size: 14px; 10 | color: #171c34; 11 | margin-right: 10px; 12 | } 13 | 14 | & > li { 15 | display: inline-block; 16 | padding: 2px 10px; 17 | margin-bottom: 16px; 18 | font-size: 14px; 19 | text-align: center; 20 | color: #919aa3; 21 | border-radius: 13px; 22 | line-height: 20px; 23 | cursor: pointer; 24 | transition: all 0.2s ease-in-out; 25 | 26 | &:hover { 27 | background-color: #eff4f8; 28 | } 29 | 30 | &.selected { 31 | background-color: #eff4f8; 32 | } 33 | 34 | & + li { 35 | margin-left: 20px; 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/components/Language/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classnames from 'classnames' 3 | import { withTranslation } from 'react-i18next' 4 | 5 | import { ReactComponent as EarthIcon } from '../../assets/earth.svg' 6 | 7 | import { getLanguage } from '../../utils/index' 8 | 9 | import Select from '../Select' 10 | 11 | import styles from './index.module.scss' 12 | 13 | const LANGS = [ 14 | { label: '简体中文', value: 'zh-CN' }, 15 | { label: 'English', value: 'en' }, 16 | ] 17 | 18 | const Language = ({ 19 | className, 20 | pageContext: { locale, defaultLocale, originalPath }, 21 | }) => { 22 | const handleChange = value => { 23 | if (typeof window !== 'undefined') { 24 | window.location.href = 25 | value === defaultLocale ? originalPath : `/${value}${originalPath}` 26 | } 27 | } 28 | 29 | return ( 30 |
    31 | 32 | 23 | 26 |
    27 | ) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/components/Search/index.module.scss: -------------------------------------------------------------------------------- 1 | .search { 2 | position: relative; 3 | 4 | input { 5 | display: block; 6 | width: 100%; 7 | padding: 12px 48px 12px 18px; 8 | height: 48px; 9 | border-radius: 24px; 10 | border: solid 1px #ccd3db; 11 | background-color: #f5f8f9; 12 | box-sizing: border-box; 13 | outline: none; 14 | font-size: 16px; 15 | transition: all 0.2s ease-in-out; 16 | 17 | &::placeholder { 18 | color: #ccd3db; 19 | } 20 | 21 | &:hover { 22 | border-color: #303e5a; 23 | } 24 | 25 | &:focus { 26 | background-color: #fff; 27 | } 28 | } 29 | 30 | button { 31 | position: absolute; 32 | top: 50%; 33 | right: 4px; 34 | transform: translateY(-50%); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/components/Select/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classNames from 'classnames' 3 | import Tippy from '@tippy.js/react' 4 | 5 | import styles from './index.module.scss' 6 | 7 | export default class Select extends React.Component { 8 | handleChange = e => { 9 | const { onChange } = this.props 10 | onChange && onChange(e.currentTarget.dataset.value) 11 | } 12 | 13 | renderControl() { 14 | const { value, options, controlClassName } = this.props 15 | 16 | const item = options.find(option => option.value === value) || {} 17 | 18 | return ( 19 |
    20 | {item.label || value} 21 |
    22 |
    23 | ) 24 | } 25 | 26 | renderOptions() { 27 | const { optionsClassName, options } = this.props 28 | return ( 29 |
    33 |
      34 | {options.map(option => ( 35 |
    • 40 | {option.label} 41 |
    • 42 | ))} 43 |
    44 |
    45 | ) 46 | } 47 | render() { 48 | return ( 49 | 58 | {this.renderControl()} 59 | 60 | ) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/components/Select/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .control { 4 | display: inline-block; 5 | vertical-align: middle; 6 | line-height: 1.83; 7 | font-size: 12px; 8 | color: #242e42; 9 | cursor: pointer; 10 | outline: none; 11 | transition: all 0.2s ease-in-out; 12 | 13 | &:hover { 14 | color: $primary; 15 | } 16 | } 17 | 18 | .options { 19 | & > ul { 20 | padding: 12px 0; 21 | list-style: none; 22 | 23 | & > li { 24 | padding: 6px; 25 | min-width: 110px; 26 | color: #36435c; 27 | font-size: 12px; 28 | line-height: 20px; 29 | cursor: pointer; 30 | text-align: center; 31 | transition: all 0.2s ease-in-out; 32 | 33 | &:hover { 34 | color: $primary; 35 | } 36 | 37 | & + li { 38 | margin-top: 4px; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/components/Slider/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classnames from 'classnames' 3 | 4 | import styles from './index.module.scss' 5 | 6 | export default class Slider extends React.Component { 7 | state = { 8 | select: 0, 9 | } 10 | 11 | componentDidMount() { 12 | const { data } = this.props 13 | 14 | this.timer = setInterval(() => { 15 | this.setState(({ select }) => ({ 16 | select: select + 1 > data.length - 1 ? 0 : select + 1, 17 | })) 18 | }, 5000) 19 | } 20 | 21 | componentWillUnmount() { 22 | clearInterval(this.timer) 23 | } 24 | 25 | handleClick = e => { 26 | this.setState({ 27 | select: Number(e.target.dataset.index), 28 | }) 29 | } 30 | 31 | render() { 32 | const { className, data } = this.props 33 | const { select } = this.state 34 | 35 | const width = data.length * 650 36 | const translateX = select * -650 37 | 38 | return ( 39 |
    40 |
      41 | {data.map((item, index) => ( 42 |
    • 43 | 44 |
    • 45 | ))} 46 |
    47 |
    48 | {data.map((_, index) => ( 49 |
    57 | ))} 58 |
    59 |
    60 | ) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/components/Slider/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .slider { 4 | overflow: hidden; 5 | 6 | ul { 7 | list-style: none; 8 | height: 100%; 9 | transition: all $transition-speed ease; 10 | 11 | & > li { 12 | display: inline-block; 13 | width: 650px; 14 | height: 100%; 15 | 16 | & > img { 17 | width: 100%; 18 | height: 100%; 19 | } 20 | } 21 | } 22 | 23 | .dots { 24 | position: absolute; 25 | bottom: 3px; 26 | left: 50%; 27 | transform: translateX(-50%); 28 | 29 | .dot { 30 | display: inline-block; 31 | width: 11px; 32 | height: 11px; 33 | opacity: 0.3; 34 | background-color: #919aa3; 35 | border-radius: 50%; 36 | cursor: pointer; 37 | transition: all $transition-speed ease; 38 | 39 | &.select { 40 | opacity: 1; 41 | background-color: #171c34; 42 | } 43 | 44 | & + .dot { 45 | margin-left: 17.4px; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/components/Star/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { withTranslation } from 'react-i18next' 3 | import classNames from 'classnames' 4 | 5 | import { ReactComponent as CloseIcon } from '../../assets/close.svg' 6 | import { ReactComponent as GithubIcon } from '../../assets/icon-git.svg' 7 | import { ReactComponent as StarLeftIcon } from '../../assets/star-left.svg' 8 | import { ReactComponent as StarRightIcon } from '../../assets/star-right.svg' 9 | 10 | import styles from './index.module.scss' 11 | 12 | class Star extends React.Component { 13 | componentDidMount() { 14 | if (typeof window !== 'undefined') { 15 | const Swiped = require('../../utils/swipe') 16 | Swiped.init({ 17 | query: '.star', 18 | left: 1000, 19 | onOpen: () => { 20 | localStorage.setItem('kubesphere-star', 'hidden') 21 | }, 22 | }) 23 | } 24 | } 25 | 26 | handleClick = () => { 27 | window.open('https://github.com/kubesphere/kubesphere', '_blank') 28 | } 29 | 30 | handleClose = e => { 31 | e.stopPropagation() 32 | localStorage.setItem('kubesphere-star', 'hidden') 33 | this.forceUpdate() 34 | } 35 | 36 | render() { 37 | const { t } = this.props 38 | 39 | const showStar = 40 | typeof localStorage !== 'undefined' 41 | ? localStorage.getItem('kubesphere-star') !== 'hidden' 42 | : false 43 | 44 | if (!showStar) { 45 | return null 46 | } 47 | 48 | return ( 49 |
    53 |
    54 | 55 | 🎉🎉🎉 56 | {' '} 57 | {t('If you like KubeSphere')} 58 |
    59 |

    60 | {t('Please give us a GitHub Star as an encouragement.')} 61 |

    62 |
    63 | Github Star 64 |
    65 |
    66 | 67 |
    68 | 69 | 70 |
    71 | ) 72 | } 73 | } 74 | 75 | export default withTranslation()(Star) 76 | -------------------------------------------------------------------------------- /src/components/Star/index.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: fixed; 3 | bottom: 26px; 4 | right: 22px; 5 | width: 354px; 6 | height: 120px; 7 | padding: 20px; 8 | border-radius: 4px; 9 | box-shadow: 0 8px 16px 0 rgba(40, 19, 254, 0.32); 10 | background-image: linear-gradient(109deg, #3023ae, #716dd7); 11 | color: #fff; 12 | cursor: pointer; 13 | 14 | .title { 15 | font-size: 14px; 16 | font-weight: 600; 17 | line-height: 1.43; 18 | color: #ffffff; 19 | } 20 | 21 | .desc { 22 | font-size: 12px; 23 | line-height: 20px; 24 | color: #ffffff; 25 | } 26 | } 27 | 28 | .star { 29 | position: absolute; 30 | bottom: 18px; 31 | right: 20px; 32 | font-size: 16px; 33 | font-weight: 600; 34 | line-height: 1.5; 35 | color: #fff; 36 | z-index: 2; 37 | 38 | & > svg { 39 | vertical-align: sub; 40 | } 41 | } 42 | 43 | .close { 44 | position: absolute; 45 | top: 15px; 46 | right: 14px; 47 | cursor: pointer; 48 | z-index: 3; 49 | } 50 | 51 | .left { 52 | position: absolute; 53 | bottom: 0; 54 | left: 0; 55 | width: 120.4px; 56 | height: 86px; 57 | object-fit: contain; 58 | opacity: 0.9; 59 | } 60 | 61 | .right { 62 | position: absolute; 63 | top: 0; 64 | right: 0; 65 | width: 134.3px; 66 | height: 120px; 67 | object-fit: contain; 68 | mix-blend-mode: multiply; 69 | } -------------------------------------------------------------------------------- /src/components/Tags/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import classnames from 'classnames' 3 | import { withTranslation } from 'react-i18next' 4 | 5 | import styles from './index.module.scss' 6 | 7 | const Item = ({ value, label, selected, onClick }) => { 8 | const handleClick = () => onClick(value) 9 | return ( 10 |
  • 14 | {label || value} 15 |
  • 16 | ) 17 | } 18 | 19 | class Tags extends React.Component { 20 | render() { 21 | const { t, options, value, onChange } = this.props 22 | 23 | return ( 24 |
    25 |
      26 | 32 | {options.map(item => ( 33 | 39 | ))} 40 |
    41 |
    42 | ) 43 | } 44 | } 45 | 46 | export default withTranslation()(Tags) 47 | -------------------------------------------------------------------------------- /src/components/Tags/index.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding: 30px 34px 22px 34px; 3 | border-radius: 5px; 4 | box-shadow: 0 4px 16px 0 rgba(7, 42, 68, 0.1); 5 | background-color: #ffffff; 6 | 7 | & > ul { 8 | list-style: none; 9 | 10 | & > li { 11 | display: inline-block; 12 | min-width: 48px; 13 | padding: 8px 16px; 14 | margin-bottom: 8px; 15 | border-radius: 20px; 16 | transition: all 0.2s ease-in-out; 17 | cursor: pointer; 18 | font-size: 16px; 19 | font-weight: 500; 20 | line-height: 1.5; 21 | text-align: center; 22 | 23 | &:hover { 24 | background-color: #55bc8a; 25 | color: #fff; 26 | } 27 | 28 | &.selected { 29 | box-shadow: 0 8px 16px 0 rgba(101, 193, 148, 0.2), 30 | 0 0 50px 0 rgba(101, 193, 148, 0.1); 31 | background-color: #55bc8a; 32 | color: #fff; 33 | } 34 | 35 | & + li { 36 | margin-left: 12px; 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/components/VideoModal/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import Modal from '../Modal/index' 4 | 5 | import styles from './index.module.scss' 6 | 7 | import { ReactComponent as CloseIcon } from '../../assets/close.svg' 8 | 9 | class VideoModal extends React.Component { 10 | render() { 11 | const { data } = this.props 12 | 13 | if (!data || !data.link) { 14 | return null 15 | } 16 | 17 | return ( 18 | 24 |
    25 |
    26 | 27 |
    28 |
    36 |
    37 | ) 38 | } 39 | } 40 | 41 | export default VideoModal 42 | -------------------------------------------------------------------------------- /src/components/VideoModal/index.module.scss: -------------------------------------------------------------------------------- 1 | @import '../../styles/variables'; 2 | 3 | .videoWrapper { 4 | position: fixed; 5 | top: 50%; 6 | left: 50%; 7 | transform: translate(-50%, -50%); 8 | } 9 | 10 | .video { 11 | width: 50vw; 12 | min-width: 745px; 13 | min-height: 419px; 14 | background-color: #171c34; 15 | outline: none; 16 | 17 | @media only screen and (max-width: $mobile-max-width) { 18 | width: 100vw; 19 | min-width: unset; 20 | min-height: unset; 21 | } 22 | } 23 | 24 | .close { 25 | position: absolute; 26 | top: -28px; 27 | right: 8px; 28 | cursor: pointer; 29 | } 30 | -------------------------------------------------------------------------------- /src/components/withI18next/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { I18nextProvider, Translation } from 'react-i18next' 3 | import { I18nProvider } from 'gatsby-i18n' 4 | import setupI18next from '../../i18n' 5 | 6 | const lngFormat = locale => locale.replace(/-[a-z]{2}$/, e => e.toUpperCase()) 7 | 8 | const withI18next = (options = {}) => Comp => { 9 | class I18nHOC extends Component { 10 | constructor(props) { 11 | super(props) 12 | 13 | const { pageContext } = props 14 | this.state = { 15 | ...options, 16 | data: pageContext.data, 17 | } 18 | 19 | this.i18n = setupI18next(pageContext) 20 | this.activateLng() 21 | } 22 | 23 | activateLng = () => { 24 | const { pageContext } = this.props 25 | const { data } = this.state 26 | this.parseFromContext(data) 27 | this.i18n.changeLanguage(lngFormat(pageContext.locale)) 28 | } 29 | 30 | parseFromContext = data => { 31 | const { pageContext } = this.props 32 | if (data) { 33 | const lng = lngFormat(pageContext.locale) 34 | data.forEach(({ ns = 'common', content }) => { 35 | if (!this.i18n.hasResourceBundle(lng, ns)) { 36 | this.i18n.addResourceBundle(lng, ns, JSON.parse(content)) 37 | } 38 | }) 39 | } 40 | } 41 | 42 | componentDidUpdate(prevProps) { 43 | if (this.props.pageContext.locale !== prevProps.pageContext.locale) { 44 | this.activateLng() 45 | } 46 | } 47 | 48 | render() { 49 | const { ns } = this.state 50 | return ( 51 | 52 | 53 | 54 | {t => ( 55 | 60 | )} 61 | 62 | 63 | 64 | ) 65 | } 66 | } 67 | 68 | return I18nHOC 69 | } 70 | 71 | export default withI18next 72 | -------------------------------------------------------------------------------- /src/html.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | require('es6-shim') 5 | require('promise-polyfill') 6 | require('./utils/polifills') 7 | require('whatwg-fetch') 8 | 9 | export default function HTML(props) { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 20 | {props.headComponents} 21 | 22 | 23 | {props.preBodyComponents} 24 | 27 |
    32 | {props.postBodyComponents} 33 |