diff --git a/docs/STORAGE_AVATARS_BUCKET.md b/docs/STORAGE_AVATARS_BUCKET.md new file mode 100644 index 0000000..5338a6c --- /dev/null +++ b/docs/STORAGE_AVATARS_BUCKET.md @@ -0,0 +1,41 @@ +# Create the `avatars` storage bucket + +If you see **"Bucket not found"** when saving a profile with an uploaded image, the `avatars` bucket does not exist yet. Create it once using one of the methods below. + +## Option 1: Supabase Dashboard (recommended) + +1. Open your project: **https://supabase.com/dashboard** (or your self‑hosted URL, e.g. `https://supa1.satoshinakamoto.win`). +2. Go to **Storage** in the left sidebar. +3. Click **New bucket**. +4. Set: + - **Name:** `avatars` (must be exactly this). + - **Public bucket:** **ON** (so avatar URLs work without signed links). + - **File size limit:** `2` MB (optional). + - **Allowed MIME types:** `image/jpeg`, `image/png`, `image/gif`, `image/webp` (optional). +5. Click **Create bucket**. + +Then add policies so users can upload only to their own folder and everyone can read: + +1. Open the **avatars** bucket. +2. Go to **Policies** (or **Storage** → **Policies**). +3. Add policies equivalent to the ones in `supabase/migrations/20250213200000_profiles_avatar_and_storage.sql` (from the line `-- RLS: allow authenticated users...` onward), or run that part of the migration in the SQL Editor. + +## Option 2: SQL Editor (if your Supabase allows it) + +Run in **SQL Editor**: + +```sql +INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types) +VALUES ( + 'avatars', + 'avatars', + true, + 2097152, + ARRAY['image/jpeg', 'image/png', 'image/gif', 'image/webp'] +) +ON CONFLICT (id) DO NOTHING; +``` + +If you get an error (e.g. column names or schema differ), use **Option 1** instead. + +After the bucket exists, run the **storage RLS policies** from `supabase/migrations/20250213200000_profiles_avatar_and_storage.sql` (the `CREATE POLICY` statements for `storage.objects`) so uploads and public read work correctly. diff --git a/index.html b/index.html index 41125d6..564a7ff 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + Omotomo diff --git a/omotomo.png b/omotomo.png new file mode 100644 index 0000000..330e6c1 Binary files /dev/null and b/omotomo.png differ diff --git a/public/omotomo.png b/public/omotomo.png new file mode 100644 index 0000000..330e6c1 Binary files /dev/null and b/public/omotomo.png differ diff --git a/src/App.svelte b/src/App.svelte index cb48c8d..fec0da5 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -6,14 +6,22 @@ import MyDecks from './routes/MyDecks.svelte'; import CreateDeck from './routes/CreateDeck.svelte'; import EditDeck from './routes/EditDeck.svelte'; + import DeckPreview from './routes/DeckPreview.svelte'; + import DeckReviews from './routes/DeckReviews.svelte'; import Community from './routes/Community.svelte'; + import CommunityUser from './routes/CommunityUser.svelte'; + import Settings from './routes/Settings.svelte'; import { auth } from './lib/stores/auth.js'; const routes = { '/': MyDecks, '/decks/new': CreateDeck, '/decks/:id/edit': EditDeck, + '/decks/:id/preview': DeckPreview, + '/decks/:id/reviews': DeckReviews, '/community': Community, + '/community/user/:id': CommunityUser, + '/settings': Settings, }; onMount(() => { diff --git a/src/app.css b/src/app.css index 0335fac..65238bc 100644 --- a/src/app.css +++ b/src/app.css @@ -19,6 +19,7 @@ --border-hover: #444; --hover-bg: #222; --accent: #3b82f6; + --navbar-height: 60px; } *, diff --git a/src/lib/AlertModal.svelte b/src/lib/AlertModal.svelte new file mode 100644 index 0000000..0f859ba --- /dev/null +++ b/src/lib/AlertModal.svelte @@ -0,0 +1,104 @@ + + +{#if open} + + +{/if} + + diff --git a/src/lib/ConfirmModal.svelte b/src/lib/ConfirmModal.svelte new file mode 100644 index 0000000..74cddc9 --- /dev/null +++ b/src/lib/ConfirmModal.svelte @@ -0,0 +1,149 @@ + + +{#if open} + + +{/if} + + diff --git a/src/lib/Navbar.svelte b/src/lib/Navbar.svelte index ec4bac3..1769b49 100644 --- a/src/lib/Navbar.svelte +++ b/src/lib/Navbar.svelte @@ -1,19 +1,26 @@ + +