diff --git a/.github/workflows/publish-dashboard.yaml b/.github/workflows/publish-dashboard.yaml index fdf31a12..0dda06bb 100644 --- a/.github/workflows/publish-dashboard.yaml +++ b/.github/workflows/publish-dashboard.yaml @@ -5,9 +5,12 @@ on: paths: - .github/workflows/publish-dashboard.yaml - packages/dashboard/** + - package.json + - pnpm-lock.yaml env: PUBLIC_APEX_DOMAIN: ${{ vars.PUBLIC_APEX_DOMAIN }} + MAIN_BRANCH: v0/main jobs: publish: @@ -47,13 +50,13 @@ jobs: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} gitHubToken: ${{ secrets.GITHUB_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - projectName: pockethost-dashboard - directory: ./dist/dashboard + projectName: pockethost-lander + directory: ./packages/dashboard/build branch: ${{ github.head_ref || github.ref_name }} wranglerVersion: '3' - name: Discord feature branch notification - if: github.ref_name != 'v0/main' + if: github.ref_name != env.MAIN_BRANCH env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} uses: Ilshidur/action-discord@master @@ -61,9 +64,9 @@ jobs: args: '**DASHBOARD PREVIEW** ${{ steps.deployment.outputs.url }} was generated by ${{ github.actor }} in [${{ env.GIT_COMMIT_SHORT_SHA }}](https://github.com/${{ github.repository}}/commit/${{ github.sha }}) on [${{ github.repository}}#${{ github.ref_name }}](https://github.com/${{ github.repository}}/tree/${{ github.ref_name }}) with memo `${{ env.GIT_COMMIT_MESSAGE_SUBJECT }}`' - name: Discord live branch notification - if: github.ref_name == 'v0/main' + if: github.ref_name == env.MAIN_BRANCH env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} uses: Ilshidur/action-discord@master with: - args: '**DASHBOARD LIVE** https://app.pockethost.io ([permalink](${{ steps.deployment.outputs.url }})) was updated by ${{ github.actor }} in [${{ env.GIT_COMMIT_SHORT_SHA }}](https://github.com/${{ github.repository}}/commit/${{ github.sha }}) on [${{ github.repository}}#${{ github.ref_name }}](https://github.com/${{ github.repository}}/tree/${{ github.ref_name }}): `${{ env.GIT_COMMIT_MESSAGE_SUBJECT }}`' + args: '**DASHBOARD LIVE** https://pockethost.io ([permalink](${{ steps.deployment.outputs.url }})) was updated by ${{ github.actor }} in [${{ env.GIT_COMMIT_SHORT_SHA }}](https://github.com/${{ github.repository}}/commit/${{ github.sha }}) on [${{ github.repository}}#${{ github.ref_name }}](https://github.com/${{ github.repository}}/tree/${{ github.ref_name }}): `${{ env.GIT_COMMIT_MESSAGE_SUBJECT }}`' diff --git a/.github/workflows/publish-lander.yaml b/.github/workflows/publish-lander.yaml deleted file mode 100644 index e8589a66..00000000 --- a/.github/workflows/publish-lander.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: Publish Lander to Cloudflare Pages - -on: - push: - paths: - - .github/workflows/publish-lander.yaml - - packages/lander/** - -env: - PUBLIC_APEX_DOMAIN: ${{ vars.PUBLIC_APEX_DOMAIN }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - contents: read - deployments: write - name: Publish to Cloudflare Pages - steps: - - name: Checkout - uses: actions/checkout@v4.1.1 - - - name: pnpm - uses: pnpm/action-setup@v3.0.0 - with: - version: 9.9.0 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: 20.x - cache: 'pnpm' - - - name: Prepare build - run: | - pnpm i - cd packages/lander - pnpm build - - - name: Expose git commit data - uses: rlespinasse/git-commit-data-action@v1.5.0 - - - name: Publish to Cloudflare Pages - uses: cloudflare/pages-action@v1.5.0 - id: deployment - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - gitHubToken: ${{ secrets.GITHUB_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - projectName: pockethost-lander - directory: ./dist/lander - branch: ${{ github.head_ref || github.ref_name }} - wranglerVersion: '3' - - - name: Discord feature branch notification - if: github.ref_name != 'v0/main' - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - uses: Ilshidur/action-discord@master - with: - args: '**LANDER PREVIEW** ${{ steps.deployment.outputs.url }} was generated by ${{ github.actor }} in [${{ env.GIT_COMMIT_SHORT_SHA }}](https://github.com/${{ github.repository}}/commit/${{ github.sha }}) on [${{ github.repository}}#${{ github.ref_name }}](https://github.com/${{ github.repository}}/tree/${{ github.ref_name }}) with memo `${{ env.GIT_COMMIT_MESSAGE_SUBJECT }}`' - - - name: Discord live branch notification - if: github.ref_name == 'v0/main' - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - uses: Ilshidur/action-discord@master - with: - args: '**LANDER LIVE** https://pockethost.io ([permalink](${{ steps.deployment.outputs.url }})) was updated by ${{ github.actor }} in [${{ env.GIT_COMMIT_SHORT_SHA }}](https://github.com/${{ github.repository}}/commit/${{ github.sha }}) on [${{ github.repository}}#${{ github.ref_name }}](https://github.com/${{ github.repository}}/tree/${{ github.ref_name }}): `${{ env.GIT_COMMIT_MESSAGE_SUBJECT }}`' diff --git a/.github/workflows/publish-superadmin.yaml b/.github/workflows/publish-superadmin.yaml deleted file mode 100644 index e1841757..00000000 --- a/.github/workflows/publish-superadmin.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: Publish Superadmin to Cloudflare Pages - -on: - push: - paths: - - .github/workflows/publish-superadmin.yaml - - packages/superadmin/** - -env: - PUBLIC_APEX_DOMAIN: ${{ vars.PUBLIC_APEX_DOMAIN }} - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - contents: read - deployments: write - name: Publish to Cloudflare Pages - steps: - - name: Checkout - uses: actions/checkout@v4.1.1 - - - name: pnpm - uses: pnpm/action-setup@v3.0.0 - with: - version: 9.9.0 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: 20.x - cache: 'pnpm' - - - name: Prepare build - run: | - pnpm i - cd packages/superadmin - pnpm build - - - name: Expose git commit data - uses: rlespinasse/git-commit-data-action@v1.5.0 - - - name: Publish to Cloudflare Pages - uses: cloudflare/pages-action@v1.5.0 - id: deployment - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - gitHubToken: ${{ secrets.GITHUB_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - projectName: pockethost-superadmin - directory: ./dist/superadmin - branch: ${{ github.head_ref || github.ref_name }} - wranglerVersion: '3' - - - name: Discord feature branch notification - if: github.ref_name != 'v0/main' - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - uses: Ilshidur/action-discord@master - with: - args: '**SUPERADMIN PREVIEW** ${{ steps.deployment.outputs.url }} was generated by ${{ github.actor }} in [${{ env.GIT_COMMIT_SHORT_SHA }}](https://github.com/${{ github.repository}}/commit/${{ github.sha }}) on [${{ github.repository}}#${{ github.ref_name }}](https://github.com/${{ github.repository}}/tree/${{ github.ref_name }}) with memo `${{ env.GIT_COMMIT_MESSAGE_SUBJECT }}`' - - - name: Discord live branch notification - if: github.ref_name == 'v0/main' - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - uses: Ilshidur/action-discord@master - with: - args: '**SUPERADMIN LIVE** https://superadmin.pockethost.io ([permalink](${{ steps.deployment.outputs.url }})) was updated by ${{ github.actor }} in [${{ env.GIT_COMMIT_SHORT_SHA }}](https://github.com/${{ github.repository}}/commit/${{ github.sha }}) on [${{ github.repository}}#${{ github.ref_name }}](https://github.com/${{ github.repository}}/tree/${{ github.ref_name }}): `${{ env.GIT_COMMIT_MESSAGE_SUBJECT }}`' diff --git a/.rizzdown/.gitignore b/.rizzdown/.gitignore deleted file mode 100644 index 2d357cff..00000000 --- a/.rizzdown/.gitignore +++ /dev/null @@ -1 +0,0 @@ -openai-secret-key \ No newline at end of file diff --git a/.rizzdown/blog/audience.md b/.rizzdown/blog/audience.md deleted file mode 100644 index 9c3893b3..00000000 --- a/.rizzdown/blog/audience.md +++ /dev/null @@ -1 +0,0 @@ -The primary audience is software developers, specifically web and nodejs programmers. Lots of interest in cloud services and avoiding writing backends. Many of our users use SvelteKit, React, Vercel, Firebase, and Supabase. My audience does NOT like puffery or flowery language. They like technical inspiration and spending time with tools that will enhance their ability to touch the lives of others with their creations. diff --git a/.rizzdown/blog/author.md b/.rizzdown/blog/author.md deleted file mode 100644 index bb692da6..00000000 --- a/.rizzdown/blog/author.md +++ /dev/null @@ -1 +0,0 @@ -I run a site called pockethost.io. I am a Typescript and nodejs programmer. I'm pretty experienced, but I focus mostly on backend stuff and I know I'm not the best at frontend ui/ux. I have a passion for open source projects and for helping people make their own creations reach people. I have a lot of experience and am seasoned, yet very patient with newcomers. I like to teach. I like to encourage people. I love to learn. I don't trust horses, and I like jiu jitsu. diff --git a/.rizzdown/blog/style.md b/.rizzdown/blog/style.md deleted file mode 100644 index 7c107b12..00000000 --- a/.rizzdown/blog/style.md +++ /dev/null @@ -1,3 +0,0 @@ -This is a blog for web and mobile app developers. They are interested in BaaS, as this is our central product. They tend to be well-versed in Typescript and JavaScript, but only have 2-5 years of experience. They like making little apps and inventions to serve specific verticals that they find interesting. They like open source, and they like independence and sovereignty. The blog should have a factual tone with no embellishments. You can include up to one pop culture reference per article, but it should not be a central point. - -Use third person language. Do not refer to 'we' or use colloquialisms. Avoid phrases like "squashed pesky bugs" and playful language. Be direct, to the point, and do not attempt to introduce personality into the prose. diff --git a/.rizzdown/blog/subject.md b/.rizzdown/blog/subject.md deleted file mode 100644 index 4ed89fa9..00000000 --- a/.rizzdown/blog/subject.md +++ /dev/null @@ -1,46 +0,0 @@ -pockethost.io is a hosted version of the open source project named PocketHost (licensed under the MIT open source license) which is based on the PocketBase open source project. - -PocketBase is essentially a REST API and admin UI over a SQLite database. PocketBase is written in golang. It provides user management, logging, REST security, as well as an advanced SQLite schema editor and data editor. - -PocketHost is a multitenant 'one click' hosting and deployment service for PocketBase. Users can create accounts, create projects with uniquely named subdomains off the pockethost.io apex domain. This way, they don't have to do any setup to get PocketBase running. Our motto is "Up and running in 30 seconds with zero config". As you might imagine, preparing PocketBase for production use takes a lot of Linux administration skills. SSL, DNS, Domain management, CNAMES, Docker containers, restarting on errors, SMTP, etc. PocketHost does all this for the user. We have a Discord channel to provide support and collect feature ideas. - -PocketHost has been received very positively by the community and has over 400 stars. It is used by many hobbyist developers as well as live applications. - -### Overview - -PocketHost hosts your [PocketBase](https://pocketbase.io) projects, so you don't have to. Create a project like you would in Firebase and Supabase and let PocketHost do the rest. - -PocketHost is a cloud hosting platform for PocketBase. You can use it to instantly provision a PocketBase backend for your latest project. Features include: - -- Create unlimited PocketBase projects, each with a custom subdomain -- Each instance runs on a subdomain of `pockethost.io` -- Access your PocketBase instance using the PocketBase JavaScript SDK as easily as `new PocketBase('https://my-project.pockethost.io')` -- Run your instance in an ultra-beefy shared environment - -### Focus on your app - -Get a live PocketBase instance in 10 seconds with no backend setup: - -1. Create an account at pockethost.io -2. Provision your first PocketBase instance -3. Connect from anywhere - -```ts -import PocketBase from 'pocketbase' - -const client = new PocketBase(`https://harvest.pockethost.io`) -``` - -### Batteries Included - -Here's all the Linux/devops stuff that PocketHost does for you: - -- Email and DKIM+SPF and more -- DNS jargon: MX, TXT, CNAME -- SSL cert provisioning and management -- Storage -- Volume mounts -- Cloud computing or VPS deployment -- CDN and static asset hosting -- Amazon AWS -- Lots more - scaling, firewalls, DDoS defense, user security, log rotation, patches, updates, build tools, CPU architectures, multitenancy, on and on diff --git a/.rizzdown/docs/audience.md b/.rizzdown/docs/audience.md deleted file mode 100644 index 9c3893b3..00000000 --- a/.rizzdown/docs/audience.md +++ /dev/null @@ -1 +0,0 @@ -The primary audience is software developers, specifically web and nodejs programmers. Lots of interest in cloud services and avoiding writing backends. Many of our users use SvelteKit, React, Vercel, Firebase, and Supabase. My audience does NOT like puffery or flowery language. They like technical inspiration and spending time with tools that will enhance their ability to touch the lives of others with their creations. diff --git a/.rizzdown/docs/author.md b/.rizzdown/docs/author.md deleted file mode 100644 index bb692da6..00000000 --- a/.rizzdown/docs/author.md +++ /dev/null @@ -1 +0,0 @@ -I run a site called pockethost.io. I am a Typescript and nodejs programmer. I'm pretty experienced, but I focus mostly on backend stuff and I know I'm not the best at frontend ui/ux. I have a passion for open source projects and for helping people make their own creations reach people. I have a lot of experience and am seasoned, yet very patient with newcomers. I like to teach. I like to encourage people. I love to learn. I don't trust horses, and I like jiu jitsu. diff --git a/.rizzdown/docs/style.md b/.rizzdown/docs/style.md deleted file mode 100644 index b9bab807..00000000 --- a/.rizzdown/docs/style.md +++ /dev/null @@ -1 +0,0 @@ -This prose is technical documentation. It should have an edgy, modern voice that is fun-loving but accurate. diff --git a/.rizzdown/docs/subject.md b/.rizzdown/docs/subject.md deleted file mode 100644 index 4ed89fa9..00000000 --- a/.rizzdown/docs/subject.md +++ /dev/null @@ -1,46 +0,0 @@ -pockethost.io is a hosted version of the open source project named PocketHost (licensed under the MIT open source license) which is based on the PocketBase open source project. - -PocketBase is essentially a REST API and admin UI over a SQLite database. PocketBase is written in golang. It provides user management, logging, REST security, as well as an advanced SQLite schema editor and data editor. - -PocketHost is a multitenant 'one click' hosting and deployment service for PocketBase. Users can create accounts, create projects with uniquely named subdomains off the pockethost.io apex domain. This way, they don't have to do any setup to get PocketBase running. Our motto is "Up and running in 30 seconds with zero config". As you might imagine, preparing PocketBase for production use takes a lot of Linux administration skills. SSL, DNS, Domain management, CNAMES, Docker containers, restarting on errors, SMTP, etc. PocketHost does all this for the user. We have a Discord channel to provide support and collect feature ideas. - -PocketHost has been received very positively by the community and has over 400 stars. It is used by many hobbyist developers as well as live applications. - -### Overview - -PocketHost hosts your [PocketBase](https://pocketbase.io) projects, so you don't have to. Create a project like you would in Firebase and Supabase and let PocketHost do the rest. - -PocketHost is a cloud hosting platform for PocketBase. You can use it to instantly provision a PocketBase backend for your latest project. Features include: - -- Create unlimited PocketBase projects, each with a custom subdomain -- Each instance runs on a subdomain of `pockethost.io` -- Access your PocketBase instance using the PocketBase JavaScript SDK as easily as `new PocketBase('https://my-project.pockethost.io')` -- Run your instance in an ultra-beefy shared environment - -### Focus on your app - -Get a live PocketBase instance in 10 seconds with no backend setup: - -1. Create an account at pockethost.io -2. Provision your first PocketBase instance -3. Connect from anywhere - -```ts -import PocketBase from 'pocketbase' - -const client = new PocketBase(`https://harvest.pockethost.io`) -``` - -### Batteries Included - -Here's all the Linux/devops stuff that PocketHost does for you: - -- Email and DKIM+SPF and more -- DNS jargon: MX, TXT, CNAME -- SSL cert provisioning and management -- Storage -- Volume mounts -- Cloud computing or VPS deployment -- CDN and static asset hosting -- Amazon AWS -- Lots more - scaling, firewalls, DDoS defense, user security, log rotation, patches, updates, build tools, CPU architectures, multitenancy, on and on diff --git a/.rizzdown/release/audience.md b/.rizzdown/release/audience.md deleted file mode 100644 index 9c3893b3..00000000 --- a/.rizzdown/release/audience.md +++ /dev/null @@ -1 +0,0 @@ -The primary audience is software developers, specifically web and nodejs programmers. Lots of interest in cloud services and avoiding writing backends. Many of our users use SvelteKit, React, Vercel, Firebase, and Supabase. My audience does NOT like puffery or flowery language. They like technical inspiration and spending time with tools that will enhance their ability to touch the lives of others with their creations. diff --git a/.rizzdown/release/author.md b/.rizzdown/release/author.md deleted file mode 100644 index bb692da6..00000000 --- a/.rizzdown/release/author.md +++ /dev/null @@ -1 +0,0 @@ -I run a site called pockethost.io. I am a Typescript and nodejs programmer. I'm pretty experienced, but I focus mostly on backend stuff and I know I'm not the best at frontend ui/ux. I have a passion for open source projects and for helping people make their own creations reach people. I have a lot of experience and am seasoned, yet very patient with newcomers. I like to teach. I like to encourage people. I love to learn. I don't trust horses, and I like jiu jitsu. diff --git a/.rizzdown/release/style.md b/.rizzdown/release/style.md deleted file mode 100644 index a1f203c6..00000000 --- a/.rizzdown/release/style.md +++ /dev/null @@ -1 +0,0 @@ -This is a blog post announcing a new version of our open source project, PocketHost. It should have an intelligently humorous opening paragraph followed by a dry, accurate, meticulous description of changes and updates, and why they are important. You can casually mathematically or logically clever notions with hidden meanings. diff --git a/.rizzdown/release/subject.md b/.rizzdown/release/subject.md deleted file mode 100644 index 4ed89fa9..00000000 --- a/.rizzdown/release/subject.md +++ /dev/null @@ -1,46 +0,0 @@ -pockethost.io is a hosted version of the open source project named PocketHost (licensed under the MIT open source license) which is based on the PocketBase open source project. - -PocketBase is essentially a REST API and admin UI over a SQLite database. PocketBase is written in golang. It provides user management, logging, REST security, as well as an advanced SQLite schema editor and data editor. - -PocketHost is a multitenant 'one click' hosting and deployment service for PocketBase. Users can create accounts, create projects with uniquely named subdomains off the pockethost.io apex domain. This way, they don't have to do any setup to get PocketBase running. Our motto is "Up and running in 30 seconds with zero config". As you might imagine, preparing PocketBase for production use takes a lot of Linux administration skills. SSL, DNS, Domain management, CNAMES, Docker containers, restarting on errors, SMTP, etc. PocketHost does all this for the user. We have a Discord channel to provide support and collect feature ideas. - -PocketHost has been received very positively by the community and has over 400 stars. It is used by many hobbyist developers as well as live applications. - -### Overview - -PocketHost hosts your [PocketBase](https://pocketbase.io) projects, so you don't have to. Create a project like you would in Firebase and Supabase and let PocketHost do the rest. - -PocketHost is a cloud hosting platform for PocketBase. You can use it to instantly provision a PocketBase backend for your latest project. Features include: - -- Create unlimited PocketBase projects, each with a custom subdomain -- Each instance runs on a subdomain of `pockethost.io` -- Access your PocketBase instance using the PocketBase JavaScript SDK as easily as `new PocketBase('https://my-project.pockethost.io')` -- Run your instance in an ultra-beefy shared environment - -### Focus on your app - -Get a live PocketBase instance in 10 seconds with no backend setup: - -1. Create an account at pockethost.io -2. Provision your first PocketBase instance -3. Connect from anywhere - -```ts -import PocketBase from 'pocketbase' - -const client = new PocketBase(`https://harvest.pockethost.io`) -``` - -### Batteries Included - -Here's all the Linux/devops stuff that PocketHost does for you: - -- Email and DKIM+SPF and more -- DNS jargon: MX, TXT, CNAME -- SSL cert provisioning and management -- Storage -- Volume mounts -- Cloud computing or VPS deployment -- CDN and static asset hosting -- Amazon AWS -- Lots more - scaling, firewalls, DDoS defense, user security, log rotation, patches, updates, build tools, CPU architectures, multitenancy, on and on diff --git a/assets/Flounder's Annual Badge.png b/assets/Flounder's Annual Badge.png new file mode 100644 index 00000000..9d8ff415 Binary files /dev/null and b/assets/Flounder's Annual Badge.png differ diff --git a/docs/introduction.md b/docs/introduction.md index 09646756..6dde5174 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -6,10 +6,10 @@ PocketHost hosts your [PocketBase](https://pocketbase.io) projects, so you don't PocketHost is a cloud hosting platform for PocketBase. You can use it to instantly provision a PocketBase backend for your latest project. Features include: -- Create unlimited PocketBase projects, each with a custom subdomain +- Create PocketBase projects, each with a custom subdomain - Each instance runs on a subdomain of `pockethost.io` -- Access your PocketBase instance using the PocketBase JavaScript SDK as easily as -`new PocketBase('https://my-project.pockethost.io')` +- Access your PocketBase instance using the PocketBase JavaScript SDK as easily as + `new PocketBase('https://my-project.pockethost.io')` - Run your instance in an ultra-beefy shared environment. ## 🎯 Focus on your app @@ -26,7 +26,7 @@ import PocketBase from 'pocketbase' const client = new PocketBase(`https://harvest.pockethost.io`) ``` -## 🔋Batteries Included +## 🔋Batteries Included Here's all the Linux/DevOps stuff that PocketHost does for you: @@ -38,4 +38,4 @@ Here's all the Linux/DevOps stuff that PocketHost does for you: - Cloud computing or VPS deployment - CDN and static asset hosting - Amazon AWS -- Lots more - scaling, firewalls, DDoS protection, user security, log retention, patches, updates, build tools, CPU architectures, multitenancy, and the list goes on \ No newline at end of file +- Lots more - scaling, firewalls, DDoS protection, user security, log retention, patches, updates, build tools, CPU architectures, multitenancy, and the list goes on diff --git a/package.json b/package.json index b73d401c..1f5ec897 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,9 @@ "lint": "prettier -c \"./**/*.{ts,js,cjs,svelte,json}\"", "lint:fix": "prettier -w \"./**/*.{ts,js,cjs,svelte,json}\"", "dev:cli": "cd packages/pockethost && pnpm dev", - "dev:lander": "cd packages/lander && pnpm start", "dev:dashboard": "cd packages/dashboard && pnpm dev", "dev:superadmin": "cd packages/superadmin && pnpm dev", "prod:cli": "cd packages/pockethost && pnpm start", - "plop": "plop --no-progress", "nofile": "cat /proc/sys/fs/file-nr", "mail": "tsx ./packages/pockethost/src/cli/sendmail.ts" }, @@ -65,13 +63,11 @@ "ncp": "^2.0.0", "nodemon": "^3.0.3", "ora": "^7.0.1", - "plop": "^4.0.0", "postinstall-postinstall": "^2.1.0", "prettier": "^3.0.3", "prettier-plugin-jsdoc": "^1.3.0", "prettier-plugin-organize-imports": "^3.2.3", "prettier-plugin-svelte": "^3.0.3", - "rizzdown": "^0.0.7", "svelte": "^4.2.2", "tslib": "^2.6.2", "tsx": "^3.14.0", @@ -80,7 +76,8 @@ }, "pnpm": { "patchedDependencies": { - "eventsource@2.0.2": "patches/eventsource@2.0.2.patch" + "eventsource@2.0.2": "patches/eventsource@2.0.2.patch", + "@sveltejs/enhanced-img": "patches/@sveltejs__enhanced-img.patch" } } } diff --git a/packages/dashboard/.force-build b/packages/dashboard/.force-build deleted file mode 100644 index 73131b36..00000000 --- a/packages/dashboard/.force-build +++ /dev/null @@ -1,3 +0,0 @@ -# Modify this file to force a build - -asd diff --git a/packages/dashboard/marked.config.js b/packages/dashboard/marked.config.js index 5507bea4..db0cb49c 100644 --- a/packages/dashboard/marked.config.js +++ b/packages/dashboard/marked.config.js @@ -1,3 +1,4 @@ +import fancyImage from '$src/lib/fancyImage' import hljs from 'highlight.js' const highlight = (code, lang) => { @@ -5,4 +6,4 @@ const highlight = (code, lang) => { return hljs.highlight(code, { language: lang }).value } -export default { highlight } +export default { highlight, fancyImage } diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json index 85e1c1b9..903d3273 100644 --- a/packages/dashboard/package.json +++ b/packages/dashboard/package.json @@ -5,40 +5,49 @@ "main": "./src/app.html", "scripts": { "check:types": "svelte-check", - "preview": "npx http-server@latest ../../dist/dashboard -P \"http://localhost:8080?\"", + "preview": "npx http-server@latest ./build -P \"http://localhost:8080?\"", "dev": "vite dev", "build": "NODE_ENV=production vite build", "lint": "prettier --check .", - "format": "prettier --write ." + "format": "prettier --write .", + "postbuild": "svelte-sitemap --domain https://pockethost.io" }, "type": "module", "devDependencies": { - "@microsoft/fetch-event-source": "https://github.com/pockethost/fetch-event-source.git#ebe3b7122647b48b93fd11effbbfb915d98956b0", - "pockethost": "workspace:../pockethost", - "@s-libs/micro-dash": "^16.1.0", - "@sveltejs/adapter-static": "^2.0.3", - "@sveltejs/kit": "^1.25.2", - "@tailwindcss/typography": "^0.5.10", - "@types/bootstrap": "^5.2.6", - "@types/d3-scale": "^4.0.3", - "@types/d3-scale-chromatic": "^3.0.0", - "@types/js-cookie": "^3.0.2", - "autoprefixer": "^10.4.16", + "@fortawesome/free-brands-svg-icons": "^6.6.0", + "@fortawesome/free-regular-svg-icons": "^6.6.0", + "@fortawesome/free-solid-svg-icons": "^6.6.0", + "@microsoft/fetch-event-source": "github:pockethost/fetch-event-source#ebe3b7122647b48b93fd11effbbfb915d98956b0", + "@s-libs/micro-dash": "^18.0.0", + "@sveltejs/adapter-static": "^3.0.5", + "@sveltejs/enhanced-img": "^0.3.8", + "@sveltejs/kit": "^2.6.2", + "@sveltejs/vite-plugin-svelte": "^3.1.2", + "@tailwindcss/typography": "^0.5.15", + "@types/bootstrap": "^5.2.10", + "@types/d3-scale": "^4.0.8", + "@types/d3-scale-chromatic": "^3.0.3", + "@types/js-cookie": "^3.0.6", + "autoprefixer": "^10.4.20", "boolean": "^3.2.0", - "chart.js": "4.4.0", "d3-scale": "^4.0.2", - "d3-scale-chromatic": "^3.0.0", - "daisyui": "^4.4.23", - "date-fns": "^2.30.0", - "highlight.js": "^11.8.0", - "sass": "^1.68.0", - "svelte": "^4.2.1", - "svelte-chartjs": "3.1.2", - "svelte-check": "^3.5.2", - "svelte-highlight": "^7.3.0", - "svelte-preprocess": "^5.0.4", - "tailwindcss": "^3.3.3", - "vite": "^4.4.9", - "@pockethost/plugin-console-logger": "workspace:*" + "d3-scale-chromatic": "^3.1.0", + "daisyui": "^4.12.12", + "date-fns": "^4.1.0", + "highlight.js": "^11.10.0", + "just-camel-case": "^6.2.0", + "mdsvex": "^0.12.3", + "mdsvex-enhanced-images": "^0.2.2", + "pockethost": "workspace:^", + "sass": "^1.79.4", + "svelte": "^4.2.19", + "svelte-check": "^4.0.4", + "svelte-fa": "^4.0.3", + "svelte-highlight": "^7.7.0", + "svelte-preprocess": "^6.0.3", + "svelte-sitemap": "^2.6.0", + "tailwindcss": "^3.4.13", + "unist-util-visit": "^5.0.0", + "vite": "^5.4.8" } } diff --git a/packages/dashboard/src/app.css b/packages/dashboard/src/app.css index f390fb05..94d386dd 100644 --- a/packages/dashboard/src/app.css +++ b/packages/dashboard/src/app.css @@ -10,5 +10,14 @@ } .prose :where(p):not(:where([class~='not-prose'], [class~='not-prose'] *)) { - @apply mt-0 mb-0; + @apply mt-2 mb-2; +} + +.docs-content img { + @apply border-accent rounded-lg border; +} + +.prose :where(li):not(:where([class~='not-prose'], [class~='not-prose'] *)) { + @apply mt-0 mb-0; + line-height: 1.5em; } diff --git a/packages/dashboard/src/app.html b/packages/dashboard/src/app.html index 89040c73..9ecdc56b 100644 --- a/packages/dashboard/src/app.html +++ b/packages/dashboard/src/app.html @@ -7,19 +7,9 @@ - - - - - - %sveltekit.head% - +
%sveltekit.body%
diff --git a/packages/dashboard/src/components/AlertBar.svelte b/packages/dashboard/src/components/AlertBar.svelte index f43b57f3..8ed8447f 100644 --- a/packages/dashboard/src/components/AlertBar.svelte +++ b/packages/dashboard/src/components/AlertBar.svelte @@ -1,4 +1,12 @@ -{#if message} +{#if message && !isHidden} {/if} diff --git a/packages/dashboard/src/components/CodeSample.svelte b/packages/dashboard/src/components/CodeSample.svelte index 073fbc98..921a4ee2 100644 --- a/packages/dashboard/src/components/CodeSample.svelte +++ b/packages/dashboard/src/components/CodeSample.svelte @@ -2,6 +2,7 @@ import CopyButton from '$components/CopyButton.svelte' import { Highlight } from 'svelte-highlight' import { typescript, type LanguageType } from 'svelte-highlight/languages' + import a11yDark from "svelte-highlight/styles/a11y-dark"; export let code: string export let language: LanguageType<'typescript' | 'bash' | 'dns'> = typescript @@ -9,6 +10,10 @@ const handleCopy = () => {} + + {@html a11yDark} + +
diff --git a/packages/dashboard/src/components/CopyButton.svelte b/packages/dashboard/src/components/CopyButton.svelte index 11b6b0be..b5e30728 100644 --- a/packages/dashboard/src/components/CopyButton.svelte +++ b/packages/dashboard/src/components/CopyButton.svelte @@ -1,6 +1,6 @@ - -
- PocketHost Logo -

- PocketHost -

-
diff --git a/packages/dashboard/src/components/MediaQuery.svelte b/packages/dashboard/src/components/MediaQuery.svelte deleted file mode 100644 index 9e15898f..00000000 --- a/packages/dashboard/src/components/MediaQuery.svelte +++ /dev/null @@ -1,42 +0,0 @@ - - - diff --git a/packages/dashboard/src/components/MobileNavDrawer.svelte b/packages/dashboard/src/components/MobileNavDrawer.svelte deleted file mode 100644 index 5e2f6583..00000000 --- a/packages/dashboard/src/components/MobileNavDrawer.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - -
- - -
-
- - - - - -
-
- -
- - -
- -
-
-
diff --git a/packages/dashboard/src/components/Navbar.svelte b/packages/dashboard/src/components/Navbar.svelte deleted file mode 100644 index c6c491b6..00000000 --- a/packages/dashboard/src/components/Navbar.svelte +++ /dev/null @@ -1,139 +0,0 @@ - - - diff --git a/packages/dashboard/src/components/ProvisioningStatus.svelte b/packages/dashboard/src/components/ProvisioningStatus.svelte deleted file mode 100644 index 7ff63bcd..00000000 --- a/packages/dashboard/src/components/ProvisioningStatus.svelte +++ /dev/null @@ -1,71 +0,0 @@ - - -
- {status} -
- - diff --git a/packages/dashboard/src/components/SubscriptionStatus.svelte b/packages/dashboard/src/components/SubscriptionStatus.svelte deleted file mode 100644 index bfafae45..00000000 --- a/packages/dashboard/src/components/SubscriptionStatus.svelte +++ /dev/null @@ -1,58 +0,0 @@ - - -
-
-
-

- {PLAN_NAMES[$userSubscriptionType]} -

- - {#if $userSubscriptionType === SubscriptionType.Free} -

- You're on the free Hacker plan. Unlock more features such as unlimited - projects. -

- -
- Unlock -
- {/if} - - {#if $userSubscriptionType === SubscriptionType.Legacy} -

- You're on the Legacy plan. Everything works, but you can't create new - projects. Unlock more features by supporting PocketHost. This plan may - be sunset eventually. -

- -
- Unlock -
- {/if} - - {#if $userSubscriptionType === SubscriptionType.Premium} -

- Your Pro membership is active. Thank you for supporting PocketHost! -

- {/if} - - {#if $userSubscriptionType === SubscriptionType.Founder} -

- What an absolute chad you are. Thank you for supporting PocketHost - with a Founder's membership! -

- {/if} -
-
-
diff --git a/packages/dashboard/src/components/VerifyAccountBar.svelte b/packages/dashboard/src/components/VerifyAccountBar.svelte index ab8ffc79..af852778 100644 --- a/packages/dashboard/src/components/VerifyAccountBar.svelte +++ b/packages/dashboard/src/components/VerifyAccountBar.svelte @@ -2,6 +2,9 @@ import { slide } from 'svelte/transition' import { isUserLoggedIn, isUserVerified } from '$util/stores' import { client } from '$src/pocketbase-client' + import UserLoggedIn from './guards/UserLoggedIn.svelte' + import { faCheck, faEnvelopeSquare } from '@fortawesome/free-solid-svg-icons' + import Fa from 'svelte-fa' const { resendVerificationEmail } = client() @@ -26,30 +29,32 @@ } -{#if $isUserLoggedIn && !$isUserVerified} -
- + + {#if !$isUserVerified} +
+ -
Please verify your account by clicking the link in your email
+
Please verify your account by clicking the link in your email
-
- {#if isButtonProcessing} -
- Sent! -
- {:else} - - {/if} +
+ {#if isButtonProcessing} +
+ Sent! +
+ {:else} + + {/if} - {#if formError} -
- {formError} -
- {/if} + {#if formError} +
+ {formError} +
+ {/if} +
-
-{/if} + {/if} +
diff --git a/packages/dashboard/src/components/cards/CardHeader.svelte b/packages/dashboard/src/components/cards/CardHeader.svelte index f1257ca0..07ea320b 100644 --- a/packages/dashboard/src/components/cards/CardHeader.svelte +++ b/packages/dashboard/src/components/cards/CardHeader.svelte @@ -1,4 +1,7 @@ @@ -10,9 +13,10 @@ href={documentation} class="btn btn-sm btn-outline btn-primary" target="_blank" - >Full documentation Full documentation
{/if} diff --git a/packages/dashboard/src/components/helpers/AuthStateGuard.svelte b/packages/dashboard/src/components/guards/AuthStateGuard.svelte similarity index 79% rename from packages/dashboard/src/components/helpers/AuthStateGuard.svelte rename to packages/dashboard/src/components/guards/AuthStateGuard.svelte index 5ef7920c..cfe13f76 100644 --- a/packages/dashboard/src/components/helpers/AuthStateGuard.svelte +++ b/packages/dashboard/src/components/guards/AuthStateGuard.svelte @@ -4,4 +4,6 @@ {#if $isAuthStateInitialized} +{:else} + {/if} diff --git a/packages/dashboard/src/components/helpers/Meta.svelte b/packages/dashboard/src/components/guards/Meta.svelte similarity index 100% rename from packages/dashboard/src/components/helpers/Meta.svelte rename to packages/dashboard/src/components/guards/Meta.svelte diff --git a/packages/dashboard/src/components/guards/UserHasRole.svelte b/packages/dashboard/src/components/guards/UserHasRole.svelte new file mode 100644 index 00000000..7d6f8fa2 --- /dev/null +++ b/packages/dashboard/src/components/guards/UserHasRole.svelte @@ -0,0 +1,23 @@ + + +{#if hasRole} + +{/if} diff --git a/packages/superadmin/src/components/helpers/UserLoggedIn.svelte b/packages/dashboard/src/components/guards/UserLoggedIn.svelte similarity index 85% rename from packages/superadmin/src/components/helpers/UserLoggedIn.svelte rename to packages/dashboard/src/components/guards/UserLoggedIn.svelte index b008f32a..058310f6 100644 --- a/packages/superadmin/src/components/helpers/UserLoggedIn.svelte +++ b/packages/dashboard/src/components/guards/UserLoggedIn.svelte @@ -4,7 +4,7 @@ export let redirect = false $: { if ($isAuthStateInitialized && redirect && !$isUserLoggedIn) { - window.location.href = '/' + window.location.href = '/get-started' } } diff --git a/packages/superadmin/src/components/helpers/UserLoggedOut.svelte b/packages/dashboard/src/components/guards/UserLoggedOut.svelte similarity index 100% rename from packages/superadmin/src/components/helpers/UserLoggedOut.svelte rename to packages/dashboard/src/components/guards/UserLoggedOut.svelte diff --git a/packages/dashboard/src/components/helpers/UserLoggedIn.svelte b/packages/dashboard/src/components/helpers/UserLoggedIn.svelte deleted file mode 100644 index 12925066..00000000 --- a/packages/dashboard/src/components/helpers/UserLoggedIn.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - - {#if $isUserLoggedIn} - - {/if} - diff --git a/packages/dashboard/src/components/helpers/UserLoggedOut.svelte b/packages/dashboard/src/components/helpers/UserLoggedOut.svelte deleted file mode 100644 index 3e256c34..00000000 --- a/packages/dashboard/src/components/helpers/UserLoggedOut.svelte +++ /dev/null @@ -1,10 +0,0 @@ - - - - {#if !$isUserLoggedIn} - - {/if} - diff --git a/packages/dashboard/src/components/helpers/UserUnverified.svelte b/packages/dashboard/src/components/helpers/UserUnverified.svelte deleted file mode 100644 index a5ad4319..00000000 --- a/packages/dashboard/src/components/helpers/UserUnverified.svelte +++ /dev/null @@ -1,10 +0,0 @@ - - - - {#if $isUserVerified} - - {/if} - diff --git a/packages/dashboard/src/components/helpers/UserVerified.svelte b/packages/dashboard/src/components/helpers/UserVerified.svelte deleted file mode 100644 index c066b606..00000000 --- a/packages/dashboard/src/components/helpers/UserVerified.svelte +++ /dev/null @@ -1,10 +0,0 @@ - - - - {#if !$isUserVerified} - - {/if} - diff --git a/packages/dashboard/src/components/helpers/theme.ts b/packages/dashboard/src/components/helpers/theme.ts deleted file mode 100644 index 613cc4b3..00000000 --- a/packages/dashboard/src/components/helpers/theme.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { assertTruthy } from 'pockethost/common' - -export const html = () => { - const htmlElement = document.querySelector('html') - assertTruthy(htmlElement, `Expected element to exist`) - return htmlElement -} diff --git a/packages/dashboard/src/components/sidebar/SidebarNavLink.svelte b/packages/dashboard/src/components/sidebar/SidebarNavLink.svelte deleted file mode 100644 index 71a456e0..00000000 --- a/packages/dashboard/src/components/sidebar/SidebarNavLink.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - {#if external} - - {/if} - diff --git a/packages/dashboard/src/components/tables/pricing-table/FeatureName.svelte b/packages/dashboard/src/components/tables/pricing-table/FeatureName.svelte deleted file mode 100644 index bded08bd..00000000 --- a/packages/dashboard/src/components/tables/pricing-table/FeatureName.svelte +++ /dev/null @@ -1,4 +0,0 @@ - - -
- diff --git a/packages/dashboard/src/components/tables/pricing-table/FeatureSupportBlock.svelte b/packages/dashboard/src/components/tables/pricing-table/FeatureSupportBlock.svelte deleted file mode 100644 index b8457c26..00000000 --- a/packages/dashboard/src/components/tables/pricing-table/FeatureSupportBlock.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - -{#if item === 'YesBlock'} - -{:else if item === 'NoBlock'} - -{:else} - {item} -{/if} diff --git a/packages/dashboard/src/components/tables/pricing-table/NoBlock.svelte b/packages/dashboard/src/components/tables/pricing-table/NoBlock.svelte deleted file mode 100644 index b75bcf21..00000000 --- a/packages/dashboard/src/components/tables/pricing-table/NoBlock.svelte +++ /dev/null @@ -1,6 +0,0 @@ - - - - Yes - - diff --git a/packages/dashboard/src/components/tables/pricing-table/PricingTable.svelte b/packages/dashboard/src/components/tables/pricing-table/PricingTable.svelte deleted file mode 100644 index 14da2554..00000000 --- a/packages/dashboard/src/components/tables/pricing-table/PricingTable.svelte +++ /dev/null @@ -1,327 +0,0 @@ - - -
-
- - {#if matches} -
-

Feature comparison

- -
-
-
- - - - - - - - - - - - {#each items as item} - - {item.name} - {#if item.isNew} - new - {/if} - {#if item.infoUrl} - i - {/if} - - - - - - {/each} - -
- Feature - - {PLAN_NAMES[SubscriptionType.Free]} - - {PLAN_NAMES[SubscriptionType.Premium]} - - {PLAN_NAMES[SubscriptionType.Founder]} -
- - - -
-
-
-
- {:else} -
-

- Feature comparison -

- -
-
-
-

- Free -

-

- Free forever. Use PocketHost for your next project and enjoy - all the same features the paid tiers get. -

-
- -
-
-

- Catered for business -

-
- - - -
-
- {#each items as item} - - {/each} -
-
- - - {#if $userSubscriptionType === SubscriptionType.Legacy || $userSubscriptionType === SubscriptionType.Free} - - {:else} - - {/if} -
-
-
-
- -
-
-

- {PLAN_NAMES[SubscriptionType.Premium]} -

-

- Want all your PocketHost projects in one place? That's what - the Pro tier is all about. -

-
- -
-
-

- Catered for business -

-
- - - -
-
- {#each items as item} - - {/each} -
-
- - - {#if $userSubscriptionType === SubscriptionType.Premium} - - {:else} - - {/if} -
-
-
-
- -
-
-

- {PLAN_NAMES[SubscriptionType.Founder]} -

-

- Super elite! The Founder's Edition is our way of saying thanks - for supporting PocketHost in these early days. Choose between - lifetime and annual options. -

-
- -
-
-

- Catered for business -

-
- - - -
-
- {#each items as item} - - {/each} -
-
- - - {#if $userSubscriptionType === SubscriptionType.Founder} - - {:else} - - {/if} -
-
-
-
-
-
- {/if} -
-
-
diff --git a/packages/dashboard/src/components/tables/pricing-table/TextBlock.svelte b/packages/dashboard/src/components/tables/pricing-table/TextBlock.svelte deleted file mode 100644 index 764dd107..00000000 --- a/packages/dashboard/src/components/tables/pricing-table/TextBlock.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/packages/dashboard/src/components/tables/pricing-table/YesBlock.svelte b/packages/dashboard/src/components/tables/pricing-table/YesBlock.svelte deleted file mode 100644 index 55114039..00000000 --- a/packages/dashboard/src/components/tables/pricing-table/YesBlock.svelte +++ /dev/null @@ -1,6 +0,0 @@ - - - - Yes - - diff --git a/packages/dashboard/src/env.ts b/packages/dashboard/src/env.ts index a4a637b2..ca4f3d69 100644 --- a/packages/dashboard/src/env.ts +++ b/packages/dashboard/src/env.ts @@ -1,5 +1,5 @@ import { boolean } from 'boolean' -import { InstanceFields } from 'pockethost/common' +import { type InstanceFields, SubscriptionType } from 'pockethost/common' /** * These environment variables default to pointing to the production build so @@ -11,13 +11,8 @@ import { InstanceFields } from 'pockethost/common' export const PUBLIC_APEX_DOMAIN = import.meta.env.PUBLIC_APEX_DOMAIN || `pockethost.io` -// The domain name where this dashboard lives export const PUBLIC_APP_URL = - import.meta.env.PUBLIC_APP_URL || `https://app.${PUBLIC_APEX_DOMAIN}` - -// The domain name of the lander/marketing site -export const PUBLIC_BLOG_URL = - import.meta.env.PUBLIC_BLOG_URL || `https://${PUBLIC_APEX_DOMAIN}` + import.meta.env.PUBLIC_APP_URL || `https://${PUBLIC_APEX_DOMAIN}` // The protocol to use, almost always will be https export const PUBLIC_HTTP_PROTOCOL = @@ -31,72 +26,19 @@ export const PUBLIC_MOTHERSHIP_URL = // Whether we are in debugging mode - default TRUE export const PUBLIC_DEBUG = boolean(import.meta.env.PUBLIC_DEBUG || 'true') -/** - * This helper function will take a dynamic list of values and join them - * together with a slash. - * - * @example - * mkPath('a', 'b', 'c') // a/b/c - * - * @param {string[]} paths This is an optional list of additional paths to - * append to the lander URL. - */ const mkPath = (...paths: string[]) => { return paths.filter((v) => !!v).join('/') } -/** - * Helpful alias for the lander url. - * - * @example - * LANDER_URL() // https://pockethost.io/ - * LANDER_URL('showcase') // https://pockethost.io/showcase/ - * - * @param {string[]} paths This is an optional list of additional paths to - * append to the lander URL. - */ -export const LANDER_URL = (...paths: string[]) => { - return `${PUBLIC_BLOG_URL}/${mkPath(...paths)}` +export const MAX_INSTANCE_COUNTS = { + [SubscriptionType.Free]: 25, + [SubscriptionType.Legacy]: 25, + [SubscriptionType.Founder]: 999, + [SubscriptionType.Premium]: 250, + [SubscriptionType.Flounder]: 250, // Added to get the error away } +export const FREE_MAX_INSTANCE_COUNT = 25 -/** - * Helpful alias for the blog url. - * - * @example - * BLOG_URL() // https://pockethost.io/blog - * BLOG_URL('new-features-2023') // https://pockethost.io/blog/new-features-2023/ - * - * @param {string[]} paths This is an optional list of additional paths to - * append to the blogs URL. - */ -export const BLOG_URL = (...paths: string[]) => { - return LANDER_URL(`blog`, ...paths) -} - -/** - * Helpful alias for the docs url. - * - * @example - * DOCS_URL() // https://pockethost.io/docs - * DOCS_URL('overview', 'help') // https://pockethost.io/docs/overview/help/ - * - * @param {string[]} paths This is an optional list of additional paths to - * append to the docs URL. - */ -export const DOCS_URL = (...paths: string[]) => { - return LANDER_URL(`docs`, ...paths) -} - -/** - * Helpful alias for the app url. - * - * @example - * APP_URL() // https://app.pockethost.io/ - * APP_URL('dashboard') // https://app.pockethost.io/dashboard - * - * @param {string[]} paths This is an optional list of additional paths to - * append to the app URL. - */ export const APP_URL = (...paths: string[]) => { return `${PUBLIC_APP_URL}/${mkPath(...paths)}` } diff --git a/packages/dashboard/src/lemonsqueezy.d.ts b/packages/dashboard/src/lemonsqueezy.d.ts new file mode 100644 index 00000000..1e18c0d6 --- /dev/null +++ b/packages/dashboard/src/lemonsqueezy.d.ts @@ -0,0 +1,42 @@ +// shims.d.ts + +interface Window { + createLemonSqueezy: () => void + LemonSqueezy: { + /** + * Initialises Lemon.js on your page. + * + * @param options - An object with a single property, eventHandler, which + * is a function that will be called when Lemon.js emits an event. + */ + Setup: (options: { + eventHandler: (event: { event: string }) => void + }) => void + /** Refreshes `lemonsqueezy-button` listeners on the page. */ + Refresh: () => void + + Url: { + /** + * Opens a given Lemon Squeezy URL, typically these are Checkout or + * Payment Details Update overlays. + * + * @param url - The URL to open. + */ + Open: (url: string) => void + + /** Closes the current opened Lemon Squeezy overlay checkout window. */ + Close: () => void + } + Affiliate: { + /** Retrieve the affiliate tracking ID */ + GetID: () => string + + /** + * Append the affiliate tracking parameter to the given URL + * + * @param url - The URL to append the affiliate tracking parameter to. + */ + Build: (url: string) => string + } + } +} diff --git a/packages/dashboard/src/pocketbase-client/PocketbaseClient.ts b/packages/dashboard/src/pocketbase-client/PocketbaseClient.ts index 81614537..6b16085f 100644 --- a/packages/dashboard/src/pocketbase-client/PocketbaseClient.ts +++ b/packages/dashboard/src/pocketbase-client/PocketbaseClient.ts @@ -3,26 +3,26 @@ import { createGenericSyncEvent } from '$util/events' import { fetchEventSource } from '@microsoft/fetch-event-source' import { keys, map } from '@s-libs/micro-dash' import { - AuthModel, + type AuthModel, BaseAuthStore, ClientResponseError, - CreateInstancePayloadSchema, - DeleteInstancePayload, - DeleteInstancePayloadSchema, - DeleteInstanceResult, - PocketBase, - RestCommands, - RestMethods, - UpdateInstancePayload, - UpdateInstancePayloadSchema, - UpdateInstanceResult, - assertExists, - createRestHelper, type CreateInstancePayload, + CreateInstancePayloadSchema, type CreateInstanceResult, + type DeleteInstancePayload, + DeleteInstancePayloadSchema, + type DeleteInstanceResult, type InstanceFields, type InstanceId, type InstanceLogFields, + PocketBase, + RestCommands, + RestMethods, + type UpdateInstancePayload, + UpdateInstancePayloadSchema, + type UpdateInstanceResult, + assertExists, + createRestHelper, } from 'pockethost/common' export type AuthToken = string diff --git a/packages/dashboard/src/routes/(app)/+layout.svelte b/packages/dashboard/src/routes/(app)/+layout.svelte new file mode 100644 index 00000000..438a4b5b --- /dev/null +++ b/packages/dashboard/src/routes/(app)/+layout.svelte @@ -0,0 +1,16 @@ + + +
+ + + + +

+ You must be logged in to access this + area. +

+
+
diff --git a/packages/dashboard/src/routes/(app)/+layout.ts b/packages/dashboard/src/routes/(app)/+layout.ts new file mode 100644 index 00000000..4f18607d --- /dev/null +++ b/packages/dashboard/src/routes/(app)/+layout.ts @@ -0,0 +1,2 @@ +export const prerender = false +export const ssr = false diff --git a/packages/dashboard/src/routes/(app)/account/+page.svelte b/packages/dashboard/src/routes/(app)/account/+page.svelte new file mode 100644 index 00000000..c4bea96e --- /dev/null +++ b/packages/dashboard/src/routes/(app)/account/+page.svelte @@ -0,0 +1,26 @@ + + +
My Account
+
+ + Change your avatar on + Gravatar +
+
+ Your plan: {PLAN_NAMES[$userSubscriptionType]} +
+
+ Need to change or cancel? Contact support +
+
+ +
diff --git a/packages/dashboard/src/routes/account/Card.svelte b/packages/dashboard/src/routes/(app)/account/Card.svelte similarity index 95% rename from packages/dashboard/src/routes/account/Card.svelte rename to packages/dashboard/src/routes/(app)/account/Card.svelte index 0159ecc7..a516f79d 100644 --- a/packages/dashboard/src/routes/account/Card.svelte +++ b/packages/dashboard/src/routes/(app)/account/Card.svelte @@ -65,8 +65,8 @@ {/each}
{#if !upgradable} - To change to this plan, contact @noaxis on Discordcontact support {/if} {/if} diff --git a/packages/dashboard/src/routes/account/Check.svelte b/packages/dashboard/src/routes/(app)/account/Check.svelte similarity index 100% rename from packages/dashboard/src/routes/account/Check.svelte rename to packages/dashboard/src/routes/(app)/account/Check.svelte diff --git a/packages/dashboard/src/routes/account/FAQItem.svelte b/packages/dashboard/src/routes/(app)/account/FAQItem.svelte similarity index 100% rename from packages/dashboard/src/routes/account/FAQItem.svelte rename to packages/dashboard/src/routes/(app)/account/FAQItem.svelte diff --git a/packages/dashboard/src/routes/account/FAQSection.svelte b/packages/dashboard/src/routes/(app)/account/FAQSection.svelte similarity index 97% rename from packages/dashboard/src/routes/account/FAQSection.svelte rename to packages/dashboard/src/routes/(app)/account/FAQSection.svelte index 263b51d6..bf47fc1b 100644 --- a/packages/dashboard/src/routes/account/FAQSection.svelte +++ b/packages/dashboard/src/routes/(app)/account/FAQSection.svelte @@ -1,6 +1,6 @@
+ import { PLAN_NAMES, SubscriptionType } from 'pockethost' + import { userStore } from '$util/stores' + import { onMount } from 'svelte' + import PricingCard from '$src/routes/(static)/pricing/PricingCard.svelte' + + export let priceMonthly: [number, string?, number?] = [ + 359, + 'once, use forever', + 299, + ] + export let priceAnnually: [number, string?, number?] = [ + 159, + 'year (save 55%)', + 99, + ] + export let comingSoonText = '' + export let comingSoon = false + export let startDate: Date | null = null + + + diff --git a/packages/dashboard/src/routes/(app)/dashboard/+page.svelte b/packages/dashboard/src/routes/(app)/dashboard/+page.svelte new file mode 100644 index 00000000..8dfff11f --- /dev/null +++ b/packages/dashboard/src/routes/(app)/dashboard/+page.svelte @@ -0,0 +1,42 @@ + + + + Dashboard - PocketHost + + +
+

Dashboard

+ + + New Instance +
+ +
+
Instances
+ +
+ {instanceCount}/{MAX_INSTANCE_COUNTS[$userSubscriptionType]} + {#if $userSubscriptionType === SubscriptionType.Free} + Upgrade + {/if} +
+
+ +
+ +
diff --git a/packages/dashboard/src/routes/dashboard/InstanceList.svelte b/packages/dashboard/src/routes/(app)/dashboard/InstanceList.svelte similarity index 64% rename from packages/dashboard/src/routes/dashboard/InstanceList.svelte rename to packages/dashboard/src/routes/(app)/dashboard/InstanceList.svelte index a369761b..3f57c062 100644 --- a/packages/dashboard/src/routes/dashboard/InstanceList.svelte +++ b/packages/dashboard/src/routes/(app)/dashboard/InstanceList.svelte @@ -1,9 +1,12 @@ {#each values($globalInstancesStore).sort( (a, b) => a.subdomain.localeCompare(b.subdomain), ) as instance, index} -
-
+
+ {/each} diff --git a/packages/dashboard/src/routes/app/instances/[instanceId]/+layout.svelte b/packages/dashboard/src/routes/(app)/instances/[instanceId]/+layout.svelte similarity index 54% rename from packages/dashboard/src/routes/app/instances/[instanceId]/+layout.svelte rename to packages/dashboard/src/routes/(app)/instances/[instanceId]/+layout.svelte index 1a91f0fd..f508da5f 100644 --- a/packages/dashboard/src/routes/app/instances/[instanceId]/+layout.svelte +++ b/packages/dashboard/src/routes/(app)/instances/[instanceId]/+layout.svelte @@ -6,8 +6,13 @@ import { assert } from 'pockethost/common' import { instance } from './store' import { client } from '$src/pocketbase-client' - import { InstanceId } from 'pockethost/common' + import { type InstanceId } from 'pockethost/common' import Toggle from './Toggle.svelte' + import Fa from 'svelte-fa' + import { + faExternalLinkAlt, + faTriangleExclamation, + } from '@fortawesome/free-solid-svg-icons' let isReady = false $: { @@ -46,53 +51,53 @@ {#if isReady} -
+

- {$instance.subdomain}.pockethost.io - v{$instance.version} + {$instance.subdomain} +

+ + Version {$instance.version} - {$instance.status} +
- +
- + {#if $instance.maintenance} - +
+ +
{/if} -
-
-
    + +
    +
    + -
    -
    - +
+
+ Danger Zone - +
-
    -
  • Change Version
  • -
  • Custom Domain
  • -
  • Admin Sync
  • -
  • Dev Mode
  • -
  • Rename
  • +