Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ SAQ_BACKGROUND_WORKERS=1
SAQ_CONCURRENCY=1

# Frontend Configuration
VITE_USE_SERVER_LIFESPAN=True
VITE_HOT_RELOAD=True
VITE_DEV_MODE=True
VITE_HOST=localhost
VITE_PORT=3006
ALLOWED_CORS_ORIGINS=["localhost:3006","localhost:8080","localhost:8000"]
Expand All @@ -40,7 +43,7 @@ APP_SCRATCH_PATH=/tmp/app
# Email Configuration (SMTP)
EMAIL_ENABLED=true # Set to true to enable email sending
EMAIL_SMTP_HOST=localhost # For MailHog: localhost, for production: your SMTP host
EMAIL_SMTP_PORT=1025 # For MailHog: 1025, for production: 587 (TLS) or 465 (SSL)
EMAIL_SMTP_PORT=11025 # For MailHog: 11025, for production: 587 (TLS) or 465 (SSL)
EMAIL_SMTP_USER= # MailHog doesn't require auth, leave empty for dev
EMAIL_SMTP_PASSWORD= # MailHog doesn't require auth, leave empty for dev
EMAIL_USE_TLS=false # MailHog doesn't use TLS, set true for production
Expand Down
5 changes: 1 addition & 4 deletions src/js/src/components/auth/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,10 @@ export function UserLoginForm() {

const onSubmit = async (data: LoginFormData) => {
try {
// TODO: Fix/verify login
await login(data.email, data.password)
navigate({ to: "/home" })
} catch (error) {
form.setError("root", {
message: "Invalid credentials",
})
console.error("[DEBUG] Login error:", error)
}
}

Expand Down
17 changes: 11 additions & 6 deletions src/js/src/components/auth/signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useAuthStore } from "@/lib/auth"
import { zodResolver } from "@hookform/resolvers/zod"
import { useNavigate } from "@tanstack/react-router"
import { useForm } from "react-hook-form"
// import { toast } from "sonner"
import { z } from "zod"

const signupSchema = z
Expand Down Expand Up @@ -40,15 +41,19 @@ export function UserSignupForm() {

const onSubmit = async (data: SignupFormData) => {
try {
// TODO: verify registration
await accountRegister({
const response = await accountRegister({
body: { email: data.email, password: data.password, name: data.name },
})
// navigate({ to: "/login" });

if (response.status === 201) {
navigate({ to: "/login" })
return
}

// Getting status 500 for BE for validation errors. Not showing toast for now.
// toast.error(response.error?.title || "Signup failed")
} catch (error) {
form.setError("root", {
message: "Signup failed",
})
console.error("[DEBUG] Signup error:", error)
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/js/src/layouts/public-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { useTheme } from "@/lib/theme-context"
import { Outlet } from "@tanstack/react-router"
import { Toaster } from "sonner"

export function PublicLayout() {
const { theme } = useTheme()

return (
<div className="flex min-h-screen flex-col">
<Toaster richColors theme={theme} position="top-right" />
<main className="flex flex-1">
<Outlet />
</main>
Expand Down
26 changes: 18 additions & 8 deletions src/js/src/lib/auth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { accountLogin, accountLogout, accountProfile } from "@/lib/api/sdk.gen"
import type { Team, User } from "@/lib/api/types.gen"
import { toast } from "sonner"
import { create } from "zustand"
import { persist } from "zustand/middleware"

Expand Down Expand Up @@ -27,18 +28,27 @@ export const useAuthStore = create<AuthState>()(
login: async (email: string, password: string) => {
set({ isLoading: true })
try {
// First make the login request
await accountLogin({ body: { username: email, password } })
// Login request
const response = await accountLogin({ body: { username: email, password } })

// Add a small delay to ensure the cookie is set
await new Promise((resolve) => setTimeout(resolve, 100))
if (response.status === 201) {
// Add a small delay to ensure the cookie is set
await new Promise((resolve) => setTimeout(resolve, 100))

// Then verify the authentication by getting the profile
const { data: user } = await accountProfile()
set({ user, isAuthenticated: true })
// Verify the authentication by getting the profile
const { data: user } = await accountProfile()
// TODO: Maybe add a check for user here?
set({ user, isAuthenticated: true })
return
}

set({ user: null, currentTeam: null, isAuthenticated: false })
toast.error(response.error?.title || "Login failed")
} catch (error) {
set({ user: null, currentTeam: null, isAuthenticated: false })
throw error
toast.error("An error occurred", {
description: error instanceof Error ? error.message : "Unknown error",
})
} finally {
set({ isLoading: false })
}
Expand Down
6 changes: 3 additions & 3 deletions src/js/src/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1524,7 +1524,7 @@
"name": "sortOrder",
"in": "query",
"schema": {
"type": ["string", "null"],
"type": ["null", "string"],
"enum": ["asc", "desc", null],
"title": "Field to search",
"default": "desc"
Expand Down Expand Up @@ -1796,7 +1796,7 @@
"name": "sortOrder",
"in": "query",
"schema": {
"type": ["string", "null"],
"type": ["null", "string"],
"enum": ["asc", "desc", null],
"title": "Field to search",
"default": "asc"
Expand Down Expand Up @@ -3530,7 +3530,7 @@
"name": "sortOrder",
"in": "query",
"schema": {
"type": ["string", "null"],
"type": ["null", "string"],
"enum": ["asc", "desc", null],
"title": "Field to search",
"default": "desc"
Expand Down
12 changes: 6 additions & 6 deletions src/py/app/server/templates/emails/email_verification.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,18 @@
<div class="content">
<h2>Welcome{{ ' ' + user.name if user.name else '' }}!</h2>
<p>Thanks for signing up for {{ app_name }}. To complete your registration, please verify your email address by clicking the button below:</p>

<div style="text-align: center;">
<a href="{{ verification_url }}" class="button">Verify Email Address</a>
</div>

<p>Or copy and paste this URL into your browser:</p>
<div class="url-box">{{ verification_url }}</div>

<p><strong>This link will expire in {{ expires_in_hours }} hours.</strong></p>

<p>If you didn't create an account with {{ app_name }}, please ignore this email.</p>

<p>Need help? Contact our support team if you have any questions.</p>
</div>
<div class="footer">
Expand All @@ -93,4 +93,4 @@
</div>
</div>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ Best regards,
{{ app_name }} Team

--
This is an automated email. Please do not reply to this message.
This is an automated email. Please do not reply to this message.
14 changes: 7 additions & 7 deletions src/py/app/server/templates/emails/team_invitation.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,22 @@
</div>
<div class="content">
<h2>Join a team on {{ app_name }}</h2>

<p><strong>{{ inviter_name }}</strong> has invited you to join their team:</p>

<div class="team-info">
<div class="team-name">{{ team_name }}</div>
</div>

<p>By joining this team, you'll be able to collaborate with other team members, share resources, and work together on {{ app_name }}.</p>

<div style="text-align: center;">
<a href="{{ invitation_url }}" class="button">Accept Invitation</a>
</div>

<p>Or copy and paste this URL into your browser:</p>
<div class="url-box">{{ invitation_url }}</div>

<p>If you don't want to join this team or don't know {{ inviter_name }}, you can safely ignore this email.</p>
</div>
<div class="footer">
Expand All @@ -109,4 +109,4 @@
</div>
</div>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ If you don't want to join this team or don't know {{ inviter_name }}, you can sa

--
This invitation was sent to you by {{ inviter_name }}.
{{ app_name }}
{{ app_name }}
12 changes: 6 additions & 6 deletions src/py/app/server/templates/emails/welcome.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@
<div class="content">
<h2>Hi{{ ' ' + user.name if user.name else '' }}!</h2>
<p>Congratulations! Your email has been verified and your account is now fully activated.</p>

<p>You're all set to start using {{ app_name }}. Here's what you can do next:</p>

<div class="feature-list">
<ul>
<li>Complete your profile to personalize your experience</li>
Expand All @@ -88,13 +88,13 @@
<li>Start creating and collaborating</li>
</ul>
</div>

<div style="text-align: center;">
<a href="{{ login_url }}" class="button">Log In to Your Account</a>
</div>

<p>If you have any questions or need assistance, our support team is here to help!</p>

<p>Thanks for joining us,<br>
The {{ app_name }} Team</p>
</div>
Expand All @@ -104,4 +104,4 @@
</div>
</div>
</body>
</html>
</html>
2 changes: 1 addition & 1 deletion src/py/app/server/templates/emails/welcome.txt.j2
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ Thanks for joining us,
The {{ app_name }} Team

--
You're receiving this email because you recently created an account.
You're receiving this email because you recently created an account.
Loading
Loading