diff --git a/.gitignore b/.gitignore index 3b462cb..db089f3 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ Thumbs.db # Vite vite.config.js.timestamp-* vite.config.ts.timestamp-* + +# Ruby +backend/vendor/bundle +backend/.bundle diff --git a/README.md b/README.md index 75842c4..463c17c 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,4 @@ -# sv +everything stickers by Nora and Euan +Ruby with Grape + Svelte -Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). - -## Creating a project - -If you're seeing this, you've probably already done this step. Congrats! - -```sh -# create a new project in the current directory -npx sv create - -# create a new project in my-app -npx sv create my-app -``` - -## Developing - -Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: - -```sh -npm run dev - -# or start the server and open the app in a new browser tab -npm run dev -- --open -``` - -## Building - -To create a production version of your app: - -```sh -npm run build -``` - -You can preview the production build with `npm run preview`. - -> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. +npm run dev \ No newline at end of file diff --git a/backend/.env.example b/backend/.env.example index b66a670..0c7c7a3 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,5 +1,5 @@ -AIRTABLE_PAT=dummy -AIRTABLE_BASE=dummy +AIRTABLE_API_KEY=dummy +AIRTABLE_BASE_ID=dummy SESSION_SECRET=dummy OIDC_ISSUER=dummy OIDC_CLIENT_ID=dummy diff --git a/backend/Gemfile b/backend/Gemfile index 40b8c5e..8a83c17 100644 --- a/backend/Gemfile +++ b/backend/Gemfile @@ -21,3 +21,4 @@ gem 'rack', '~> 3.2' gem 'omniauth' gem 'omniauth_openid_connect' gem 'rack-session' +gem 'rack-cors' diff --git a/backend/Gemfile.lock b/backend/Gemfile.lock index fc33ae1..ce15d3d 100644 --- a/backend/Gemfile.lock +++ b/backend/Gemfile.lock @@ -140,6 +140,9 @@ GEM puma (7.1.0) nio4r (~> 2.0) rack (3.2.4) + rack-cors (3.0.0) + logger + rack (>= 3.0.14) rack-oauth2 (2.3.0) activesupport attr_required @@ -188,6 +191,7 @@ DEPENDENCIES omniauth_openid_connect puma (~> 7.1) rack (~> 3.2) + rack-cors rack-session rackup zeitwerk (~> 2.6) diff --git a/backend/api/airtable_data.rb b/backend/api/airtable_data.rb new file mode 100644 index 0000000..906c778 --- /dev/null +++ b/backend/api/airtable_data.rb @@ -0,0 +1,23 @@ +class StickersTable < AirctiveRecord::Base + self.base_key = ENV['AIRTABLE_BASE_ID'] + self.table_name = "stickerDB" +end + +class AirtableData < Grape::API + format :json + + helpers do + def airtable_client + StickersTable + end + end + + get '/data' do + records = airtable_client.all + records.map(&:fields) + end + + post '/data' do + airtable_client.create(params[:fields]) + end +end diff --git a/backend/api/app.rb b/backend/api/app.rb index 696b505..ba724d8 100644 --- a/backend/api/app.rb +++ b/backend/api/app.rb @@ -2,7 +2,7 @@ class App < Grape::API format :json - + mount AirtableData mount Auth mount Stickers end diff --git a/backend/api/stickers.rb b/backend/api/stickers.rb index c02b19f..d52f746 100644 --- a/backend/api/stickers.rb +++ b/backend/api/stickers.rb @@ -5,20 +5,29 @@ class Stickers < Base resource :stickers do get do - Sticker.only_active.all.map(&:as_json) + [current_user: current_user] - end - - before do - @sticker = Sticker.only_active.where(autonumber: params[:id]).first || error!('not found', 404) + records = StickersTable.all + records.map do |record| + { + id: record.id, + name: record["Sticker Name"], + image: record["CDNURL"], + artist: record["Artist"], + event: record["Event"] + } + end end route_param :id, type: String do - before { authenticate! } get do - @sticker.as_json - end - get '/backwards' do - @sticker.name.reverse + record = StickersTable.find(params[:id]) + error!('not found', 404) unless record + { + id: record.id, + name: record["Sticker Name"], + image: record["CDNURL"], + artist: record["Artist"], + event: record["Event"] + } end end end diff --git a/backend/boot.rb b/backend/boot.rb index e5429f6..6a884bf 100644 --- a/backend/boot.rb +++ b/backend/boot.rb @@ -9,7 +9,7 @@ require 'grape' Dotenv.load -Norairrecord.api_key = ENV['AIRTABLE_PAT'] +Norairrecord.api_key = ENV['AIRTABLE_API_KEY'] loader = Zeitwerk::Loader.new loader.push_dir("#{__dir__}/models") diff --git a/backend/config.ru b/backend/config.ru index 3878ebd..7442b8a 100644 --- a/backend/config.ru +++ b/backend/config.ru @@ -8,6 +8,14 @@ require 'grape' require 'rack/session' require 'omniauth' require 'omniauth_openid_connect' +require 'rack/cors' + +use Rack::Cors do + allow do + origins 'http://localhost:5173', 'http://localhost:4173' + resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options] + end +end use Rack::Session::Cookie, key: 'stickers.session', diff --git a/backend/models/application_record.rb b/backend/models/application_record.rb index c8efe69..5b1f454 100644 --- a/backend/models/application_record.rb +++ b/backend/models/application_record.rb @@ -1,3 +1,3 @@ class ApplicationRecord < AirctiveRecord::Base - self.base_key = ENV['AIRTABLE_BASE'] + self.base_key = ENV['AIRTABLE_BASE_ID'] end diff --git a/src/routes/dash/+page.svelte b/src/routes/dash/+page.svelte index a31c2bc..2d5d776 100644 --- a/src/routes/dash/+page.svelte +++ b/src/routes/dash/+page.svelte @@ -2,6 +2,12 @@ import Peelable from '$lib/components/Peelable.svelte'; import stickersBg from '$lib/assets/images/stickers.jpg'; + let showClaimModal = $state(false); + let requiredFingers = $state(Math.floor(Math.random() * 5) + 1); + let uploadedFile = $state(null); + let previewUrl = $state(null); + let isDragging = $state(false); + function goToTrade() { window.location.href = '/trade'; } @@ -13,8 +19,125 @@ function goToVote() { window.location.href = '/vote'; } + + function openClaimModal() { + requiredFingers = Math.floor(Math.random() * 5) + 1; + showClaimModal = true; + } + + function closeClaimModal() { + showClaimModal = false; + clearFile(); + } + + function handleFileSelect(event) { + const input = event.target; + if (input.files && input.files[0]) { + setFile(input.files[0]); + } + } + + function handleDrop(event) { + event.preventDefault(); + isDragging = false; + if (event.dataTransfer?.files && event.dataTransfer.files[0]) { + setFile(event.dataTransfer.files[0]); + } + } + + function handleDragOver(event) { + event.preventDefault(); + isDragging = true; + } + + function handleDragLeave() { + isDragging = false; + } + + function setFile(file) { + if (file.type.startsWith('image/')) { + uploadedFile = file; + previewUrl = URL.createObjectURL(file); + } + } + + function clearFile() { + if (previewUrl) { + URL.revokeObjectURL(previewUrl); + } + uploadedFile = null; + previewUrl = null; + } + + function submitClaim() { + if (!uploadedFile) return; + alert('Claim submitted for verification!'); + closeClaimModal(); + } +{#if showClaimModal} +
+{/if} +