Skip to content

Commit

Permalink
Feature/crosshair manager (#2)
Browse files Browse the repository at this point in the history
* migrations system setup

* updated types location, github actions defined

* auth flow complete

* env badge, updated packages, manager page, simplified home page, layout

* user context, logout button

* crosshair contains name

* scale taken into account for xhair calculations

* outline takes alpha into account, update style of xhairpreview, start of manager page

* useCrosshair hook

* text overflow handled, addcrosshaircard component made

* frontend for crosshair form done

* crosshair commands moved to utils, updated styling of preview card, usercrosshairs component, useCrosshair hook, crosshair endpoint, user type moved, DBTypes

* edit/delete form done

* created_at for crosshairs
  • Loading branch information
saddiqs1 authored Jan 11, 2024
1 parent 81b3798 commit b4ce370
Show file tree
Hide file tree
Showing 57 changed files with 3,414 additions and 386 deletions.
8 changes: 6 additions & 2 deletions .env example
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
NEXT_PUBLIC_CLIENT_VAR=
SERVER_VAR=
DATABASE_URL="postgresql://user:password@localhost:5432/cs-crosshairs"
NODE_ENV="development" # DO NOT CHANGE THIS

NEXT_PUBLIC_DOMAIN=http://localhost:3000
STEAM_API_KEY= # Get from https://steamcommunity.com/dev/apikey
SESSION_SECRET=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
47 changes: 47 additions & 0 deletions .github/workflows/main-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Deploy

on:
push:
branches:
- main

jobs:
migrate-database:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 18

- name: Install dependencies
run: npm ci

- name: Run Database Migration
run: npm run migrate
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
NODE_ENV: 'production'

build-and-deploy-to-vercel:
runs-on: ubuntu-latest
needs: migrate-database

steps:
- uses: actions/checkout@v2

- name: Install Vercel CLI
run: npm install --global vercel@latest

- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

- name: Build Project Artifacts
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
28 changes: 28 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: PR Created

on:
pull_request:
branches:
- main

jobs:
lint-and-build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 18

- name: Install dependencies
run: npm ci

- name: Lint code
run: npm run lint

- name: Build App
run: npm run build
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/node_modules
/.pnp
.pnp.js
/distDatabase

# testing
/coverage
Expand Down
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,63 @@ This is a basic [Next.js](https://nextjs.org/) template with [Mantine Core & Not

2. Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

## Database Commands

- Create a new migration

```bash
npm run migrate:create migration-name
```

- Run all migrations (_NOTE: This will run migrations that have not yet been run_)

```bash
npm run migrate
```

- Generate your database types. You should run this everytime after you have run a new migration.

```bash
npm run db:generate
```

- Run migrations from fresh i.e. after deleting everything in the database (_NOTE: This will nuke your database, and run all migrations_)

```bash
npm run migrate:fresh
```

- Run a single migration

```bash
npm run migrate:up
```

- Revert a single migration (_NOTE: This will only revert a single migration at a time. Mainly useful for development_)

```bash
npm run migrate:down
```

- Seed your database (_NOTE: This will insert example data into your database. Mainly useful for development_)

```bash
npm run db:seed
```

- Migrate fresh and seed the db in one command. Useful for the dev environment.

```bash
npm run dev:reset-db
```

### TODO

- [ ] Fix `csgo-sharecode` package import
- [ ] Show crosshair style within preview
- [ ] toggle between 16:9 vs 4:3 for crosshair preview
- [ ] allow user to save crosshair
- [ ] validation on converter page

- [ ] create login
- [ ] create ui for entering in and saving crosshairs
27 changes: 27 additions & 0 deletions database/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { ColumnType } from "kysely";

export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
? ColumnType<S, I | undefined, U>
: ColumnType<T, T | undefined, T>;

export type Timestamp = ColumnType<Date, Date | string, Date | string>;

export interface Crosshairs {
created_at: Generated<Timestamp>;
crosshair: string;
id: Generated<number>;
name: string;
user_id: number | null;
}

export interface Users {
created_at: Generated<Timestamp>;
id: Generated<number>;
latest_login_at: Timestamp | null;
steam_uid: string;
}

export interface DB {
crosshairs: Crosshairs;
users: Users;
}
182 changes: 182 additions & 0 deletions database/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import * as path from 'path';
import { promises as fs } from 'fs';
import { Kysely, Migrator, FileMigrationProvider, sql } from 'kysely';
import chalk from 'chalk';
import { Env, getDb, getEnv } from './utils';

function getMigrator(db: Kysely<any>) {
const migrator = new Migrator({
db,
provider: new FileMigrationProvider({
fs,
path,
migrationFolder: path.join(__dirname, 'migrations'),
}),
});

return migrator;
}

async function migrateFresh(env: Env) {
const db = getDb(env);
const migrator = getMigrator(db);

// Deletes all tables from database.
await sql`
DO $$
DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
END LOOP;
END $$;
`.execute(db);

const { error, results } = await migrator.migrateToLatest();

results?.forEach((it) => {
if (it.status === 'Success') {
console.log(
chalk.greenBright(
`✔ Migration "${it.migrationName}" was executed successfully!`
)
);
} else if (it.status === 'Error') {
console.error(
chalk.redBright(`❗ Failed to execute migration "${it.migrationName}"`)
);
}
});

if (error) {
console.error(chalk.redBright(`❌ Migrations have failed`));
console.error(error);
process.exit(1);
}

await db.destroy();
}

async function migrateToLatest(env: Env) {
const db = getDb(env);
const migrator = getMigrator(db);

const { error, results } = await migrator.migrateToLatest();

if (results?.length === 0 && !error) {
console.log(chalk.blueBright(`No migrations were executed.`));
await db.destroy();
return;
}

results?.forEach((it) => {
if (it.status === 'Success') {
console.log(
chalk.greenBright(
`✔ Migration "${it.migrationName}" was executed successfully!`
)
);
} else if (it.status === 'Error') {
console.error(
chalk.redBright(`❗ Failed to execute migration "${it.migrationName}"`)
);
}
});

if (error) {
console.error(chalk.redBright(`❌ Migrations have failed`));
console.error(error);
process.exit(1);
}

await db.destroy();
}

async function migrateUp(env: Env) {
const db = getDb(env);
const migrator = getMigrator(db);

const { error, results } = await migrator.migrateUp();

if (results?.length === 0 && !error) {
console.log(chalk.blueBright(`No migrations were executed.`));
await db.destroy();
return;
}

results?.forEach((it) => {
if (it.status === 'Success') {
console.log(
chalk.greenBright(
`✔ Migration "${it.migrationName}" was executed successfully!`
)
);
} else if (it.status === 'Error') {
console.error(
chalk.redBright(`❗ Failed to execute migration "${it.migrationName}"`)
);
}
});

if (error) {
console.error(chalk.redBright(`❌ Migrations have failed`));
console.error(error);
process.exit(1);
}

await db.destroy();
}

async function migrateDown(env: Env) {
const db = getDb(env);
const migrator = getMigrator(db);

const { error, results } = await migrator.migrateDown();

if (results?.length === 0 && !error) {
console.log(chalk.blueBright(`No migrations were executed.`));
await db.destroy();
return;
}

results?.forEach((it) => {
if (it.status === 'Success') {
console.log(
chalk.greenBright(
`✔ Migration "${it.migrationName}" was reverted successfully!`
)
);
} else if (it.status === 'Error') {
console.error(
chalk.redBright(`❗ Failed to revert migration "${it.migrationName}"`)
);
}
});

if (error) {
console.error(chalk.redBright(`❌ Migrations have failed`));
console.error(error);
process.exit(1);
}

await db.destroy();
}

const env = getEnv();

if (process.argv[2] === 'down') {
console.log(chalk.blueBright('Migrating Down...'));
migrateDown(env);
} else if (process.argv[2] === 'up') {
console.log(chalk.blueBright('Migrating Up...'));
migrateUp(env);
} else if (process.argv[2] === 'fresh') {
console.log(chalk.blueBright('Migrating Fresh...'));
migrateFresh(env);
} else if (process.argv[2] === 'latest') {
console.log(chalk.blueBright('Migrating To Latest...'));
migrateToLatest(env);
} else {
console.log(chalk.grey('Unknown command'));
}
Loading

0 comments on commit b4ce370

Please sign in to comment.