Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sample website #9

Merged
merged 19 commits into from
Dec 18, 2023
Merged
37 changes: 37 additions & 0 deletions .github/workflows/web-deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
on:
push:
paths:
- "web/**"
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
name: Deploy web to Cloudflare Pages
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Build Cache
uses: actions/cache@v3
with:
path: |
~/.npm
${{ github.workspace }}/web/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
- name: Build
env:
NEXT_TELEMETRY_DISABLED: 1
run: cd web && yarn install && yarn build
- name: Publish
uses: cloudflare/pages-action@1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: invenhost-web
directory: web/out
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ Nothing intresting for the public is happening here, go to [the docs site](https
doc-site Settings and layouting for docs site
docs Meta docs for the project
plugins Source for already open-sourced plugins
web Source for the main website
```
36 changes: 36 additions & 0 deletions web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
14 changes: 14 additions & 0 deletions web/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const withNextra = require('nextra')({
theme: 'nextra-theme-blog',
themeConfig: './theme.config.js',
})

/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
unoptimized: true,
},
}

module.exports = withNextra(nextConfig)
23 changes: 23 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"private": true,
"scripts": {
"dev": "next",
"build": "node ./scripts/gen-rss.js && next build",
"start": "next start"
},
"dependencies": {
"gray-matter": "^4.0.3",
"next": "latest",
"nextra": "^2.0.0-beta.5",
"nextra-theme-blog": "^2.0.0-beta.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rss": "^1.2.2"
},
"devDependencies": {
"@types/node": "^18.0.0",
"@types/react": "^18.0.14",
"@types/react-dom": "^18.0.5",
"typescript": "^4.7.4"
}
}
27 changes: 27 additions & 0 deletions web/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'nextra-theme-blog/style.css'
import type { AppProps } from 'next/app'
import Head from 'next/head'
import '../styles/main.css'

export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Head>
<link
rel="alternate"
type="application/rss+xml"
title="RSS"
href="/feed.xml"
/>
<link
rel="preload"
href="/fonts/Inter-roman.latin.var.woff2"
as="font"
type="font/woff2"
crossOrigin="anonymous"
/>
</Head>
<Component {...pageProps} />
</>
)
}
28 changes: 28 additions & 0 deletions web/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
const meta = {
title: 'InvenHost',
description: 'Extend InvenTree for your use case.',
}

return (
<Html lang="en">
<Head>
<meta name="robots" content="follow, index" />
<meta name="description" content={meta.description} />
<meta property="og:site_name" content={meta.title} />
<meta property="og:description" content={meta.description} />
<meta property="og:title" content={meta.title} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@matthiasjmair" />
<meta name="twitter:title" content={meta.title} />
<meta name="twitter:description" content={meta.description} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
27 changes: 27 additions & 0 deletions web/pages/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
type: page
title: About InvenHost
date: 2023-12-18
---

# InvenHost

InvenHost aims to enhance and extend the functionality of core InvenTree to support commercial and enterprise use cases.

Read more about the project and goals in the docs [here](https://doc.invenhost.com/).

## Current initiatives

### Approvals
The beta is out and available for testing -> check it out [here](https://doc.invenhost.com/inventree_approval/main/)

### Infrastructure

Creating a new infrastructure for publishing and distributing InvenHost plugins - both closed and open source - requires dedicated infrastructure.

Read more about this endeavor [here](https://doc.invenhost.com/invenhost/main/services).

### Website

I have learned the hard lesson that a fancy website and marketing seems to be a requirement for a successful open source project.
A nicer looking website for InvenHost is in the works, this is a placeholder for now.
61 changes: 61 additions & 0 deletions web/pages/posts/1_softlaunch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
title: Soft Launching InvenHost
date: 2023-12-18
description: Staring a new project is a catch-22. You have to start somewhere.
author: Matthias Mair
tag: project
---

# Soft Launching InvenHost

Staring a new project is a catch-22. You have to start somewhere but you know that the current state is not what you aspire it to be. Getting feedback is a bit hard if you do not show anything.

Therefore, I am soft launching the InvenHost project. Feel free to reach out to [email protected] if you have any questions or feedback.

## What is InvenHost?

InvenHosts goal is to provide **enterprise plugins** for InvenTree ([InvenTree](https://inventree.org/) is an open-source inventory management system with a focus on electronics manufacturing).

This entails **developing plugins** and **providing** the **infrastructure** to develop, test, document, license, distribute and maintain open and closed plugins.

## Who is InvenHost for?

The main audience are companies / commercial users of InvenTree that need functions that make sense for a company but not for hobby users of InvenTree. This includes things like:
- Approval workflows
- Integration with Marketplaces like [Shopify](https://github.com/matmair/inventree-shopify), Ebay, Amazon, Tindie, Etsy or self-hosted solutions like WooCommerce
- Integration with suppliers/vendors for metadata, stock levels and ordering

## Why InvenHost?

InvenTree is a great project and I have been contributing to it for a while now. However, it is a MIT licensed community project and as such it is hard to get any feedback from users.

The project does not even know how many people use it. This makes it hard to justify spending time on features that are not used by the core team, their employers and friends. We tried surveys, enabeling discussions, creating social media accounts, making a website, etc. but nothing really worked.

InvenHost is a way to experiment with other models of licensing (less permisive), distribution (required telemetry) and monetization (subscriptions, support, consulting, custom development).

My goal is not to make money but have the freedom to experiment without exposing the core project to any risk.
The only time you seem to get feedback is when users tell you they do not like something.

## Inven ... Host?

I already owned the domain + GitHub org and it has a good standing with the big email providers, so I chose to keep using it.
The host refers both to the hosting of instances for friends and family (which I have been doing for a while under this domain) as well as the hosting of plugins and tools.

Instance hosting is a friends-only thing and nothing I offer to the public.

## My History with InvenTree

I have been active with the InvenTree project since Mar 2021 when I became aware of them through [Stephen Hawes](https://stephenhawes.com/)’ discord server (he runs a [fantastic company](https://www.opulo.io/) building OSS PnP machines).
At the time of writing, I have 2,234 commits in the main branch of the repository, which places me second after Oliver, the maintainer.
Some of the features I have implemented/contributed towards are:
- proper plugin support
- security things like 2FA, SSO, email verification, magic link login
- PUI - the new frontend written in React [inventree.org blog](https://inventree.org/blog/2023/08/28/react)

Outside of that I wrote the current website and plugin repo, helped with docs, the brother integration, social media handles and various funding opportunities.

I am currently taking it slower with the project to focus on InvenHost and getting the first 3 plugins out.

## Disclaimer

InvenHost is not affiliated with InvenTree other than I work on both sometimes.
7 changes: 7 additions & 0 deletions web/pages/posts/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
type: posts
title: Blog
date: 2023-12-18
---

# Posts
13 changes: 13 additions & 0 deletions web/pages/tags/[tag].mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
type: tag
title: Tagged Posts
---

import { useRouter } from 'next/router'

export const TagName = () => {
const { tag } = useRouter().query
return tag || null
}

# Posts Tagged with “<TagName/>”
Binary file added web/public/fonts/Inter-italic.latin.var.woff2
Binary file not shown.
Binary file added web/public/fonts/Inter-roman.latin.var.woff2
Binary file not shown.
38 changes: 38 additions & 0 deletions web/scripts/gen-rss.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const { promises: fs } = require('fs')
const path = require('path')
const RSS = require('rss')
const matter = require('gray-matter')

async function generate() {
const feed = new RSS({
title: 'Your Name',
site_url: 'https://invenhost.com',
feed_url: 'https://invenhost.com/feed.xml',
})

const posts = await fs.readdir(path.join(__dirname, '..', 'pages', 'posts'))

await Promise.all(
posts.map(async (name) => {
if (name.startsWith('index.')) return

const content = await fs.readFile(
path.join(__dirname, '..', 'pages', 'posts', name)
)
const frontmatter = matter(content)

feed.item({
title: frontmatter.data.title,
url: '/posts/' + name.replace(/\.mdx?/, ''),
date: frontmatter.data.date,
description: frontmatter.data.description,
categories: frontmatter.data.tag.split(', '),
author: frontmatter.data.author,
})
})
)

await fs.writeFile('./public/feed.xml', feed.xml({ indent: true }))
}

generate()
65 changes: 65 additions & 0 deletions web/styles/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
@font-face {
font-family: 'Inter var';
font-style: normal;
font-weight: 100 900;
font-display: block;
src: url(/fonts/Inter-roman.latin.var.woff2) format('woff2');
}
@font-face {
font-family: 'Inter var';
font-style: italic;
font-weight: 100 900;
font-display: block;
src: url(/fonts/Inter-italic.latin.var.woff2) format('woff2');
font-named-instance: 'Italic';
}

body {
font-family: 'Inter var', system-ui, -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
-webkit-font-smoothing: subpixel-antialiased;
font-feature-settings: 'case' 1, 'cpsp' 1, 'dlig' 1, 'cv01' 1, 'cv02',
'cv03' 1, 'cv04' 1;
font-variation-settings: 'wght' 450;
font-variant: common-ligatures contextual;
letter-spacing: -0.02em;
}
b,
strong,
h3,
h4,
h5,
h6 {
font-variation-settings: 'wght' 650;
}
h1 {
font-variation-settings: 'wght' 850;
}
h2 {
font-variation-settings: 'wght' 750;
}

@media screen and (min-device-pixel-ratio: 1.5),
screen and (min-resolution: 1.5dppx) {
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
}

details summary {
cursor: pointer;
}

img.next-image {
margin: 0;
}

.prose a {
color: #0074de;
}

.nav-line .nav-link {
color: #69778c;
}
Loading