Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
AlemTuzlak authored May 28, 2024
0 parents commit a13aa99
Show file tree
Hide file tree
Showing 55 changed files with 17,036 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Add your env variables here
82 changes: 82 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* This is intended to be a basic starting point for linting in your app.
* It relies on recommended configs out of the box for simplicity, but you can
* and should modify this configuration to best suit your team's needs.
*/

/** @type {import('eslint').Linter.Config} */
module.exports = {
root: true,
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
env: {
browser: true,
commonjs: true,
es6: true,
},
// Base config
extends: ["eslint:recommended"],

overrides: [
// React
{
files: ["**/*.{js,jsx,ts,tsx}"],
plugins: ["react", "jsx-a11y"],
extends: [
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended",
],
settings: {
react: {
version: "detect",
},
formComponents: ["Form"],
linkComponents: [
{ name: "Link", linkAttribute: "to" },
{ name: "NavLink", linkAttribute: "to" },
],
"import/resolver": {
typescript: {},
},
},
},

// Typescript
{
files: ["**/*.{ts,tsx}"],
plugins: ["@typescript-eslint", "import"],
parser: "@typescript-eslint/parser",
settings: {
"import/internal-regex": "^~/",
"import/resolver": {
node: {
extensions: [".ts", ".tsx"],
},
typescript: {
alwaysTryTypes: true,
},
},
},
extends: [
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
],
},

// Node
{
files: [".eslintrc.js"],
env: {
node: true,
},
},
],
};
42 changes: 42 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Fixes #

# Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context.
List any dependencies that are required for this change.

## Type of change

Please mark relevant options with an `x` in the brackets.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
- [ ] Algorithm update - updates algorithm documentation/questions/answers etc.
- [ ] Other (please describe):

# How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also
list any relevant details for your test configuration

- [ ] Integration tests
- [ ] Unit tests
- [ ] Manual tests
- [ ] No tests required

# Reviewer checklist

Mark everything that needs to be checked before merging the PR.

- [ ] Check if the UI is working as expected and is satisfactory
- [ ] Check if the code is well documented
- [ ] Check if the behavior is what is expected
- [ ] Check if the code is well tested
- [ ] Check if the code is readable and well formatted
- [ ] Additional checks (document below if any)

# Screenshots (if appropriate):

# Questions (if appropriate):
81 changes: 81 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: 🚀 Validation Pipeline
concurrency:
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
actions: write
contents: read
# Required to put a comment into the pull-request
pull-requests: write
jobs:
lint:
name: ⬣ ESLint
runs-on: ubuntu-latest
steps:
- name: 🛑 Cancel Previous Runs
uses: styfle/[email protected]

- name: ⬇️ Checkout repo
uses: actions/checkout@v4

- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 20

- name: 📥 Download deps
uses: bahmutov/npm-install@v1
with:
useLockFile: false

- name: 🔬 Lint
run: npm run lint:strict

typecheck:
name: 🔎 Type check
runs-on: ubuntu-latest
steps:
- name: 🛑 Cancel Previous Runs
uses: styfle/[email protected]
- name: ⬇️ Checkout repo
uses: actions/checkout@v4
- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 20
- name: 📥 Download deps
uses: bahmutov/npm-install@v1
with:
useLockFile: false
- name: 🔎 Type check
run: npm run typecheck

vitest:
name: ⚡ Unit Tests
runs-on: ubuntu-latest
steps:
- name: 🛑 Cancel Previous Runs
uses: styfle/[email protected]
- name: ⬇️ Checkout repo
uses: actions/checkout@v4
- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 20
- name: 📥 Download deps
uses: bahmutov/npm-install@v1
with:
useLockFile: false
- name: Install dotenv cli
run: npm install -g dotenv-cli
- name: ⚡ Run vitest
run: npm run test:cov
- name: "Report Coverage"
# Only works if you set `reportOnFailure: true` in your vite config as specified above
if: always()
uses: davelosert/vitest-coverage-report-action@v2
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
/.cache
/build
.env
coverage
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npm run typecheck && npm run lint:strict
1 change: 1 addition & 0 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npm run test && npm run knip -- --no-exit-code
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build
node_modules
coverage
3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["codeforge.remix-forge"]
}
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Forge 42

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@


<p align="middle">
<img width="900px" height="500px" src="./public/base-stack.png" />
</p>

# Welcome to Forge 42 base-stack

This is a base-stack for Forge 42 projects. This stack is a starting point for all Forge 42 stacks with more
advanced features. This is an ESM Vite stack with Remix.run.

It includes a basic setup for a project with Remix.run and:
- TypeScript
- TailwindCSS
- Vite
- Vitest (unit tests)
- Scripting
- ESLint
- i18n support
- Icon generator
- Husky hooks
- remix-development-tools + plugins

## How to use

1. Initialize the repository with our CLI:
```bash
npx f42 init -t base-stack -o ./your-project-name-here
```
2. Install the dependencies:
```bash
npm install
```
3. Read through the README.md files in the project to understand our decisions.

4. Run the cleanup script:
```bash
npm run cleanup
```

This will remove everything in the project related to the base-stack like README.md etc.
This is the first thing you should run after initializing the project.
After it is run it will remove itself from the package.json.

5. Start the development server:
```bash
npm run dev
```
6. Happy coding!

23 changes: 23 additions & 0 deletions app/.server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# .server convention

Thanks to vite you can put all your server specific code under this directory.
This is a great place to put your server code, like API routes, server middleware, database connections, etc.

This directory is not included in the client build, so you can use server-specific modules here.
We highly recommend you don't use barrel files to export from here.
Instead, import the files directly where you need them.

For example, do this:

```js
import { getPosts } from '~/server/api/posts'
```

Instead of this:

```js
import { getPosts } from '~/server'
```

It can cause circular dependencies in your project and make it harder to understand where things are coming from.
Your file might have more imports but your bundles will thank you for it!
53 changes: 53 additions & 0 deletions app/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { RemixBrowser } from "@remix-run/react";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import i18n from "~/localization/i18n";
import i18next from "i18next";
import { I18nextProvider, initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
import { getInitialNamespaces } from "remix-i18next/client";
import { resources } from "./localization/resource";

async function hydrate() {
// eslint-disable-next-line import/no-named-as-default-member
await i18next
.use(initReactI18next) // Tell i18next to use the react-i18next plugin
.use(LanguageDetector) // Setup a client-side language detector
.use(Backend) // Setup your backend
.init({
...i18n, // spread the configuration
// This function detects the namespaces your routes rendered while SSR use
ns: getInitialNamespaces(),
backend: { loadPath: "/locales/{{lng}}/{{ns}}.json" },
resources,
detection: {
// Here only enable htmlTag detection, we'll detect the language only
// server-side with remix-i18next, by using the `<html lang>` attribute
// we can communicate to the client the language detected server-side
order: ["htmlTag"],
// Because we only use htmlTag, there's no reason to cache the language
// on the browser, so we disable it
caches: [],
},
});

startTransition(() => {
hydrateRoot(
document,
<I18nextProvider i18n={i18next}>
<StrictMode>
<RemixBrowser />
</StrictMode>
</I18nextProvider>
);
});
}

if (window.requestIdleCallback) {
window.requestIdleCallback(hydrate);
} else {
// Safari doesn't support requestIdleCallback
// https://caniuse.com/requestidlecallback
window.setTimeout(hydrate, 1);
}
Loading

0 comments on commit a13aa99

Please sign in to comment.