Skip to content

Commit

Permalink
Add remix
Browse files Browse the repository at this point in the history
  • Loading branch information
shawnmclean committed May 20, 2024
0 parents commit bdeafa2
Show file tree
Hide file tree
Showing 111 changed files with 25,480 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Package Managers

yarn.lock
node_modules

# Editor Configs

.idea
.vscode
.DS_Store

# Miscelaneous

/.cache
/build
/public/build
.env

# Prisma

/prisma/data.db
/prisma/data.db-journal

# Tests

/coverage
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/node_modules
/build
/public/build
6 changes: 6 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @type {import('eslint').Linter.Config}
*/
module.exports = {
extends: ['@remix-run/eslint-config', '@remix-run/eslint-config/node', 'prettier'],
}
20 changes: 20 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Learn about Dependabot:
# https://docs.github.com/en/code-security/dependabot

version: 2
updates:
# Enable version updates for npm.
- package-ecosystem: 'npm'
# Look for `package.json` and `lock` files in the `root` directory.
directory: '/'
# Check the npm registry for updates every day.
schedule:
interval: 'weekly'

# Enable version updates for Github-Actions.
- package-ecosystem: github-actions
# Look in the `root` directory.
directory: /
# Check for updates every day (weekdays)
schedule:
interval: weekly
84 changes: 84 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: 💿 Main
on:
push:
branches:
- main
- dev
pull_request: {}

permissions:
actions: write
contents: read

jobs:
lint:
name: ⬣ ESLint
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]

- name: Checkout Repository
uses: actions/[email protected]

- name: Setup Node
uses: actions/[email protected]
with:
node-version: 20

- name: Install Dependencies
uses: pnpm/action-setup@v4
with:
version: 8
run_install: true

- name: Run Lint
run: pnpm lint

typecheck:
name: ʦ TypeScript
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]

- name: Checkout Repository
uses: actions/[email protected]

- name: Setup Node
uses: actions/[email protected]
with:
node-version: 20

- name: Install Dependencies
uses: pnpm/action-setup@v4
with:
version: 8
run_install: true

- name: Run Typechecking
run: pnpm typecheck

vitest:
name: ⚡ Vitest
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]

- name: Checkout Repository
uses: actions/[email protected]

- name: Setup Node.js
uses: actions/[email protected]
with:
node-version: 20

- name: Install Dependencies
uses: pnpm/action-setup@v4
with:
version: 8
run_install: true

- name: Run Vitest
run: pnpm test
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Package Managers
yarn.lock
node_modules

# Editor Configs
.idea
.vscode
.DS_Store

# Miscelaneous
/.cache
/build
/public/build
.env

# Prisma
/prisma/data.db
/prisma/data.db-journal

# Tests
/coverage
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
auto-install-peers=true
registry=https://registry.npmjs.org/
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
package-lock.json
pnpm-lock.yaml

/build
/public/build
.env
14 changes: 14 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"tabWidth": 2,
"printWidth": 90,
"semi": false,
"useTabs": false,
"bracketSpacing": true,
"bracketSameLine": true,
"singleQuote": true,
"jsxSingleQuote": false,
"singleAttributePerLine": false,
"arrowParens": "always",
"trailingComma": "all",
"plugins": ["prettier-plugin-tailwindcss"]
}
64 changes: 64 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# syntax = docker/dockerfile:1

# Adjust NODE_VERSION as desired
ARG NODE_VERSION=20.11.0
FROM node:${NODE_VERSION}-slim as base

LABEL fly_launch_runtime="Remix/Prisma"

# Remix/Prisma app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV="production"

# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential node-gyp openssl pkg-config python-is-python3

# Install node modules
COPY --link .npmrc package-lock.json package.json ./
RUN npm ci --include=dev

# Generate Prisma Client
COPY --link prisma .
RUN npx prisma generate

# Copy application code
COPY --link . .

# Build application
RUN npm run build

# Remove development dependencies
RUN npm prune --omit=dev

# Final stage for app image
FROM base

# Install packages needed for deployment
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y openssl sqlite3 && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Copy built application
COPY --from=build /app /app
COPY --from=build /app/node_modules/prisma /app/node_modules/prisma

# Setup sqlite3 on a separate volume
RUN mkdir -p /data
VOLUME /data

# add shortcut for connecting to database CLI
RUN echo "#!/bin/sh\nset -x\nsqlite3 \$DATABASE_URL" > /usr/local/bin/database-cli && chmod +x /usr/local/bin/database-cli

# Entrypoint prepares the database.
ENTRYPOINT [ "/app/docker-entrypoint.js" ]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
ENV DATABASE_URL="file:///data/sqlite.db"
CMD [ "npm", "run", "start" ]
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<h1 align="center">
🛍️ Remix SaaS
</h1>

<div align="center">
<p>
A Lightweight, Feature-Rich, and Production-Ready Remix Stack for your next SaaS application.
</p>
</div>

<div align="center">
<p>
<a href="https://remix-saas.fly.dev">Live Demo</a>
·
<a href="https://github.com/dev-xo/remix-saas/tree/main/docs">Documentation</a>
·
<a href="https://twitter.com/DanielKanem">Twitter</a>
</p>
</div>

```sh
npx create-remix-saas@latest
```

## [Live Demo](https://remix-saas.fly.dev)

[![Remix SaaS](https://raw.githubusercontent.com/dev-xo/dev-xo/main/remix-saas/intro.png)](https://remix-saas.fly.dev)

We've created a simple demo that displays all template-provided features. Psst! Give the site a few seconds to load! _(It's running on a free tier!)_

> [!NOTE]
> Remix SaaS is an Open Source Template that shares common bits of code with: [Indie Stack](https://github.com/remix-run/indie-stack), [Epic Stack](https://github.com/epicweb-dev/epic-stack), [Supa Stripe Stack](https://github.com/rphlmr/supa-stripe-stack), and some other amazing Open Source Remix resources. Check them out, please!
## Getting Started

Please, read the [Getting Started Documentation](https://github.com/dev-xo/remix-saas/tree/main/docs#remix-saas-documentation) to successfully initialize your **Remix SaaS** Template.

## Support

If you found **Remix SaaS** helpful, consider supporting it with a ⭐ [Star](https://github.com/dev-xo/remix-saas). It helps the repository grow and provides the required motivation to continue maintaining the project. Thank you!

## Acknowledgments

Special thanks to [@mw10013](https://github.com/mw10013) who has been part of the Remix SaaS development.
39 changes: 39 additions & 0 deletions app/components/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useLocation } from '@remix-run/react'
import { ROUTE_PATH as DASHBOARD_PATH } from '#app/routes/dashboard+/_layout'
import { ROUTE_PATH as BILLING_PATH } from '#app/routes/dashboard+/settings.billing'
import { ROUTE_PATH as SETTINGS_PATH } from '#app/routes/dashboard+/settings'
import { ROUTE_PATH as ADMIN_PATH } from '#app/routes/admin+/_layout'

export function Header() {
const location = useLocation()
const allowedLocations = [DASHBOARD_PATH, BILLING_PATH, SETTINGS_PATH, ADMIN_PATH]

const headerTitle = () => {
if (location.pathname === DASHBOARD_PATH) return 'Dashboard'
if (location.pathname === BILLING_PATH) return 'Billing'
if (location.pathname === SETTINGS_PATH) return 'Settings'
if (location.pathname === ADMIN_PATH) return 'Admin'
}
const headerDescription = () => {
if (location.pathname === DASHBOARD_PATH)
return 'Manage your Apps and view your usage.'
if (location.pathname === SETTINGS_PATH) return 'Manage your account settings.'
if (location.pathname === BILLING_PATH)
return 'Manage billing and your subscription plan.'
if (location.pathname === ADMIN_PATH) return 'Your admin dashboard.'
}

if (!allowedLocations.includes(location.pathname as (typeof allowedLocations)[number]))
return null

return (
<header className="z-10 flex w-full flex-col border-b border-border bg-card px-6">
<div className="mx-auto flex w-full max-w-screen-xl items-center justify-between py-12">
<div className="flex flex-col items-start gap-2">
<h1 className="text-3xl font-medium text-primary/80">{headerTitle()}</h1>
<p className="text-base font-normal text-primary/60">{headerDescription()}</p>
</div>
</div>
</header>
)
}
28 changes: 28 additions & 0 deletions app/components/logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { cn } from '#app/utils/misc.js'

type LogoProps = {
width?: number
height?: number
className?: string
[key: string]: unknown | undefined
}

export function Logo({ width, height, className, ...args }: LogoProps) {
return (
<svg
{...args}
width={width ?? 40}
height={height ?? 40}
xmlns="http://www.w3.org/2000/svg"
className={cn(`text-primary ${className}`)}
viewBox="0 0 24 24"
fill="none">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M13.5475 3.25H13.5475C15.3866 3.24999 16.8308 3.24998 17.9694 3.3786C19.1316 3.50988 20.074 3.78362 20.8574 4.40229C21.0919 4.58749 21.3093 4.79205 21.507 5.0138C22.1732 5.76101 22.4707 6.66669 22.6124 7.77785C22.75 8.85727 22.75 10.2232 22.75 11.9473V12.0528C22.75 13.7768 22.75 15.1427 22.6124 16.2222C22.4707 17.3333 22.1732 18.239 21.507 18.9862C21.3093 19.208 21.0919 19.4125 20.8574 19.5977C20.074 20.2164 19.1316 20.4901 17.9694 20.6214C16.8308 20.75 15.3866 20.75 13.5475 20.75H10.4525C8.61345 20.75 7.16917 20.75 6.03058 20.6214C4.86842 20.4901 3.926 20.2164 3.14263 19.5977C2.90811 19.4125 2.69068 19.2079 2.49298 18.9862C1.82681 18.239 1.52932 17.3333 1.38763 16.2222C1.24998 15.1427 1.24999 13.7767 1.25 12.0527V12.0527V11.9473V11.9472C1.24999 10.2232 1.24998 8.85727 1.38763 7.77785C1.52932 6.66669 1.82681 5.76101 2.49298 5.0138C2.69068 4.79205 2.90811 4.58749 3.14263 4.40229C3.926 3.78362 4.86842 3.50988 6.03058 3.3786C7.16917 3.24998 8.61345 3.24999 10.4525 3.25H10.4525H13.5475ZM10 8C7.79086 8 6 9.79086 6 12C6 14.2091 7.79086 16 10 16C10.7286 16 11.4117 15.8052 12.0001 15.4648C12.5884 15.8049 13.2719 16 13.9998 16C16.2089 16 17.9998 14.2091 17.9998 12C17.9998 9.79086 16.2089 8 13.9998 8C13.2719 8 12.5884 8.19505 12.0001 8.53517C11.4117 8.19481 10.7286 8 10 8ZM8 12C8 10.8954 8.89543 10 10 10C11.1046 10 12 10.8954 12 12C12 13.1046 11.1046 14 10 14C8.89543 14 8 13.1046 8 12ZM13.9998 14C13.8271 14 13.6599 13.9783 13.5004 13.9374C13.8187 13.3634 14 12.7029 14 12C14 11.2971 13.8187 10.6366 13.5004 10.0626C13.6599 10.0217 13.8271 10 13.9998 10C15.1043 10 15.9998 10.8954 15.9998 12C15.9998 13.1046 15.1043 14 13.9998 14Z"
fill="currentColor"
/>
</svg>
)
}
22 changes: 22 additions & 0 deletions app/components/misc/client-hints.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useEffect } from 'react'
import { useRevalidator } from '@remix-run/react'
import { subscribeToSchemeChange } from '@epic-web/client-hints/color-scheme'
import { hintsUtils } from '#app/utils/hooks/use-hints'

/**
* Injects an inline script that checks/sets CH Cookies (if not present).
* Reloads the page if any Cookie was set to an inaccurate value.
*/
export function ClientHintCheck({ nonce }: { nonce: string }) {
const { revalidate } = useRevalidator()
useEffect(() => subscribeToSchemeChange(() => revalidate()), [revalidate])

return (
<script
nonce={nonce}
dangerouslySetInnerHTML={{
__html: hintsUtils.getClientHintCheckScript(),
}}
/>
)
}
Loading

0 comments on commit bdeafa2

Please sign in to comment.