mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 00:36:31 +02:00
refactor: update launch configurations and enhance HeroSection with Google login functionality
This commit is contained in:
parent
fabbae2b48
commit
73eeb555b2
2 changed files with 181 additions and 23 deletions
94
.vscode/launch.json
vendored
94
.vscode/launch.json
vendored
|
|
@ -5,7 +5,7 @@
|
|||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python Debugger: UV Run with Reload",
|
||||
"name": "Backend: FastAPI",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "uvicorn",
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
"python": "${command:python.interpreterPath}"
|
||||
},
|
||||
{
|
||||
"name": "Python Debugger: main.py (direct)",
|
||||
"name": "Backend: FastAPI (main.py)",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/surfsense_backend/main.py",
|
||||
|
|
@ -34,17 +34,95 @@
|
|||
"cwd": "${workspaceFolder}/surfsense_backend"
|
||||
},
|
||||
{
|
||||
"name": "Python Debugger: Chat DeepAgent",
|
||||
"name": "Frontend: Next.js",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}/surfsense_web",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run", "dev"],
|
||||
"console": "integratedTerminal",
|
||||
"serverReadyAction": {
|
||||
"pattern": "- Local:.+(https?://.+)",
|
||||
"uriFormat": "%s",
|
||||
"action": "debugWithChrome"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Frontend: Next.js (Server-Side Debug)",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}/surfsense_web",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run", "debug:server"],
|
||||
"console": "integratedTerminal",
|
||||
"serverReadyAction": {
|
||||
"pattern": "- Local:.+(https?://.+)",
|
||||
"uriFormat": "%s",
|
||||
"action": "debugWithChrome"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Celery: Worker",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "app.agents.new_chat.chat_deepagent",
|
||||
"module": "celery",
|
||||
"args": [
|
||||
"-A",
|
||||
"app.celery_app:celery_app",
|
||||
"worker",
|
||||
"--loglevel=info",
|
||||
"--pool=solo"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": false,
|
||||
"cwd": "${workspaceFolder}/surfsense_backend",
|
||||
"python": "${command:python.interpreterPath}",
|
||||
"env": {
|
||||
"PYTHONPATH": "${workspaceFolder}/surfsense_backend"
|
||||
"python": "${command:python.interpreterPath}"
|
||||
},
|
||||
{
|
||||
"name": "Celery: Beat Scheduler",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "celery",
|
||||
"args": [
|
||||
"-A",
|
||||
"app.celery_app:celery_app",
|
||||
"beat",
|
||||
"--loglevel=info"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": false,
|
||||
"cwd": "${workspaceFolder}/surfsense_backend",
|
||||
"python": "${command:python.interpreterPath}"
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Full Stack: Backend + Frontend + Celery",
|
||||
"configurations": [
|
||||
"Backend: FastAPI",
|
||||
"Frontend: Next.js",
|
||||
"Celery: Worker",
|
||||
"Celery: Beat Scheduler"
|
||||
],
|
||||
"stopAll": true,
|
||||
"presentation": {
|
||||
"hidden": false,
|
||||
"group": "Full Stack",
|
||||
"order": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Full Stack: Backend + Frontend",
|
||||
"configurations": [
|
||||
"Backend: FastAPI",
|
||||
"Frontend: Next.js"
|
||||
],
|
||||
"stopAll": true,
|
||||
"presentation": {
|
||||
"hidden": false,
|
||||
"group": "Full Stack",
|
||||
"order": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,29 @@ import Link from "next/link";
|
|||
import React, { useEffect, useRef, useState } from "react";
|
||||
import Balancer from "react-wrap-balancer";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { trackLoginAttempt } from "@/lib/posthog/events";
|
||||
|
||||
// Official Google "G" logo with brand colors
|
||||
const GoogleLogo = ({ className }: { className?: string }) => (
|
||||
<svg className={className} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
||||
fill="#4285F4"
|
||||
/>
|
||||
<path
|
||||
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
|
||||
fill="#34A853"
|
||||
/>
|
||||
<path
|
||||
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
|
||||
fill="#FBBC05"
|
||||
/>
|
||||
<path
|
||||
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
|
||||
fill="#EA4335"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export function HeroSection() {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
|
@ -60,7 +83,7 @@ export function HeroSection() {
|
|||
<h2 className="relative z-50 mx-auto mb-4 mt-4 max-w-4xl text-balance text-center text-3xl font-semibold tracking-tight text-gray-700 md:text-7xl dark:text-neutral-300">
|
||||
<Balancer>
|
||||
The AI Workspace{" "}
|
||||
<div className="relative mx-auto inline-block w-max [filter:drop-shadow(0px_1px_3px_rgba(27,_37,_80,_0.14))]">
|
||||
<div className="relative mx-auto inline-block w-max filter-[drop-shadow(0px_1px_3px_rgba(27,37,80,0.14))]">
|
||||
<div className="text-black [text-shadow:0_0_rgba(0,0,0,0.1)] dark:text-white">
|
||||
<span className="">Built for Teams</span>
|
||||
</div>
|
||||
|
|
@ -73,12 +96,7 @@ export function HeroSection() {
|
|||
your team.
|
||||
</p>
|
||||
<div className="mb-10 mt-8 flex w-full flex-col items-center justify-center gap-4 px-8 sm:flex-row md:mb-20">
|
||||
<Link
|
||||
href="/login"
|
||||
className="group relative z-20 flex h-10 w-full cursor-pointer items-center justify-center space-x-2 rounded-lg bg-black p-px px-4 py-2 text-center text-sm font-semibold leading-6 text-white no-underline transition duration-200 sm:w-52 dark:bg-white dark:text-black"
|
||||
>
|
||||
Get Started
|
||||
</Link>
|
||||
<GetStartedButton />
|
||||
{/* <Link
|
||||
href="/pricing"
|
||||
className="shadow-input group relative z-20 flex h-10 w-full cursor-pointer items-center justify-center space-x-2 rounded-lg bg-white p-px px-4 py-2 text-sm font-semibold leading-6 text-black no-underline transition duration-200 hover:-translate-y-0.5 sm:w-52 dark:bg-neutral-800 dark:text-white"
|
||||
|
|
@ -115,6 +133,68 @@ export function HeroSection() {
|
|||
);
|
||||
}
|
||||
|
||||
function GetStartedButton() {
|
||||
const isGoogleAuth = process.env.NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE === "GOOGLE";
|
||||
|
||||
const handleGoogleLogin = () => {
|
||||
trackLoginAttempt("google");
|
||||
window.location.href = `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/auth/google/authorize-redirect`;
|
||||
};
|
||||
|
||||
if (isGoogleAuth) {
|
||||
return (
|
||||
<motion.button
|
||||
type="button"
|
||||
onClick={handleGoogleLogin}
|
||||
whileHover="hover"
|
||||
whileTap={{ scale: 0.98 }}
|
||||
initial="idle"
|
||||
className="group relative z-20 flex h-11 w-full cursor-pointer items-center justify-center gap-3 overflow-hidden rounded-xl bg-white px-6 py-2.5 text-sm font-semibold text-neutral-700 shadow-lg ring-1 ring-neutral-200/50 transition-shadow duration-300 hover:shadow-xl sm:w-56 dark:bg-neutral-900 dark:text-neutral-200 dark:ring-neutral-700/50"
|
||||
variants={{
|
||||
idle: { scale: 1, y: 0 },
|
||||
hover: { scale: 1.02, y: -2 },
|
||||
}}
|
||||
>
|
||||
{/* Animated gradient background on hover */}
|
||||
<motion.div
|
||||
className="absolute inset-0 bg-linear-to-r from-blue-50 via-green-50 to-yellow-50 dark:from-blue-950/30 dark:via-green-950/30 dark:to-yellow-950/30"
|
||||
variants={{
|
||||
idle: { opacity: 0 },
|
||||
hover: { opacity: 1 },
|
||||
}}
|
||||
transition={{ duration: 0.3 }}
|
||||
/>
|
||||
{/* Google logo with subtle animation */}
|
||||
<motion.div
|
||||
className="relative"
|
||||
variants={{
|
||||
idle: { rotate: 0 },
|
||||
hover: { rotate: [0, -8, 8, 0] },
|
||||
}}
|
||||
transition={{ duration: 0.4, ease: "easeInOut" }}
|
||||
>
|
||||
<GoogleLogo className="h-5 w-5" />
|
||||
</motion.div>
|
||||
<span className="relative">Continue with Google</span>
|
||||
</motion.button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.02, y: -2 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
>
|
||||
<Link
|
||||
href="/login"
|
||||
className="group relative z-20 flex h-11 w-full cursor-pointer items-center justify-center gap-2 rounded-xl bg-black px-6 py-2.5 text-sm font-semibold text-white shadow-lg transition-shadow duration-300 hover:shadow-xl sm:w-56 dark:bg-white dark:text-black"
|
||||
>
|
||||
Get Started
|
||||
</Link>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
const BackgroundGrids = () => {
|
||||
return (
|
||||
<div className="pointer-events-none absolute inset-0 z-0 grid h-full w-full -rotate-45 transform select-none grid-cols-2 gap-10 md:grid-cols-4">
|
||||
|
|
@ -126,7 +206,7 @@ const BackgroundGrids = () => {
|
|||
<GridLineVertical className="left-0" />
|
||||
<GridLineVertical className="left-auto right-0" />
|
||||
</div>
|
||||
<div className="relative h-full w-full bg-gradient-to-b from-transparent via-neutral-100 to-transparent dark:via-neutral-800">
|
||||
<div className="relative h-full w-full bg-linear-to-b from-transparent via-neutral-100 to-transparent dark:via-neutral-800">
|
||||
<GridLineVertical className="left-0" />
|
||||
<GridLineVertical className="left-auto right-0" />
|
||||
</div>
|
||||
|
|
@ -237,7 +317,7 @@ const CollisionMechanism = React.forwardRef<
|
|||
repeatDelay: beamOptions.repeatDelay || 0,
|
||||
}}
|
||||
className={cn(
|
||||
"absolute left-96 top-20 m-auto h-14 w-px rounded-full bg-gradient-to-t from-orange-500 via-yellow-500 to-transparent",
|
||||
"absolute left-96 top-20 m-auto h-14 w-px rounded-full bg-linear-to-t from-orange-500 via-yellow-500 to-transparent",
|
||||
beamOptions.className
|
||||
)}
|
||||
/>
|
||||
|
|
@ -276,7 +356,7 @@ const Explosion = ({ ...props }: React.HTMLProps<HTMLDivElement>) => {
|
|||
animate={{ opacity: [0, 1, 0] }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 1, ease: "easeOut" }}
|
||||
className="absolute -inset-x-10 top-0 m-auto h-[4px] w-10 rounded-full bg-gradient-to-r from-transparent via-orange-500 to-transparent blur-sm"
|
||||
className="absolute -inset-x-10 top-0 m-auto h-[4px] w-10 rounded-full bg-linear-to-r from-transparent via-orange-500 to-transparent blur-sm"
|
||||
></motion.div>
|
||||
{spans.map((span) => (
|
||||
<motion.span
|
||||
|
|
@ -284,7 +364,7 @@ const Explosion = ({ ...props }: React.HTMLProps<HTMLDivElement>) => {
|
|||
initial={{ x: span.initialX, y: span.initialY, opacity: 1 }}
|
||||
animate={{ x: span.directionX, y: span.directionY, opacity: 0 }}
|
||||
transition={{ duration: Math.random() * 1.5 + 0.5, ease: "easeOut" }}
|
||||
className="absolute h-1 w-1 rounded-full bg-gradient-to-b from-orange-500 to-yellow-500"
|
||||
className="absolute h-1 w-1 rounded-full bg-linear-to-b from-orange-500 to-yellow-500"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -307,11 +387,11 @@ const GridLineVertical = ({ className, offset }: { className?: string; offset?:
|
|||
} as React.CSSProperties
|
||||
}
|
||||
className={cn(
|
||||
"absolute top-[calc(var(--offset)/2*-1)] h-[calc(100%+var(--offset))] w-[var(--width)]",
|
||||
"absolute top-[calc(var(--offset)/2*-1)] h-[calc(100%+var(--offset))] w-(--width)",
|
||||
"bg-[linear-gradient(to_bottom,var(--color),var(--color)_50%,transparent_0,transparent)]",
|
||||
"[background-size:var(--width)_var(--height)]",
|
||||
"[mask:linear-gradient(to_top,var(--background)_var(--fade-stop),transparent),_linear-gradient(to_bottom,var(--background)_var(--fade-stop),transparent),_linear-gradient(black,black)]",
|
||||
"[mask-composite:exclude]",
|
||||
"bg-size-[var(--width)_var(--height)]",
|
||||
"[mask:linear-gradient(to_top,var(--background)_var(--fade-stop),transparent),linear-gradient(to_bottom,var(--background)_var(--fade-stop),transparent),linear-gradient(black,black)]",
|
||||
"mask-exclude",
|
||||
"z-30",
|
||||
"dark:bg-[linear-gradient(to_bottom,var(--color-dark),var(--color-dark)_50%,transparent_0,transparent)]",
|
||||
className
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue