feat: adds initial website built from docusaurus

Change-Id: I0794ac26ba9c6d82c0df31adff66bd229ca5e9f8
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
This commit is contained in:
Florent Benoit 2022-04-04 17:01:17 +02:00 committed by Florent BENOIT
parent acfd93abbf
commit 4c988ef7a5
25 changed files with 8881 additions and 2 deletions

53
.github/workflows/pr-check-website.yaml vendored Normal file
View file

@ -0,0 +1,53 @@
#
# Copyright (C) 2022 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
name: pr-check-website
on:
pull_request:
paths:
- 'package.json'
- 'yarn.lock'
- 'website/**'
jobs:
website-build:
name: build website
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Execute yarn
run: yarn --frozen-lockfile
- name: Run website
run: yarn website:build

73
.github/workflows/website-next.yaml vendored Normal file
View file

@ -0,0 +1,73 @@
#
# Copyright (C) 2022 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
name: next build
on:
workflow_dispatch:
push:
branches:
- main
paths:
- 'package.json'
- 'yarn.lock'
- 'website/**'
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
jobs:
deploy:
name: Build and deploy website
runs-on: ubuntu-20.04
timeout-minutes: 60
steps:
- uses: actions/checkout@v3
with:
ref: ${{ needs.tag.outputs.githubTag}}
- uses: actions/setup-node@v2
with:
node-version: 16
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: yarn
run: |
yarn --frozen-lockfile --network-timeout 180000
- name: Run Build
timeout-minutes: 20
run: yarn website:build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# Build output to publish to the `gh-pages` branch:
publish_dir: ./build
# The following lines assign commit authorship to the official
# GH-Actions bot for deploys to `gh-pages` branch:
# https://github.com/actions/checkout/issues/13#issuecomment-724415212
# The GH actions bot is used by default if you didn't specify the two fields.
# You can swap them out with your own user credentials.
user_name: github-actions[bot]
user_email: 41898282+github-actions[bot]@users.noreply.github.com

View file

@ -11,7 +11,8 @@
"workspaces": {
"packages": [
"packages/*",
"extensions/*"
"extensions/*",
"website"
]
},
"scripts": {
@ -43,7 +44,8 @@
"typecheck:main": "tsc --noEmit -p packages/main/tsconfig.json",
"typecheck:preload": "tsc --noEmit -p packages/preload/tsconfig.json",
"typecheck:renderer": "npm run build:preload:types",
"typecheck": "npm run typecheck:main && npm run typecheck:preload && npm run typecheck:renderer"
"typecheck": "npm run typecheck:main && npm run typecheck:preload && npm run typecheck:renderer",
"website:build": "cd website && yarn run docusaurus build"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^21.0.1",

20
website/.gitignore vendored Normal file
View file

@ -0,0 +1,20 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

33
website/README.md Normal file
View file

@ -0,0 +1,33 @@
# Website
### Local Development of the website / documentation
```
$ yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
### Build
```
$ yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
### Deployment
Using SSH:
```
$ USE_SSH=true yarn deploy
```
Not using SSH:
```
$ GIT_USER=<Your GitHub username> yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

3
website/babel.config.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

5
website/blog/authors.yml Normal file
View file

@ -0,0 +1,5 @@
benoitf:
name: Florent Benoit
title: Maintainer of Container Desktop
url: https://github.com/benoitf
image_url: https://github.com/benoitf.png

24
website/docs/intro.md Normal file
View file

@ -0,0 +1,24 @@
---
sidebar_position: 1
---
# Introduction
Let's discover **Container Desktop in less than 5 minutes**.
## Getting Started
Get started by **[Downloading](/downloads) the product** for your Operating System.
### What you'll need
- Podman 4.x
- Check there is a podman machine running
### Check podman CLI is working
Run the development server:
```sh
$ podman run redhat/ubi8-micro echo hello world
```

View file

@ -0,0 +1,36 @@
---
sidebar_position: 2
---
# Troubleshooting
Here, find some answers to the question : I have downloaded Container Desktop but I am unable to see any of my image or container
## Podman
### system requirements
The tool connects to Podman using the socket on the host on macOS and on a named pipe on Windows. This is available only on podman 4.0.2+
So, please check your version and update.
On Windows, the named pipe is `//./pipe/docker_engine` when Docker Desktop is not installed. It will be solved by https://github.com/containers/podman/issues/13502 / https://github.com/containers/podman/pull/13655. During that time, you may start Docker Desktop so the named pipe is the one expected.
### Check connection
Check at least a podman machine is running on Windows & macOS:
```bash
podman machine list
```
And check a connection can be made with the CLI
```sh
$ podman run redhat/ubi8-micro echo hello world
```
## Code Ready Containers
- Check that podman preset is defined. (`crc config get preset`)
- Check that `crc` binary is available in the user PATH (`/usr/local/bin/crc`)
- Check that `crc setup --check-only` is running without errors.

View file

@ -0,0 +1,115 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
const lightCodeTheme = require('prism-react-renderer/themes/github');
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
const title = 'Container Desktop';
/** @type {import('@docusaurus/types').Config} */
const config = {
title,
url: 'https://your-docusaurus-test-site.com',
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.ico',
organizationName: 'containers',
projectName: 'desktop',
deploymentBranch: 'gh-pages',
trailingSlash: false,
plugins: [
async () => {
return {
name: 'docusaurus-tailwindcss',
configurePostCss(postcssOptions) {
postcssOptions.plugins.push(require('tailwindcss'));
postcssOptions.plugins.push(require('autoprefixer'));
return postcssOptions;
},
};
},
],
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: require.resolve('./sidebars.js'),
editUrl: 'https://github.com/container/desktop/tree/main/website',
},
// disable for now the blog posts
blog: false,
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
}),
],
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
colorMode: {
defaultMode: 'dark',
disableSwitch: false,
respectPrefersColorScheme: false,
},
navbar: {
title,
logo: {
alt: 'My Site Logo',
src: 'img/logo.svg',
},
items: [
{
type: 'doc',
docId: 'intro',
position: 'left',
label: 'Documentation',
},
{to: '/downloads', label: 'Downloads', position: 'left'},
/*{to: '/blog', label: 'Blog', position: 'left'},*/
{
href: 'https://github.com/containers/desktop',
className: 'header-github-link',
position: 'right',
},
],
},
footer: {
links: [
{
title: 'Documentation',
items: [
{
label: 'Introduction',
to: '/docs/intro',
},
],
},
{
title: 'Links',
items: [
/*{
label: 'Blog',
to: '/blog',
},*/
{
label: 'GitHub',
href: 'https://github.com/containers/desktop',
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} ${title}<br/>Apache License 2.0 License`,
},
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
},
}),
};
module.exports = config;

46
website/package.json Normal file
View file

@ -0,0 +1,46 @@
{
"name": "docs",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "2.0.0-beta.18",
"@docusaurus/preset-classic": "2.0.0-beta.18",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.1.1",
"prism-react-renderer": "^1.3.1",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.0.0-beta.18",
"@tsconfig/docusaurus": "^1.0.5",
"autoprefixer": "^10.4.4",
"postcss": "^8.4.12",
"tailwindcss": "^3.0.23",
"typescript": "^4.6.3"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

31
website/sidebars.js Normal file
View file

@ -0,0 +1,31 @@
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
// @ts-check
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
// By default, Docusaurus generates a sidebar from the docs folder structure
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
// But you can create a sidebar manually
/*
tutorialSidebar: [
{
type: 'category',
label: 'Tutorial',
items: ['hello'],
},
],
*/
};
module.exports = sidebars;

View file

@ -0,0 +1,27 @@
import React from 'react';
import { useColorMode } from '@docusaurus/theme-common';
import { useEffect } from 'react';
const updadeTailwindDarkTheme = () => {
const { colorMode } = useColorMode();
useEffect(() => {
const html = document.documentElement;
if (colorMode === 'dark') {
html.classList.add('dark');
} else {
html.classList.remove('dark');
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
return () => {};
}, [colorMode]);
};
export const ThemeProvider = () => {
updadeTailwindDarkTheme();
return <div></div>;
};
export default function TailWindThemeSelector(): JSX.Element {
updadeTailwindDarkTheme();
return <div></div>;
}

View file

@ -0,0 +1,92 @@
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Apply default style for markdown
*/
h1 {
@apply text-4xl font-bold;
}
h2 {
@apply text-2xl font-bold;
}
h3 {
@apply text-xl font-bold;
}
/*
Apply style on documentation
*/
.docs-doc-page div.main-wrapper a {
@apply text-violet-600;
}
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #6d28d9;
--ifm-color-primary-dark: #6223c5;
--ifm-color-primary-darker: #5c21ba;
--ifm-color-primary-darkest: #4c1b99;
--ifm-color-primary-light: #7c3edd;
--ifm-color-primary-lighter: #8349df;
--ifm-color-primary-lightest: #996ae5;
--ifm-code-font-size: 95%;
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-color-primary: #6d28d9;
--ifm-color-primary-dark: #6223c5;
--ifm-color-primary-darker: #5c21ba;
--ifm-color-primary-darkest: #4c1b99;
--ifm-color-primary-light: #7c3edd;
--ifm-color-primary-lighter: #8349df;
--ifm-color-primary-lightest: #996ae5;
}
.docusaurus-highlight-code-line {
background-color: rgba(0, 0, 0, 0.1);
display: block;
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
}
[data-theme='dark'] .docusaurus-highlight-code-line {
background-color: rgba(0, 0, 0, 0.3);
}
svg.iconExternalLink_node_modules-\@docusaurus-theme-classic-lib-next-theme-IconExternalLink-styles-module {
display: inline;
}
/* Add icon for github instead of label */
.header-github-link:hover {
opacity: 0.6;
}
.header-github-link::before {
content: '';
width: 24px;
height: 24px;
display: flex;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}
[data-theme='dark'] .header-github-link::before {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}
svg.darkToggleIcon_node_modules-\@docusaurus-theme-classic-lib-next-theme-ColorModeToggle-styles-module {
width: 16px;
color: #343e50;
}
svg.lightToggleIcon_node_modules-\@docusaurus-theme-classic-lib-next-theme-ColorModeToggle-styles-module {
width: 16px;
color: #343e50;
}

View file

@ -0,0 +1,19 @@
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import React from 'react';
import TailWindThemeSelector from '@site/src/components/TailWindThemeSelector';
import { MacOSDownloads } from '@site/src/pages/downloads/macOS';
import { WindowsDownloads } from '@site/src/pages/downloads/windows';
import { LinuxDownloads } from '@site/src/pages/downloads/linux';
export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout title={siteConfig.title} description="Downloads">
<TailWindThemeSelector />
<MacOSDownloads />
<WindowsDownloads />
<LinuxDownloads />
</Layout>
);
}

View file

@ -0,0 +1,84 @@
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import type { SetStateAction } from 'react';
import React, { useEffect, useState } from 'react';
import TailWindThemeSelector from '@site/src/components/TailWindThemeSelector';
import Link from '@docusaurus/Link';
let grabbed = false;
async function grabfilenameforMac(
setDownloadData: React.Dispatch<SetStateAction<{ version: string; binary: string }>>,
): Promise<void> {
if (grabbed) {
return;
}
const result = await fetch('https://api.github.com/repos/containers/desktop/releases/latest');
const jsonContent = await result.json();
const assets = jsonContent.assets;
const linuxAssets = assets.filter(asset => (asset.name as string).endsWith('.tar.gz'));
if (linuxAssets.length !== 1) {
throw new Error('Unable to grab .tar.gz');
}
const linuxAsset = linuxAssets[0];
const data = {
version: jsonContent.name,
binary: linuxAsset.browser_download_url,
};
setDownloadData(data);
grabbed = true;
}
export function LinuxDownloads(): JSX.Element {
const [downloadData, setDownloadData] = useState({
version: '',
binary: '',
setup: '',
});
useEffect(() => {
grabfilenameforMac(setDownloadData);
});
return (
<section className="text-gray-400 bg-gray-900 min-h-full">
<div className="container px-5 py-24 mx-auto center">
<h1 className="text-3xl font-medium title-font text-white mb-12 text-center">
{downloadData.version}: Downloads for Linux
</h1>
<div className="w-2/3 flex mx-auto justify-center center">
<div className="p-4 ">
<div className="h-full bg-gray-800 bg-opacity-40 p-8 rounded">
<div className="w-full flex flex-col justify-center center">
<p className="mb-6 text-5xl">Tgz archive of binary</p>
<Link
className="no-underline hover:no-underline inline-flex text-white hover:text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
to={downloadData.binary}>
<svg
className="w-5 h-5 mr-2 mt-1"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20">
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
Download .tgz
</Link>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout title={siteConfig.title} description="Downloads for macOS">
<TailWindThemeSelector />
<main className="h-screen"></main>
<LinuxDownloads />
</Layout>
);
}

View file

@ -0,0 +1,112 @@
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import type { SetStateAction } from 'react';
import React, { useEffect, useState } from 'react';
import TailWindThemeSelector from '@site/src/components/TailWindThemeSelector';
import Link from '@docusaurus/Link';
let grabbed = false;
async function grabfilenameforMac(
setDownloadData: React.Dispatch<SetStateAction<{ version: string; x64: string; arm64: string }>>,
): Promise<void> {
if (grabbed) {
return;
}
const result = await fetch('https://api.github.com/repos/containers/desktop/releases/latest');
const jsonContent = await result.json();
const assets = jsonContent.assets;
const armMacDmg = assets.filter(asset => (asset.name as string).endsWith('-arm64.dmg'));
if (armMacDmg.length !== 1) {
throw new Error('Unable to grab arm64 dmg');
}
const armLink = armMacDmg[0];
const intelMacDmgResults = assets.filter(
asset => (asset.name as string).endsWith('.dmg') && asset.name !== armLink.name,
);
const intelMacDmg = intelMacDmgResults[0];
const data = {
version: jsonContent.name,
x64: intelMacDmg.browser_download_url,
arm64: armLink.browser_download_url,
};
setDownloadData(data);
grabbed = true;
}
export function MacOSDownloads(): JSX.Element {
const [downloadData, setDownloadData] = useState({
version: '',
x64: '',
arm64: '',
});
useEffect(() => {
grabfilenameforMac(setDownloadData);
});
return (
<section className="text-gray-400 bg-gray-900 min-h-full">
<div className="container px-5 py-24 mx-auto center">
<h1 className="text-3xl font-medium title-font text-white mb-12 text-center">
{downloadData.version}: Downloads for macOS
</h1>
<div className="w-2/3 flex mx-auto justify-center center">
<div className="grid grid-cols-2">
<div className="p-4 ">
<div className="h-full bg-gray-800 bg-opacity-40 p-8 rounded">
<div className="w-full flex flex-col justify-center center">
<p className="mb-6 text-5xl">Mac Intel</p>
<Link
className="no-underline hover:no-underline inline-flex text-white hover:text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
to={downloadData.x64}>
<svg
className="w-5 h-5 mr-2 mt-1"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20">
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
Download x64 dmg
</Link>
</div>
</div>
</div>
<div className="p-4 ">
<div className="h-full bg-gray-800 bg-opacity-40 p-8 rounded">
<div className="w-full flex flex-col mx-auto justify-center center">
<p className=" mb-6 text-5xl">Mac Silicon/M1</p>
<Link
className="no-underline hover:no-underline inline-flex text-white hover:text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
to={downloadData.arm64}>
<svg
className="w-5 h-5 mr-2 mt-1"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20">
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
Download arm64 dmg
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout title={siteConfig.title} description="Downloads for macOS">
<TailWindThemeSelector />
<main className="h-screen">
<MacOSDownloads />
</main>
</Layout>
);
}

View file

@ -0,0 +1,113 @@
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import type { SetStateAction } from 'react';
import React, { useEffect, useState } from 'react';
import TailWindThemeSelector from '@site/src/components/TailWindThemeSelector';
import Link from '@docusaurus/Link';
let grabbed = false;
async function grabfilenameforMac(
setDownloadData: React.Dispatch<SetStateAction<{ version: string; binary: string; setup: string }>>,
): Promise<void> {
if (grabbed) {
return;
}
const result = await fetch('https://api.github.com/repos/containers/desktop/releases/latest');
const jsonContent = await result.json();
const assets = jsonContent.assets;
const windowsSetupAssets = assets.filter(asset => (asset.name as string).endsWith('-setup.exe'));
if (windowsSetupAssets.length !== 1) {
throw new Error('Unable to grab setup.exe');
}
const windowsSetupAsset = windowsSetupAssets[0];
const binaryOnlyWindowsAssets = assets.filter(
asset => (asset.name as string).endsWith('.exe') && asset.name !== windowsSetupAsset.name,
);
const binaryAsset = binaryOnlyWindowsAssets[0];
const data = {
version: jsonContent.name,
binary: binaryAsset.browser_download_url,
setup: windowsSetupAsset.browser_download_url,
};
setDownloadData(data);
grabbed = true;
}
export function WindowsDownloads(): JSX.Element {
const [downloadData, setDownloadData] = useState({
version: '',
binary: '',
setup: '',
});
useEffect(() => {
grabfilenameforMac(setDownloadData);
});
return (
<section className="text-gray-400 bg-gray-900 min-h-full">
<div className="container px-5 py-24 mx-auto center">
<h1 className="text-3xl font-medium title-font text-white mb-12 text-center">
{downloadData.version}: Downloads for Windows
</h1>
<div className="w-2/3 flex mx-auto justify-center center">
<div className="grid grid-cols-2">
<div className="p-4 ">
<div className="h-full bg-gray-800 bg-opacity-40 p-8 rounded">
<div className="w-full flex flex-col justify-center center">
<p className="mb-6 text-5xl">Binary only</p>
<Link
className="no-underline hover:no-underline inline-flex text-white hover:text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
to={downloadData.binary}>
<svg
className="w-5 h-5 mr-2 mt-1"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20">
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
Download exe
</Link>
</div>
</div>
</div>
<div className="p-4 ">
<div className="h-full bg-gray-800 bg-opacity-40 p-8 rounded">
<div className="w-full flex flex-col mx-auto justify-center center">
<p className=" mb-6 text-5xl">Installer</p>
<Link
className="no-underline hover:no-underline inline-flex text-white hover:text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
to={downloadData.setup}>
<svg
className="w-5 h-5 mr-2 mt-1"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20">
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
Download setup.exe
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout title={siteConfig.title} description="Downloads for macOS">
<TailWindThemeSelector />
<main className="h-screen">
<WindowsDownloads />
</main>
</Layout>
);
}

106
website/src/pages/index.tsx Normal file
View file

@ -0,0 +1,106 @@
import React from 'react';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import TailWindThemeSelector from '@site/src/components/TailWindThemeSelector';
import BrowserOnly from '@docusaurus/BrowserOnly';
function DownloadClientLinks() {
let operatingSystem = '';
const userAgent = navigator.userAgent;
if (userAgent.indexOf('Windows') != -1) {
operatingSystem = 'Windows';
} else if (userAgent.indexOf('Mac') != -1) {
operatingSystem = 'macOS';
} else if (userAgent.indexOf('Linux') != -1) {
operatingSystem = 'Linux';
}
let mainButton;
let otherButton;
if (operatingSystem !== '') {
mainButton = (
<Link
className="no-underline hover:no-underline inline-flex text-white hover:text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
to={'/downloads/' + operatingSystem}>
Downloads for {operatingSystem}
</Link>
);
otherButton = (
<Link
className="no-underline hover:no-underline ml-4 inline-flex text-gray-700 bg-gray-100 border-0 py-2 px-6 focus:outline-none hover:bg-gray-200 rounded text-lg"
to="/downloads">
Other downloads
</Link>
);
} else {
mainButton = (
<Link
className="no-underline hover:no-underline inline-flex text-white hover:text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
to="/downloads">
Download Page
</Link>
);
}
return (
<div className="flex justify-center">
{mainButton}
{otherButton}
</div>
);
}
function DownloadGenericLinks() {
return (
<div className="flex justify-center">
<Link
className="no-underline hover:no-underline inline-flex text-white hover:text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
to="/downloads">
Download Page
</Link>
</div>
);
}
function Hero() {
const { siteConfig } = useDocusaurusContext();
return (
<section className="text-gray-600 dark:text-gray-400 body-font">
<div className="container mx-auto flex px-5 py-24 items-center justify-center flex-col">
<div className="text-center lg:w-2/3 w-full">
<h1 className="title-font sm:text-4xl text-3xl lg:text-6xl mb-4 font-medium text-gray-900 dark:text-white">
{siteConfig.title}
</h1>
<p className="mb-3 py-3 leading-relaxed">
This tool allows to browse, manage lifecycle of containers, inspect containers, images from different
container engines. It includes a tray icon support. It can connect to multiple engines at the same time and
provides an unified interface.
</p>
<div className="flex justify-center"></div>
</div>
<div className="flex justify-center">
{/* With client mode, provides the link to the client browser */}
<BrowserOnly fallback={<DownloadGenericLinks></DownloadGenericLinks>}>
{() => {
return <DownloadClientLinks />;
}}
</BrowserOnly>
</div>
<img className="w-2/3" src="https://raw.githubusercontent.com/containers/desktop/media/screenshot.png" />
</div>
</section>
);
}
export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout title={siteConfig.title} description="Manage containers">
<TailWindThemeSelector />
<Hero />
</Layout>
);
}

0
website/static/.nojekyll Normal file
View file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="645" height="642.17" fill="none" version="1.1" viewBox="0 0 645 642.17" xmlns="http://www.w3.org/2000/svg">
<path d="m327.87 17.267c-3.379-1.689-7.355-1.689-10.734 0l-290.5 145.25c-4.065 2.033-6.633 6.188-6.633 10.733v287.67c0 4.545 2.568 8.7 6.633 10.733l290.5 145.25c3.379 1.689 7.355 1.689 10.734 0l290.5-145.25c4.065-2.033 6.633-6.188 6.633-10.733v-287.67c0-4.545-2.568-8.7-6.633-10.733z" clip-rule="evenodd" fill="url(#paint1_linear_1_2)" fill-rule="evenodd" style="fill:url(#paint1_linear_1_2)"/>
<g transform="translate(-189 -194.42)" filter="url(#filter0_d_1_2)" shape-rendering="crispEdges">
<path d="m506.13 211.68c3.379-1.689 7.355-1.689 10.734 0l290.5 145.25c4.065 2.033 6.633 6.188 6.633 10.733v287.67c0 4.545-2.568 8.7-6.633 10.733l-290.5 145.25c-3.379 1.689-7.355 1.689-10.734 0l-290.5-145.25c-4.065-2.033-6.633-6.188-6.633-10.733v-287.67c0-4.545 2.568-8.7 6.633-10.733z" fill="url(#paint2_linear_1_2)" fill-opacity=".2" style="fill:url(#paint2_linear_1_2)"/>
<path d="m506.13 211.68c3.379-1.689 7.355-1.689 10.734 0l290.5 145.25c4.065 2.033 6.633 6.188 6.633 10.733v287.67c0 4.545-2.568 8.7-6.633 10.733l-290.5 145.25c-3.379 1.689-7.355 1.689-10.734 0l-290.5-145.25c-4.065-2.033-6.633-6.188-6.633-10.733v-287.67c0-4.545 2.568-8.7 6.633-10.733z" stroke="url(#paint3_linear_1_2)" stroke-linecap="square" stroke-linejoin="round" stroke-width="32" style="stroke:url(#paint3_linear_1_2)"/>
</g>
<g transform="translate(-189 -194.42)" filter="url(#filter1_i_1_2)">
<path d="m512.5 227 285.5 144v282.5l-287.5 142-285.5-142v-282.5z" fill="url(#paint4_linear_1_2)" fill-opacity=".2" style="fill:url(#paint4_linear_1_2)"/>
</g>
<path d="m322 33.584-286 142.5 286 145.5 287-145.5z" fill="url(#paint5_linear_1_2)" fill-opacity=".3" style="fill:url(#paint5_linear_1_2)"/>
<path d="m107.91 390.82h428.23" stroke="url(#paint6_linear_1_2)" style="stroke:url(#paint6_linear_1_2)"/>
<g transform="translate(-189 -194.42)" filter="url(#filter2_dd_1_2)">
<path d="m297.09 421.02c0-7.732 6.268-14 14-14h400.58c7.732 0 14 6.268 14 14v186.29c0 7.732-6.268 14-14 14h-400.58c-7.732 0-14-6.268-14-14zm35.714 26.715c0-2.762 2.239-5 5-5h25.715c2.762 0 5 2.238 5 5v97.145c0 2.761-2.238 5-5 5h-25.715c-2.761 0-5-2.239-5-5zm76.43-5c-2.761 0-5 2.238-5 5v97.145c0 2.761 2.239 5 5 5h25.715c2.761 0 5-2.239 5-5v-97.145c0-2.762-2.239-5-5-5zm66.43 5c0-2.762 2.239-5 5-5h25.715c2.761 0 5 2.238 5 5v97.145c0 2.761-2.239 5-5 5h-25.715c-2.761 0-5-2.239-5-5zm76.601-5.161c-2.762 0-5 2.238-5 5v97.145c0 2.761 2.238 5 5 5h25.715c2.761 0 5-2.239 5-5v-97.145c0-2.762-2.239-5-5-5z" clip-rule="evenodd" fill="url(#paint7_linear_1_2)" fill-rule="evenodd" style="fill:url(#paint7_linear_1_2)"/>
</g>
<path d="m108.09 391.18h428.58v23.714c0 6.628-5.372 12-12 12h-404.58c-6.628 0-12-5.372-12-12z" fill="#472ea8"/>
<defs>
<filter id="filter0_d_1_2" x="189" y="194.42" width="645" height="642.17" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_1_2"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_1_2" result="shape"/>
</filter>
<filter id="filter1_i_1_2" x="225" y="227" width="573" height="568.5" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset/>
<feGaussianBlur stdDeviation="8"/>
<feComposite in2="hardAlpha" k2="-1" k3="1" operator="arithmetic"/>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
<feBlend in2="shape" result="effect1_innerShadow_1_2"/>
</filter>
<filter id="filter2_dd_1_2" x="286.09" y="392.02" width="450.58" height="237.29" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="-4"/>
<feGaussianBlur stdDeviation="5.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.14 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_1_2"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend in2="effect1_dropShadow_1_2" result="effect2_dropShadow_1_2"/>
<feBlend in="SourceGraphic" in2="effect2_dropShadow_1_2" result="shape"/>
</filter>
<linearGradient id="paint1_linear_1_2" x1="511.5" x2="511.5" y1="210.42" y2="812.58" gradientTransform="translate(-189 -194.42)" gradientUnits="userSpaceOnUse">
<stop stop-color="#2E114A" offset="0"/>
<stop stop-color="#07051B" offset=".9434"/>
</linearGradient>
<linearGradient id="paint2_linear_1_2" x1="271.39" x2="271.39" y1="814" y2="209" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".73" offset="0"/>
<stop stop-color="#F1F1F1" stop-opacity=".94" offset="1"/>
</linearGradient>
<linearGradient id="paint3_linear_1_2" x1="172.13" x2="814" y1="251.54" y2="814" gradientUnits="userSpaceOnUse">
<stop stop-color="#6AD2FA" offset="0"/>
<stop stop-color="#7669FA" offset=".49479"/>
<stop stop-color="#8850E4" offset=".74479"/>
<stop stop-color="#CE0EBB" offset="1"/>
</linearGradient>
<linearGradient id="paint4_linear_1_2" x1="284.3" x2="284.3" y1="792" y2="227" gradientUnits="userSpaceOnUse">
<stop stop-opacity=".73" offset="0"/>
<stop stop-color="#F1F1F1" stop-opacity=".94" offset="1"/>
</linearGradient>
<linearGradient id="paint5_linear_1_2" x1="513.91" x2="513.91" y1="230" y2="395.12" gradientTransform="translate(-189 -194.42)" gradientUnits="userSpaceOnUse">
<stop stop-color="#621EA6" stop-opacity=".89" offset="0"/>
<stop stop-color="#CCCAD1" stop-opacity="0" offset="1"/>
</linearGradient>
<linearGradient id="paint6_linear_1_2" x1="512.46" x2="512.46" y1="585.23" y2="586.23" gradientTransform="translate(-189 -194.42)" gradientUnits="userSpaceOnUse">
<stop stop-opacity="0" offset="0"/>
<stop stop-opacity=".37" offset=".22917"/>
<stop stop-opacity=".046875" offset=".64583"/>
<stop stop-opacity="0" offset="1"/>
</linearGradient>
<linearGradient id="paint7_linear_1_2" x1="511.38" x2="511.38" y1="407.02" y2="621.31" gradientUnits="userSpaceOnUse">
<stop stop-color="#E9E9E9" offset="0"/>
<stop stop-color="#A59ADE" offset="1"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 7 KiB

View file

@ -0,0 +1,8 @@
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
darkMode: 'class',
theme: {
extend: {},
},
plugins: [],
};

7
website/tsconfig.json Normal file
View file

@ -0,0 +1,7 @@
{
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@tsconfig/docusaurus/tsconfig.json",
"compilerOptions": {
"baseUrl": "."
}
}

7783
website/yarn.lock Normal file

File diff suppressed because it is too large Load diff