diff --git a/.env.example b/.env.example index 244e8f7f..6ab5aa22 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1 @@ -VITE_CLERK_PUBLISHABLE_KEY=pk_test_123 - -VITE_CLERK_SIGN_IN_URL=/sign_in -VITE_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/dashboard -VITE_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/dashboard \ No newline at end of file +VITE_CLERK_PUBLISHABLE_KEY=pk_test_123 \ No newline at end of file diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index b890ab03..bd4dd68e 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class SessionsController < InertiaController - skip_before_action :authenticate_user!, only: %i[ new ] + skip_before_action :authenticate_user!, only: %i[ new sign_up ] def new if user_signed_in? @@ -10,6 +10,13 @@ def new end end + def sign_up + if user_signed_in? + flash[:notice] = "You are already signed in" + redirect_to root_path + end + end + def switch # renders the account selector page end diff --git a/app/frontend/pages/sessions/sign_up.tsx b/app/frontend/pages/sessions/sign_up.tsx new file mode 100644 index 00000000..a4517d20 --- /dev/null +++ b/app/frontend/pages/sessions/sign_up.tsx @@ -0,0 +1,65 @@ +import { SignUp, useAuth } from "@clerk/clerk-react" +import { Head, router } from "@inertiajs/react" +import { useEffect } from "react" + +import AuthLayout from "@/layouts/auth-layout" + +export default function SignUpPage() { + const { getToken, isSignedIn } = useAuth() + + useEffect(() => { + const createSession = async () => { + if (isSignedIn) { + try { + const token = await getToken() + if (token) { + // Post the clerk token to our backend to create a session + await fetch("/sign_up", { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-CSRF-Token": + document + .querySelector('meta[name="csrf-token"]') + ?.getAttribute("content") ?? "", + }, + body: JSON.stringify({ clerk_token: token }), + }) + + // Redirect after successful session creation + router.visit("/dashboard") + } + } catch (error) { + console.error("Failed to create session:", error) + } + } + } + + void createSession() + }, [isSignedIn, getToken]) + + return ( + + + +
+ +
+ +
+ By clicking continue, you agree to our{" "} + + Terms of Service + {" "} + and{" "} + + Privacy Policy + + . +
+
+ ) +} diff --git a/app/frontend/routes/index.d.ts b/app/frontend/routes/index.d.ts index f038100d..fbce062e 100644 --- a/app/frontend/routes/index.d.ts +++ b/app/frontend/routes/index.d.ts @@ -1,6 +1,6 @@ /** - * @file Generated by js-routes 2.3.5. Based on Rails 8.0.2 routes of InertiaRailsShadcnStarter::Application. - * @version 8768cfd61fbd4e0dcca2080f637cacf221d79cdb73f8a56ffaa8cbaa3268a4fe + * @file Generated by js-routes 2.3.5. Based on Rails 8.0.2.1 routes of InertiaRailsShadcnStarter::Application. + * @version 06c66b0089ef8669a19a912743babeb60c949a23bf292fe7b05b04587232096c * @see https://github.com/railsware/js-routes */ declare type Optional = { @@ -406,6 +406,16 @@ export const signInPath: (( options?: {format?: OptionalRouteParameter} & RouteOptions ) => string) & RouteHelperExtras; +/** + * Generates rails route to + * /sign_up(.:format) + * @param {object | undefined} options + * @returns {string} route path + */ +export const signUpPath: (( + options?: {format?: OptionalRouteParameter} & RouteOptions +) => string) & RouteHelperExtras; + /** * Generates rails route to * /switch(.:format) diff --git a/app/frontend/routes/index.js b/app/frontend/routes/index.js index 19b689bd..f8482165 100644 --- a/app/frontend/routes/index.js +++ b/app/frontend/routes/index.js @@ -1,6 +1,6 @@ /** - * @file Generated by js-routes 2.3.5. Based on Rails 8.0.2 routes of InertiaRailsShadcnStarter::Application. - * @version 8768cfd61fbd4e0dcca2080f637cacf221d79cdb73f8a56ffaa8cbaa3268a4fe + * @file Generated by js-routes 2.3.5. Based on Rails 8.0.2.1 routes of InertiaRailsShadcnStarter::Application. + * @version 06c66b0089ef8669a19a912743babeb60c949a23bf292fe7b05b04587232096c * @see https://github.com/railsware/js-routes */ // eslint-disable-next-line @@ -792,6 +792,14 @@ export const settingsAppearancePath = /*#__PURE__*/ __jsr.r({"format":{}}, [2,[7 */ export const signInPath = /*#__PURE__*/ __jsr.r({"format":{}}, [2,[7,"/"],[2,[6,"sign_in"],[1,[2,[8,"."],[3,"format"]]]]]); +/** + * Generates rails route to + * /sign_up(.:format) + * @param {object | undefined} options + * @returns {string} route path + */ +export const signUpPath = /*#__PURE__*/ __jsr.r({"format":{}}, [2,[7,"/"],[2,[6,"sign_up"],[1,[2,[8,"."],[3,"format"]]]]]); + /** * Generates rails route to * /switch(.:format) diff --git a/config/routes.rb b/config/routes.rb index 48dd9302..5a7e33a2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,7 @@ Rails.application.routes.draw do get "sign_in", to: "sessions#new", as: :sign_in + get "sign_up", to: "sessions#sign_up", as: :sign_up get "switch", to: "sessions#switch", as: :switch_account # Clerk webhook endpoint diff --git a/spec/requests/sessions_spec.rb b/spec/requests/sessions_spec.rb index c259ef68..814b5ac1 100644 --- a/spec/requests/sessions_spec.rb +++ b/spec/requests/sessions_spec.rb @@ -24,6 +24,25 @@ end end + describe "GET /sign_up" do + context "when user is not signed in" do + it "returns http success" do + get sign_up_url + expect(response).to have_http_status(:success) + end + end + + context "when user is already signed in" do + before { sign_in_as user } + + it "redirects to root with notice" do + get sign_up_url + expect(response).to redirect_to(root_path) + expect(flash[:notice]).to eq("You are already signed in") + end + end + end + describe "GET /switch" do context "when user is signed in" do before { sign_in_as user }