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
4 changes: 2 additions & 2 deletions apps/web/app/(authenticated)/projects/new/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ export default function NewProjectPage() {
className="flex flex-col overflow-hidden transition-colors hover:border-primary/50"
>
<CardHeader className="flex-1 pb-4">
<div className="flex items-start justify-between gap-4">
<div className="flex min-w-0 items-start justify-between gap-4">
<CardTitle
className="truncate text-base font-semibold"
className="min-w-0 flex-1 truncate text-base font-semibold"
title={repo.fullName}
>
{repo.name}
Expand Down
7 changes: 6 additions & 1 deletion apps/web/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ export default function RootLayout({
return (
<html lang="en" suppressHydrationWarning>
<body className={`${manrope.variable} font-sans antialiased`}>
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem>
<ThemeProvider
attribute="class"
defaultTheme="dark"
enableSystem={false}
themes={['light', 'dark']}
>
<SWRProvider>
<NavigationHistoryTracker />
{children}
Expand Down
42 changes: 38 additions & 4 deletions apps/web/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { toast } from 'sonner';
import { Loader2 } from 'lucide-react';

import { loginRequestSchema, type LoginRequest } from '@repo/contracts';
import {
loginRequestSchema,
type ExploreProjectResponse,
type LoginRequest,
} from '@repo/contracts';
import { AuthShell } from '@/components/auth-shell';
import { PasswordInput } from '@/components/password-input';
import { useAuth } from '@/hooks/use-auth';
Expand All @@ -25,6 +29,38 @@ const THUMB_GRADIENTS = [
'from-orange to-accent',
];

function ProjectThumbnail({
project,
index,
}: {
project: ExploreProjectResponse;
index: number;
}) {
const [imageFailed, setImageFailed] = useState(false);
const coverUrl = project.media[0]?.publicUrl;
const imageUrl = coverUrl ?? project.logoUrl;

return (
<div
className={`relative flex h-16 shrink-0 items-center justify-center overflow-hidden bg-gradient-to-br px-4 ${THUMB_GRADIENTS[index % THUMB_GRADIENTS.length]}`}
>
{imageUrl && !imageFailed && (
// eslint-disable-next-line @next/next/no-img-element
<img
src={imageUrl}
alt={`${project.title} preview`}
onError={() => setImageFailed(true)}
className={
coverUrl
? 'absolute inset-0 h-full w-full object-cover'
: 'h-10 w-10 rounded-md bg-white/90 object-contain p-1 shadow-sm'
}
/>
)}
</div>
);
}

// Component to handle fetching & randomizing projects
function RandomProjects() {
// Fetch up to 50 projects for a healthy randomization pool
Expand Down Expand Up @@ -80,9 +116,7 @@ function RandomProjects() {
className="block h-full"
>
<Card className="flex flex-col overflow-hidden py-0 border-white/10 shadow-[0_0_60px_-15px_rgba(47,120,238,0.15)] hover:border-primary/50 transition-colors h-full">
<div
className={`relative flex h-12 shrink-0 items-center bg-gradient-to-br px-4 ${THUMB_GRADIENTS[index % THUMB_GRADIENTS.length]}`}
/>
<ProjectThumbnail project={project} index={index} />

<div className="flex flex-1 flex-col gap-1.5 px-4 pt-3 pb-4">
<h4 className="text-sm font-semibold line-clamp-1">
Expand Down
23 changes: 17 additions & 6 deletions apps/web/components/onboarding-wizard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useState } from 'react';
import { useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useForm, Controller, type Path } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
Expand Down Expand Up @@ -92,6 +92,12 @@ export function OnboardingWizard({ user }: OnboardingWizardProps) {
user.developerProfile?.publicSlug,
)
: '';
const slugWasManuallyEdited = useRef(
Boolean(
user.developerProfile?.publicSlug &&
!user.developerProfile.publicSlug.startsWith('dev-'),
),
);

const {
register,
Expand Down Expand Up @@ -134,12 +140,20 @@ export function OnboardingWizard({ user }: OnboardingWizardProps) {
const name = e.target.value;
setValue('displayName', name, { shouldValidate: true });

if (isDev) {
if (isDev && !slugWasManuallyEdited.current) {
const generated = slugify(name);
setValue('publicSlug', generated, { shouldValidate: true });
}
};

const handlePublicSlugChange = (e: React.ChangeEvent<HTMLInputElement>) => {
slugWasManuallyEdited.current = true;
setValue('publicSlug', e.target.value, {
shouldDirty: true,
shouldValidate: true,
});
};

const handleNextStep = async (e?: React.MouseEvent) => {
e?.preventDefault();

Expand All @@ -151,11 +165,9 @@ export function OnboardingWizard({ user }: OnboardingWizardProps) {
? ['displayName', 'publicSlug']
: ['organizationName', 'organizationType'];

console.log('[DEBUG] Wizard - Validating Step 1:', fieldsToValidate);
const isValid = await trigger(fieldsToValidate);

if (!isValid) {
console.log('[DEBUG] Wizard - Validation failed on Step 1');
return;
}

Expand Down Expand Up @@ -202,7 +214,6 @@ export function OnboardingWizard({ user }: OnboardingWizardProps) {

const isStep2Valid = await trigger(step2Fields);
if (!isStep2Valid) {
console.log('[DEBUG] Wizard - Validation failed on Step 2 URLs/Fields');
return;
}

Expand All @@ -214,7 +225,6 @@ export function OnboardingWizard({ user }: OnboardingWizardProps) {
return;
}

console.log('[DEBUG] Wizard - Submission started...');
setIsSubmitting(true);
try {
await updateProfile(data);
Expand Down Expand Up @@ -294,6 +304,7 @@ export function OnboardingWizard({ user }: OnboardingWizardProps) {
className="rounded-l-none"
placeholder="jane-doe"
{...register('publicSlug')}
onChange={handlePublicSlugChange}
/>
</div>
{errors.publicSlug && (
Expand Down
6 changes: 1 addition & 5 deletions apps/web/components/theme-toggle.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import * as React from 'react';
import { Moon, Sun, Laptop } from 'lucide-react';
import { Moon, Sun } from 'lucide-react';
import { useTheme } from 'next-themes';
import { Button } from '@/components/ui/button';
import {
Expand Down Expand Up @@ -37,10 +37,6 @@ export function ThemeToggle() {
<Moon className="mr-2 h-4 w-4 text-blue-400" />
<span>Dark</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
<Laptop className="mr-2 h-4 w-4 text-muted-foreground" />
<span>System</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
Expand Down
Loading