Skip to content

Commit

Permalink
feat: ✨ adding sign up support for new users (#114)
Browse files Browse the repository at this point in the history
* feat: ✨ adding sign up support for new users

* fix: 🐛 fixed issue with sign up api

* feat: ✨ adding sign in feature for new users

* fix: 🐛 fixed lint issues

* fix: 🐛 fixed issue with google sign in

* fix: 🐛 fixed issue with lint workflow

* perf: 🔊 added debug logs

* perf: 🔊 added preview debug logs

* perf: 🔊 updated preview debug logs

* feat: ✨ handled redirects for different envs for login

* fix: 🐛 fixed issue with login on preview instance

* fix: 🐛 fixed issue when sign in feature is off
  • Loading branch information
WasiqB authored Feb 15, 2025
1 parent c483f22 commit 0fab18d
Show file tree
Hide file tree
Showing 31 changed files with 3,026 additions and 1,579 deletions.
15 changes: 15 additions & 0 deletions apps/web/app/(app)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use client';

import { signOut } from '@/app/utils/actions';
import { Button } from '@ultra-reporter/ui/components/button';

export default function DashboardPage() {
return (
<div className='container mx-auto py-8'>
<h1 className='text-3xl font-bold'>Dashboard</h1>
<Button onClick={signOut} variant='default' size='lg' className='mt-4'>
Sign Out
</Button>
</div>
);
}
46 changes: 46 additions & 0 deletions apps/web/app/(auth)/auth/callback/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { logger } from '@ultra-reporter/logger';
import { createClient } from '@ultra-reporter/supabase/server';
import { isPreview } from '@ultra-reporter/utils/constants';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url);
const code = searchParams.get('code');
const next = searchParams.get('next') ?? '/dashboard';

if (isPreview) {
logger.debug('====================');
logger.debug(`Route Received URL: ${request.url}`);
logger.debug(`Route Received searchParams: ${searchParams}`);
logger.debug(`Route Received code: ${code}`);
logger.debug(`Route Received next: ${next}`);
logger.debug(`Route Received origin: ${origin}`);
logger.debug('====================');
}

if (code) {
const supabase = await createClient();
const { error } = await supabase.auth.exchangeCodeForSession(code);
if (!error) {
const forwardedHost = request.headers.get('x-forwarded-host');
const isLocalEnv = process.env.NODE_ENV === 'development';
if (isPreview) {
logger.debug('====================');
logger.debug(`Route Received forwardedHost: ${forwardedHost}`);
logger.debug(`Route Received isLocalEnv: ${isLocalEnv}`);
logger.debug('====================');
}
if (isLocalEnv) {
// we can be sure that there is no load balancer in between, so no need to watch for X-Forwarded-Host
return NextResponse.redirect(`${origin}${next}`);
} else if (forwardedHost) {
return NextResponse.redirect(`https://${forwardedHost}${next}`);
} else {
return NextResponse.redirect(`${origin}${next}`);
}
}
}

// return the user to an error page with instructions
return NextResponse.redirect(`${origin}/auth/auth-code-error`);
}
14 changes: 14 additions & 0 deletions apps/web/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { NavBar } from '@ultra-reporter/ui/home/nav-bar';

export default function AuthLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<NavBar hideAuth={true} />
{children}
</>
);
}
65 changes: 65 additions & 0 deletions apps/web/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use client';

import { signinWithGoogle } from '@/app/utils/actions';
import { Button } from '@ultra-reporter/ui/components/button';
import { DemoCarousel } from '@ultra-reporter/ui/components/demo-carousel';
import { Icons } from '@ultra-reporter/ui/components/icons';

export default function AuthPage() {
return (
<div className='container mx-auto flex min-h-screen items-center justify-center'>
<div className='grid w-full items-center gap-8 lg:grid-cols-2'>
{/* Demo Carousel Section */}
<div className='relative hidden h-[600px] lg:block'>
<DemoCarousel />
</div>

{/* Auth Section */}
<div className='mx-auto w-full max-w-md space-y-8'>
<div className='space-y-2 text-center'>
<h1 className='text-3xl font-bold tracking-tight'>
Welcome to Ultra Reporter
</h1>
<p className='text-muted-foreground text-lg'>
Sign in to your account or create a new one
</p>
</div>

<div className='space-y-4'>
<Button
variant='default'
size='lg'
className='w-full py-6 text-lg'
onClick={signinWithGoogle}
>
<Icons.google className='mr-2 h-5 w-5' />
Continue with Google
</Button>

<div className='relative'>
<div className='absolute inset-0 flex items-center'>
<span className='w-full border-t' />
</div>
<div className='relative flex justify-center text-sm uppercase'>
<span className='bg-background text-muted-foreground px-2'>
Secure Authentication
</span>
</div>
</div>

<p className='text-muted-foreground text-center text-sm'>
By continuing, you agree to our{' '}
<a href='/terms' className='hover:text-primary underline'>
Terms of Service
</a>{' '}
and{' '}
<a href='/privacy' className='hover:text-primary underline'>
Privacy Policy
</a>
</p>
</div>
</div>
</div>
</div>
);
}
69 changes: 69 additions & 0 deletions apps/web/app/utils/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use server';

import { logger } from '@ultra-reporter/logger';
import { Provider } from '@ultra-reporter/supabase/client';
import { createClient } from '@ultra-reporter/supabase/server';
import { isPreview, isProd } from '@ultra-reporter/utils/constants';
import { headers } from 'next/headers';
import { redirect } from 'next/navigation';

const getURL = () => {
let url = isProd
? process?.env?.NEXT_PUBLIC_SITE_URL
: isPreview
? process?.env?.NEXT_PUBLIC_VERCEL_URL
: 'http://localhost:3000/';
// Make sure to include `https://` when not localhost.
url = url?.startsWith('http') ? url : `https://${url}`;
// Make sure to include a trailing `/`.
url = url.endsWith('/') ? url : `${url}/`;
return url;
};

const signInWith = (provider: Provider) => async () => {
const supabase = await createClient();
const requestHeaders = await headers();
const origin = getURL();

if (isPreview) {
logger.debug('====================');
logger.debug(`Actions Received provider: ${provider}`);
logger.debug(`Actions Received origin: ${origin}`);
requestHeaders.forEach((key, value) => {
logger.debug(`Actions Header [${key}]: [${value}]`);
});
logger.debug('====================');
}

const { data, error } = await supabase.auth.signInWithOAuth({
provider: provider,
options: {
redirectTo: `${origin}auth/callback`,
},
});

if (error) {
logger.error(`Error while signing in with ${provider}: ${error.message}`);
}
if (data?.url) {
if (isPreview) {
logger.debug(`Actions Redirecting to: ${data.url}`);
}
redirect(data.url);
}
};

const signinWithGoogle = signInWith('google');

const signOut = async () => {
const supabase = await createClient();
const { error } = await supabase.auth.signOut();

if (!error) {
redirect('/');
} else {
logger.error(`Error while signing out: ${error.message}`);
}
};

export { signinWithGoogle, signOut };
20 changes: 20 additions & 0 deletions apps/web/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { updateSession } from '@ultra-reporter/supabase/middleware';
import { type NextRequest } from 'next/server';

export async function middleware(request: NextRequest) {
return await updateSession(request);
}

export const config = {
matcher: [
/*
* Match all request paths except:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - images - .svg, .png, .jpg, .jpeg, .gif, .webp
* Feel free to modify this pattern to include more paths.
*/
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
};
16 changes: 9 additions & 7 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@
"react-dom": "^19.0"
},
"dependencies": {
"@next/third-parties": "^15.1.2",
"@tanstack/react-table": "^8.20.6",
"@next/third-parties": "^15.1.7",
"@tanstack/react-table": "^8.21.2",
"@ultra-reporter/analytics": "workspace:*",
"@ultra-reporter/feature-toggle": "workspace:*",
"@ultra-reporter/logger": "workspace:*",
"@ultra-reporter/supabase": "workspace:*",
"@ultra-reporter/ui": "workspace:*",
"@ultra-reporter/utils": "workspace:*",
"lucide-react": "^0.469.0",
"next": "15.1.2"
"lucide-react": "^0.475.0",
"next": "15.1.7"
},
"devDependencies": {
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"@ultra-reporter/typescript-config": "workspace:*",
"postcss": "^8.4.49",
"postcss": "^8.5.2",
"tailwindcss": "^3.4.17"
}
}
46 changes: 24 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,35 @@
"release:prepatch": "pnpm beta prepatch"
},
"devDependencies": {
"@eslint/compat": "^1.2.4",
"@next/eslint-plugin-next": "^15.1.2",
"@eslint/compat": "^1.2.6",
"@eslint/js": "^9.20.0",
"@next/eslint-plugin-next": "^15.1.7",
"@release-it-plugins/lerna-changelog": "^7.0.0",
"@stylistic/eslint-plugin-js": "^2.12.1",
"@stylistic/eslint-plugin-ts": "^2.12.1",
"@types/node": "^22.10.2",
"@typescript-eslint/eslint-plugin": "^8.18.1",
"@typescript-eslint/parser": "^8.18.1",
"@stylistic/eslint-plugin-js": "^3.1.0",
"@stylistic/eslint-plugin-ts": "^3.1.0",
"@types/node": "^22.13.4",
"@typescript-eslint/eslint-plugin": "^8.24.0",
"@typescript-eslint/parser": "^8.24.0",
"@vercel/style-guide": "^6.0.0",
"eslint": "^9.17.0",
"eslint-config-next": "15.1.2",
"eslint-config-prettier": "^9.1.0",
"eslint-config-turbo": "2.3.3",
"eslint": "^9.20.1",
"eslint-config-next": "15.1.7",
"eslint-config-prettier": "^10.0.1",
"eslint-config-turbo": "2.4.2",
"eslint-plugin-only-warn": "^1.1.0",
"eslint-plugin-prettier": "^5.2.1",
"globals": "^15.14.0",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-react": "^7.37.4",
"globals": "^15.15.0",
"husky": "^9.1.7",
"lerna-changelog": "^2.2.0",
"lint-staged": "^15.2.11",
"prettier": "^3.4.2",
"lint-staged": "^15.4.3",
"prettier": "^3.5.1",
"prettier-plugin-organize-imports": "^4.1.0",
"prettier-plugin-tailwindcss": "^0.6.9",
"release-it": "^17.10.0",
"release-it-pnpm": "^4.6.3",
"turbo": "^2.3.3",
"typescript": "^5.7.2",
"typescript-eslint": "^8.18.1"
"prettier-plugin-tailwindcss": "^0.6.11",
"release-it": "^18.1.2",
"release-it-pnpm": "^4.6.4",
"turbo": "^2.4.2",
"typescript": "^5.7.3",
"typescript-eslint": "^8.24.0"
},
"lint-staged": {
"**/*.{ts,tsx}": [
Expand All @@ -66,5 +68,5 @@
"engines": {
"node": ">=20"
},
"packageManager": "pnpm@9.15.0"
"packageManager": "pnpm@10.4.0"
}
4 changes: 2 additions & 2 deletions packages/analytics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
"dependencies": {
"@openpanel/nextjs": "^1.0.7",
"@ultra-reporter/utils": "workspace:*",
"@vercel/functions": "^1.5.2"
"@vercel/functions": "^2.0.0"
},
"devDependencies": {
"@types/react": "^19.0.2",
"@types/react": "^19.0.8",
"@ultra-reporter/logger": "workspace:*",
"@ultra-reporter/typescript-config": "workspace:*"
}
Expand Down
4 changes: 2 additions & 2 deletions packages/db/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
".": "./src/index.ts"
},
"dependencies": {
"@prisma/client": "^6.1.0"
"@prisma/client": "^6.3.1"
},
"devDependencies": {
"@ultra-reporter/typescript-config": "workspace:*",
"prisma": "^6.1.0"
"prisma": "^6.3.1"
}
}
Loading

0 comments on commit 0fab18d

Please sign in to comment.