Skip to content

Commit

Permalink
Add create project steps (#384)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kitenite authored Sep 19, 2024
1 parent ce26e5a commit 9f1096c
Show file tree
Hide file tree
Showing 23 changed files with 992 additions and 464 deletions.
Binary file modified app/bun.lockb
Binary file not shown.
32 changes: 32 additions & 0 deletions app/common/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,35 @@ export function isOnlookInDoc(doc: Document): boolean {
).booleanValue;
return attributeExists;
}

export function timeSince(date: Date): string {
if (!(date instanceof Date) || isNaN(date.getTime())) {
console.error('Invalid date provided');
return 'Invalid date';
}

const now = new Date();
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
let interval = seconds / 31536000;

if (interval > 1) {
return Math.floor(interval) + 'y';
}
interval = seconds / 2592000;
if (interval > 1) {
return Math.floor(interval) + 'm';
}
interval = seconds / 86400;
if (interval > 1) {
return Math.floor(interval) + 'd';
}
interval = seconds / 3600;
if (interval > 1) {
return Math.floor(interval) + 'h';
}
interval = seconds / 60;
if (interval > 1) {
return Math.floor(interval) + 'm';
}
return Math.floor(seconds) + 's';
}
1 change: 1 addition & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-progress": "^1.1.0",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
Expand Down
23 changes: 23 additions & 0 deletions app/src/components/ui/progress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as React from 'react';
import * as ProgressPrimitive from '@radix-ui/react-progress';

import { cn } from '@/lib/utils';

const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn('relative h-2 w-full overflow-hidden rounded-full bg-primary/20', className)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
));
Progress.displayName = ProgressPrimitive.Root.displayName;

export { Progress };
66 changes: 66 additions & 0 deletions app/src/routes/projects/ProjectsTab/Create/ChooseMethod.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Card } from '@/components/ui/card';
import { DownloadIcon, FilePlusIcon } from '@radix-ui/react-icons';
import { CreateMethod } from '../..';

export const ChooseMethod = ({
setCreateMethod,
}: {
setCreateMethod: (method: CreateMethod | null) => void;
}) => {
const MESSAGES = [
"Ready to make some good lookin' apps",
"What a week... right? Doesn't matter, let's build!",
"These apps aren't gunna design themselves",
'Time to unleash your inner designer',
'Release your inner artist today',
"Let's craft some beautiful UIs!",
"*crackles knuckles* Let's get building!",
'Another day another design',
"Can't wait to see what you create!",
"Let's design something fresh today",
"Let's get to work",
"What time is it? It's time to build!",
"ಠ_ಠ Why aren't you designing? ಠ_ಠ",
];

const OPENING_MESSAGE = MESSAGES[Math.floor(Math.random() * MESSAGES.length)];

return (
<div className="flex flex-col w-[40rem] gap-20 mt-40">
<div className="gap-5 flex flex-col">
<h1 className="text-title1 text-text-active leading-none">{'Projects'}</h1>
<p className="text-text text-regular">{OPENING_MESSAGE}</p>
</div>
<div className="flex flex-row w-full gap-8">
<Card
className="w-full border border-blue-800 bg-blue-900/50 hover:bg-blue-900 hover:border-blue-600 hover:cursor-pointer flex flex-col items-center justify-center space-y-2 p-8 transition"
onClick={() => {
setCreateMethod(CreateMethod.NEW);
}}
>
<div className="rounded-full p-2 bg-blue-500">
<FilePlusIcon className="w-4 h-4 text-blue-100" />
</div>
<h3 className="text-regular font-medium pt-2 text-blue-100">
{'New Onlook project'}
</h3>
<p className="text-small text-blue-200"> {'Start a React App'} </p>
</Card>
<Card
className="w-full border border-teal-800 bg-teal-1000 hover:bg-teal-800 hover:border-teal-600 hover:cursor-pointer flex flex-col items-center justify-center space-y-2 p-8 transition"
onClick={() => {
setCreateMethod(CreateMethod.LOAD);
}}
>
<div className="rounded-full p-2 bg-teal-500">
<DownloadIcon className="w-4 h-4 text-teal-100" />
</div>
<h3 className="text-regular font-medium text-teal-100 pt-2">
{'Import existing project'}
</h3>
<p className="text-small text-teal-200">{'Work on your React UI'}</p>
</Card>
</div>
</div>
);
};
84 changes: 84 additions & 0 deletions app/src/routes/projects/ProjectsTab/Create/Load/SelectFolder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { MinusCircledIcon } from '@radix-ui/react-icons';
import { useState } from 'react';
import { StepProps } from '..';
import { MainChannels } from '/common/constants';

export const LoadSelectFolder = ({
props: { currentStep, totalSteps, prevStep, nextStep },
}: {
props: StepProps;
}) => {
const [projectName, setProjectName] = useState<string | null>(null);
const [projectPath, setProjectPath] = useState<string | null>(null);

async function pickProjectFolder() {
const path = (await window.api.invoke(MainChannels.PICK_COMPONENTS_DIRECTORY)) as
| string
| null;

if (path == null) {
return;
}
setProjectName('Project Name');
setProjectPath('/path/to/project');
}

return (
<Card className="w-[30rem]">
<CardHeader>
<CardTitle>{'Select your project folder'}</CardTitle>
<CardDescription>{'This is where we’ll reference your App'}</CardDescription>
</CardHeader>
<CardContent className="h-24 flex items-center w-full">
{projectPath ? (
<div className="w-full flex flex-row items-center border p-4 rounded">
<div className="flex flex-col text-sm">
<p>{projectName}</p>
<p>{projectPath}</p>
</div>
<Button
className="ml-auto"
variant={'ghost'}
size={'icon'}
onClick={() => {
setProjectPath(null);
setProjectName(null);
}}
>
<MinusCircledIcon />
</Button>
</div>
) : (
<Button className="w-full h-12" variant={'outline'} onClick={pickProjectFolder}>
{'Click to select your folder'}
</Button>
)}
</CardContent>
<CardFooter className="text-sm">
<p>{`${currentStep + 1} of ${totalSteps}`}</p>
<div className="flex ml-auto gap-2">
<Button type="button" onClick={prevStep} variant="ghost">
Back
</Button>
<Button
disabled={!projectPath}
type="button"
onClick={nextStep}
variant="outline"
>
Next
</Button>
</div>
</CardFooter>
</Card>
);
};
57 changes: 57 additions & 0 deletions app/src/routes/projects/ProjectsTab/Create/Load/SetUrl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useState } from 'react';
import { StepProps } from '..';

export const LoadSetUrl = ({
props: { currentStep, totalSteps, prevStep, nextStep },
}: {
props: StepProps;
}) => {
const [projectUrl, setProjectUrl] = useState<string>('http://localhost:3000');

return (
<Card className="w-[30rem]">
<CardHeader>
<CardTitle>{'Set your project URL'}</CardTitle>
<CardDescription>{'Where is your project running locally?'}</CardDescription>
</CardHeader>
<CardContent className="h-24 flex items-center w-full">
<div className="flex flex-col w-full gap-2">
<Label htmlFor="text">Local Url</Label>
<Input
value={projectUrl}
type="text"
placeholder="http://localhost:3000"
onInput={(e) => setProjectUrl(e.currentTarget.value)}
/>
</div>
</CardContent>
<CardFooter className="text-sm">
<p>{`${currentStep + 1} of ${totalSteps}`}</p>
<div className="flex ml-auto gap-2">
<Button type="button" onClick={prevStep} variant="ghost">
Back
</Button>
<Button
disabled={!projectUrl || projectUrl.length === 0}
type="button"
onClick={nextStep}
variant="outline"
>
Complete setup
</Button>
</div>
</CardFooter>
</Card>
);
};
77 changes: 77 additions & 0 deletions app/src/routes/projects/ProjectsTab/Create/Load/Verify.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { CheckCircledIcon, ExclamationTriangleIcon } from '@radix-ui/react-icons';
import clsx from 'clsx';
import { useState } from 'react';
import { StepProps } from '..';

export const LoadVerifyProject = ({
props: { currentStep, totalSteps, prevStep, nextStep },
}: {
props: StepProps;
}) => {
const [isInstalled, setIsInstalled] = useState<boolean | null>(null);

async function installOnlook() {
setIsInstalled(true);
}

return (
<Card className="w-[30rem]">
<CardHeader>
<CardTitle>
{isInstalled ? 'Onlook is installed' : 'Onlook is not installed'}
</CardTitle>
<CardDescription>
{isInstalled
? 'Your project is all set up'
: 'It takes one second to install Onlook on your project'}
</CardDescription>
</CardHeader>
<CardContent className="h-24 flex items-center w-full">
<div
className={clsx(
'w-full flex flex-row items-center border p-4 rounded',
isInstalled
? 'border-green-600 text-green-600 bg-green-100'
: 'border-yellow-700 text-yellow-700 bg-yellow-100',
)}
>
<div className={'flex flex-col text-sm'}>
<p>{'projectName'}</p>
<p>{'projectPath'}</p>
</div>
{isInstalled ? (
<CheckCircledIcon className="ml-auto" />
) : (
<ExclamationTriangleIcon className="ml-auto" />
)}
</div>
</CardContent>
<CardFooter className="text-sm">
<p>{`${currentStep + 1} of ${totalSteps}`}</p>
<div className="flex ml-auto gap-2">
<Button type="button" onClick={prevStep} variant="ghost">
Select a different folder
</Button>
{isInstalled ? (
<Button variant={'outline'} onClick={nextStep}>
{'Next'}
</Button>
) : (
<Button variant={'outline'} onClick={installOnlook}>
{'Install Onlook'}
</Button>
)}
</div>
</CardFooter>
</Card>
);
};
43 changes: 0 additions & 43 deletions app/src/routes/projects/ProjectsTab/Create/LoadProject.tsx

This file was deleted.

Loading

0 comments on commit 9f1096c

Please sign in to comment.