Skip to content

Commit

Permalink
hack creation support
Browse files Browse the repository at this point in the history
  • Loading branch information
bates64 committed Jan 29, 2024
1 parent 94a3e4d commit cae4c20
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 29 deletions.
30 changes: 23 additions & 7 deletions src/lib/supabase/database.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/routes/games/[game]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<ol class="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
{#each data.hacks as hack}
<li>
<a href={`/games/${data.game.slug}/${hack.slug}`} class="w-full">
<a href={`/hacks/${hack.slug}`} class="w-full">
<HackCard name={hack.name} description={hack.short_description} />
</a>
</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { error } from '@sveltejs/kit';

export async function load({ parent, locals: { supabase }, params }) {
const { game } = await parent();

export async function load({ locals: { supabase }, params }) {
const { data: hack, error: queryError } = await supabase
.from('hacks')
.select()
.eq('game_id', game.id)
.eq('slug', params.hack);
.eq('slug', params.slug)
.single();

if (queryError) {
console.error(queryError);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@

<Layout>
<Breadcrumbs slot="breadcrumbs">
<Breadcrumb up={2}>
{data.platform?.name}
</Breadcrumb>
<Breadcrumb up={1}>
{data.game?.game_name}
</Breadcrumb>
<Breadcrumb up={0}>
{data.hack.name}
</Breadcrumb>
Expand All @@ -29,7 +23,7 @@
<main class="grow">
<h1 class="py-3 text-4xl font-bold text-stone-900 dark:text-stone-100">{data.hack.name}</h1>

<Markdown source={data.hack.markdownDescription} />
<Markdown source={data.hack.markdown_description} />
</main>
<aside class="w-96 overflow-hidden">
<!--
Expand Down
55 changes: 53 additions & 2 deletions src/routes/new/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,60 @@
import { toSlug } from '$lib/convert';
import { error, fail, redirect } from '@sveltejs/kit';
import { superValidate } from 'sveltekit-superforms/server';

import type { Actions, PageServerLoad } from './$types';
import { formSchema } from './schema';

export async function load() {
export const load: PageServerLoad = async ({ locals: { getSession } }) => {
// if not logged in, redirect to login
const session = await getSession();
if (!session) {
return redirect(303, `/auth?redirect=/new`);
}

return {
form: await superValidate(formSchema),
};
}
};

export const actions: Actions = {
default: async (event) => {
const form = await superValidate(event, formSchema);
if (!form.valid) {
return fail(400, {
form,
});
}

const { supabase } = event.locals;

// Get the game id
const gameResp = await supabase
.from('games')
.select('id')
.eq('name', form.data.game_name)
.single();
if (gameResp.error) {
console.error(gameResp.error);
throw error(500, 'Error finding game');
}

// Create the hack
const createResp = await supabase
.from('hacks')
.insert({
game_id: gameResp.data.id,
name: form.data.name,
slug: form.data.slug.length === 0 ? toSlug(form.data.name) : form.data.slug,
})
.select('slug')
.single();
if (createResp.error) {
console.error(createResp.error);
throw error(500, 'Error creating hack');
}

// Redirect to the hack's page
return redirect(303, `/hacks/${createResp.data.slug}`);
},
};
1 change: 0 additions & 1 deletion src/routes/new/new-hack-form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
<Form.Root method="POST" {form} schema={formSchema} let:config>
<Form.Field {config} name="game_name">
<Form.Item>
<!-- TODO: display as url, like https://site/games/[game]/[slug] -->
<Form.Label>Game</Form.Label>
<Form.Game />
<Form.Validation />
Expand Down
14 changes: 10 additions & 4 deletions src/routes/new/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ import { z } from 'zod';

export const formSchema = z.object({
name: z.string().min(1, { message: 'Required' }),
slug: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {
message: 'Must be kebab-case (lowercase, hyphenated, no spaces)',
}),
game_name: z.string().min(1, { message: 'Required' }),
slug: z
.string()
.regex(/^[a-z0-9]*(-[a-z0-9]+)*$/, {
message: 'Must be kebab-case (lowercase, hyphenated, no spaces)',
})
.max(50, { message: 'Must be 50 characters or less' }),
game_name: z
.string()
.min(1, { message: 'Required' })
.max(50, { message: 'Must be 50 characters or less' }),
});

export type FormSchema = typeof formSchema;
4 changes: 2 additions & 2 deletions supabase/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ enabled = true
# in emails.
site_url = "http://localhost:5173/"
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
additional_redirect_urls = ["http://localhost:5173"]
additional_redirect_urls = ["http://localhost:5173", "http://localhost:5173/new"]
# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
jwt_expiry = 3600
# If disabled, the refresh token will never expire.
enable_refresh_token_rotation = true
# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
# Allows refresh tokens to be reused after expiry, up to the specified intervmarkdown_descriptional in seconds.
# Requires enable_refresh_token_rotation = true.
refresh_token_reuse_interval = 10
# Allow/disallow new user signups to your project.
Expand Down
96 changes: 96 additions & 0 deletions supabase/migrations/20240129172214_remote_schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
create table "public"."hacks" (
"id" bigint generated by default as identity not null,
"game_id" bigint,
"created_at" timestamp with time zone not null default now(),
"name" text not null,
"short_description" text not null default ''::text,
"markdown_description" text not null default ''::text,
"creator" uuid default auth.uid(),
"slug" text not null,
"public" boolean default false
);


alter table "public"."hacks" enable row level security;

CREATE UNIQUE INDEX hacks_pkey ON public.hacks USING btree (id);

CREATE UNIQUE INDEX hacks_slug_idx ON public.hacks USING btree (slug);

alter table "public"."hacks" add constraint "hacks_pkey" PRIMARY KEY using index "hacks_pkey";

alter table "public"."hacks" add constraint "hacks_creator_fkey" FOREIGN KEY (creator) REFERENCES auth.users(id) ON UPDATE CASCADE ON DELETE CASCADE not valid;

alter table "public"."hacks" validate constraint "hacks_creator_fkey";

alter table "public"."hacks" add constraint "hacks_game_id_fkey" FOREIGN KEY (game_id) REFERENCES games(id) ON UPDATE CASCADE ON DELETE CASCADE not valid;

alter table "public"."hacks" validate constraint "hacks_game_id_fkey";

grant delete on table "public"."hacks" to "anon";

grant insert on table "public"."hacks" to "anon";

grant references on table "public"."hacks" to "anon";

grant select on table "public"."hacks" to "anon";

grant trigger on table "public"."hacks" to "anon";

grant truncate on table "public"."hacks" to "anon";

grant update on table "public"."hacks" to "anon";

grant delete on table "public"."hacks" to "authenticated";

grant insert on table "public"."hacks" to "authenticated";

grant references on table "public"."hacks" to "authenticated";

grant select on table "public"."hacks" to "authenticated";

grant trigger on table "public"."hacks" to "authenticated";

grant truncate on table "public"."hacks" to "authenticated";

grant update on table "public"."hacks" to "authenticated";

grant delete on table "public"."hacks" to "service_role";

grant insert on table "public"."hacks" to "service_role";

grant references on table "public"."hacks" to "service_role";

grant select on table "public"."hacks" to "service_role";

grant trigger on table "public"."hacks" to "service_role";

grant truncate on table "public"."hacks" to "service_role";

grant update on table "public"."hacks" to "service_role";

create policy "Enable insert for authenticated users only"
on "public"."hacks"
as permissive
for insert
to authenticated
with check (true);


create policy "Enable read access for public hacks"
on "public"."hacks"
as permissive
for select
to public
using ((public = true));


create policy "Users can do anything with hacks they created"
on "public"."hacks"
as permissive
for all
to authenticated
using ((auth.uid() = creator));



5 changes: 5 additions & 0 deletions supabase/migrations/20240129172647_remote_schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
alter table "public"."hacks" alter column "game_id" set not null;

alter table "public"."hacks" alter column "public" set not null;


0 comments on commit cae4c20

Please sign in to comment.