Skip to content

Commit

Permalink
Working auth with new UI (#372)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kitenite authored Sep 17, 2024
1 parent 4bca046 commit 48c0417
Show file tree
Hide file tree
Showing 14 changed files with 89 additions and 89 deletions.
3 changes: 3 additions & 0 deletions app/common/supabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { createClient } from '@supabase/supabase-js';
let supabase: ReturnType<typeof createClient> | undefined;

try {
if (!import.meta.env.VITE_SUPABASE_API_URL || !import.meta.env.VITE_SUPABASE_ANON_KEY) {
throw new Error('Supabase environment variables not set, running in offline mode');
}
supabase = createClient(
import.meta.env.VITE_SUPABASE_API_URL || '',
import.meta.env.VITE_SUPABASE_ANON_KEY || '',
Expand Down
46 changes: 37 additions & 9 deletions app/electron/main/analytics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,29 @@ import * as Mixpanel from 'mixpanel';
import { nanoid } from 'nanoid';
import { PersistenStorage } from '../storage';
import { MainChannels } from '/common/constants';
import { UserMetadata } from '/common/models/settings';

export function sendAnalytics(event: string, data?: Record<string, any>) {
ipcMain.emit(MainChannels.SEND_ANALYTICS, '', { event, data });
}

class Analytics {
mixpanel: ReturnType<typeof Mixpanel.init> | undefined;
id: string | undefined;
private static instance: Analytics;
private mixpanel: ReturnType<typeof Mixpanel.init> | undefined;
private id: string | undefined;

constructor() {
private constructor() {
this.restoreSettings();
}

restoreSettings() {
public static getInstance(): Analytics {
if (!Analytics.instance) {
Analytics.instance = new Analytics();
}
return Analytics.instance;
}

private restoreSettings() {
const settings = PersistenStorage.USER_SETTINGS.read() || {};
const enable = settings.enableAnalytics;
this.id = settings.id;
Expand All @@ -32,7 +41,7 @@ class Analytics {
}
}

toggleSetting(enable: boolean) {
public toggleSetting(enable: boolean) {
const settings = PersistenStorage.USER_SETTINGS.read() || {};
if (settings.enableAnalytics === enable) {
return;
Expand All @@ -48,7 +57,7 @@ class Analytics {
PersistenStorage.USER_SETTINGS.write({ enableAnalytics: enable, id: this.id });
}

enable() {
private enable() {
try {
this.mixpanel = Mixpanel.init(import.meta.env.VITE_MIXPANEL_TOKEN || '');
} catch (error) {
Expand All @@ -57,11 +66,11 @@ class Analytics {
}
}

disable() {
private disable() {
this.mixpanel = undefined;
}

track(event: string, data?: Record<string, any>, callback?: () => void) {
public track(event: string, data?: Record<string, any>, callback?: () => void) {
if (this.mixpanel) {
const eventData = {
distinct_id: this.id,
Expand All @@ -70,6 +79,25 @@ class Analytics {
this.mixpanel.track(event, eventData, callback);
}
}

public identify(user: UserMetadata) {
if (this.mixpanel && this.id) {
if (user.id !== this.id) {
this.mixpanel.alias(user.id, this.id);
PersistenStorage.USER_SETTINGS.update({ id: user.id });
}

this.mixpanel.people.set(this.id, {
$name: user.name,
$email: user.email,
$avatar: user.avatarUrl,
});
}
}

public signOut() {
PersistenStorage.USER_SETTINGS.write({ id: undefined });
}
}

export default Analytics;
export default Analytics.getInstance();
2 changes: 2 additions & 0 deletions app/electron/main/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { User } from '@supabase/supabase-js';
import { mainWindow } from '..';
import analytics from '../analytics';
import { PersistenStorage } from '../storage';
import { APP_SCHEMA, MainChannels } from '/common/constants';
import { AuthTokens, UserMetadata } from '/common/models/settings';
Expand Down Expand Up @@ -33,6 +34,7 @@ export async function handleAuthCallback(url: string) {
const userMetadata = getUserMetadata(user);
PersistenStorage.USER_METADATA.write(userMetadata);

analytics.identify(userMetadata);
emitAuthEvent();
}

Expand Down
4 changes: 1 addition & 3 deletions app/electron/main/events/analytics.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { ipcMain } from 'electron';
import Analytics from '../analytics';
import analytics from '../analytics';
import { MainChannels } from '/common/constants';

export function listenForAnalyticsMessages() {
const analytics: Analytics = new Analytics();

ipcMain.on(MainChannels.ANLYTICS_PREF_SET, (e: Electron.IpcMainInvokeEvent, args) => {
const analyticsPref = args as boolean;
analytics.toggleSetting(analyticsPref);
Expand Down
3 changes: 2 additions & 1 deletion app/electron/main/events/auth.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ipcMain } from 'electron';
import { mainWindow } from '..';
import analytics from '../analytics';
import { PersistenStorage } from '../storage';
import { MainChannels } from '/common/constants';

export function listenForAuthMessages() {
ipcMain.handle(MainChannels.SIGN_OUT, (e: Electron.IpcMainInvokeEvent, args) => {
PersistenStorage.USER_METADATA.clear();
PersistenStorage.AUTH_TOKENS.clear();

analytics.signOut();
mainWindow?.webContents.send(MainChannels.USER_SIGNED_OUT);
});
}
2 changes: 0 additions & 2 deletions app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TooltipProvider } from '@/components/ui/tooltip';
import Announcement from './components/Announcement';
import AppBar from './components/AppBar';
import AuthProvider from './components/AuthProvider';
import RouteProvider from './components/RouteProvider';
Expand All @@ -15,7 +14,6 @@ function App() {
<RouteProvider>
<AppBar />
<Routes />
<Announcement />
<Toaster />
</RouteProvider>
</AuthProvider>
Expand Down
37 changes: 0 additions & 37 deletions app/src/components/Announcement/auth.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion app/src/components/AppBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const AppBar = observer(() => {
const routeManager = useRouteManager();
return (
<div
className={`flex flex-row items-center pl-20 h-10 ${routeManager.route === Route.LOGIN ? 'bg-transparent' : 'bg-bg-active border-b'}`}
className={`flex flex-row items-center pl-20 h-10 ${routeManager.route === Route.SIGN_IN ? 'bg-transparent' : 'bg-bg-active border-b'}`}
>
<div className="appbar w-full h-full"></div>
<Button
Expand Down
5 changes: 2 additions & 3 deletions app/src/components/ui/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ const TooltipContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
'z-50 overflow-hidden rounded-md bg-black px-2 py-1.5 text-xs text-text-foreground',
'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 duration-100',
'z-50 rounded-md bg-black px-2 py-1.5 text-xs text-text-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className,
)}
{...props}
/>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TooltipPortal };
export { Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger };
4 changes: 2 additions & 2 deletions app/src/lib/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { sendAnalytics } from '../utils';

export enum Route {
EDITOR = 'editor',
LOGIN = 'login',
SIGN_IN = 'signin',
PROJECTS = 'projects',
}

Expand All @@ -19,7 +19,7 @@ export class RouteManager {
}

set route(newRoute: Route) {
this.route = newRoute;
this.currentRoute = newRoute;
sendAnalytics('navigate', { route: newRoute });
}
}
23 changes: 7 additions & 16 deletions app/src/routes/editor/LayersPanel/Tree/TreeNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,23 +178,14 @@ const TreeNode = observer(
</TooltipTrigger>
{node.data.textContent !== '' && (
<TooltipPortal container={document.getElementById('layer-tab-id')}>
<TooltipContent side="right" align="center" sideOffset={sideOffset()}>
<TooltipContent
side="right"
align="center"
sideOffset={sideOffset()}
className="animation-none"
>
<TooltipArrow className="fill-black" />
<motion.p
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
transition={{ duration: 0.2 }}
className="max-w-[200px] overflow-hidden"
style={{
display: '-webkit-box',
WebkitLineClamp: 4,
WebkitBoxOrient: 'vertical',
lineClamp: 4,
}}
>
{node.data.textContent}
</motion.p>
<p>{node.data.textContent}</p>
</TooltipContent>
</TooltipPortal>
)}
Expand Down
2 changes: 2 additions & 0 deletions app/src/routes/editor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Announcement from '@/components/Announcement';
import { EditorEngine } from '@/lib/editor/engine';
import { createContext, useContext } from 'react';
import Canvas from './Canvas';
Expand All @@ -14,6 +15,7 @@ export const useEditorEngine = () => useContext(EditorEngineContext);
function ProjectEditor() {
return (
<EditorEngineContext.Provider value={useEditorEngine()}>
<Announcement />
<div className="relative flex flex-row h-[calc(100vh-2.5rem)] select-none">
<Canvas>
<WebviewArea />
Expand Down
12 changes: 9 additions & 3 deletions app/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { useAuthManager } from '@/components/AuthProvider';
import { useRouteManager } from '@/components/RouteProvider';
import { Route } from '@/lib/routes';
import { observer } from 'mobx-react-lite';
import ProjectEditor from './editor';
import Login from './login';
import Projects from './projects';
import SignIn from './signin';

const Routes = observer(() => {
const routeManager = useRouteManager();
const authManager = useAuthManager();

if (authManager.authenticated && routeManager.route === Route.SIGN_IN) {
routeManager.route = Route.EDITOR;
}

switch (routeManager.route) {
case Route.EDITOR:
return <ProjectEditor />;
case Route.LOGIN:
return <Login />;
case Route.SIGN_IN:
return <SignIn />;
case Route.PROJECTS:
return <Projects />;
default:
Expand Down
33 changes: 21 additions & 12 deletions app/src/routes/login/index.tsx → app/src/routes/signin/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import dunes from '@/assets/dunes-login.png';
import google_logo from '@/assets/google_logo.svg';
import wordLogo from '@/assets/word-logo.svg';
import { useAuthManager } from '@/components/AuthProvider';
import { Button } from '@/components/ui/button';
import { GitHubLogoIcon } from '@radix-ui/react-icons';
import { observer } from 'mobx-react-lite';
import { useEffect, useState } from 'react';

const Login = () => {
const [lastLoginMethod, setLastLoginMethod] = useState<string | null>(null);
enum SignInMethod {
GITHUB = 'github',
GOOGLE = 'google',
}

const SignIn = observer(() => {
const [lastSignInMethod, setLastSignInMethod] = useState<SignInMethod | null>(null);
const authManager = useAuthManager();

useEffect(() => {
// Retrieve the last login method from localStorage
}, []);

const handleLogin = (method: string) => {
const handleLogin = (method: SignInMethod) => {
// Save the login method to localStorage
// Implement actual login logic here
authManager.signIn(method);
};

return (
Expand All @@ -29,7 +38,7 @@ const Login = () => {
</div>
<div className="space-y-4">
<h1 className="text-title1">
{lastLoginMethod ? 'Welcome back to Onlook' : 'Welcome to Onlook'}
{lastSignInMethod ? 'Welcome back to Onlook' : 'Welcome to Onlook'}
</h1>
<p className="text-text text-large">
Onlook is an open-source visual editor for React apps. Design directly
Expand All @@ -40,12 +49,12 @@ const Login = () => {
<div className="flex flex-col items-center w-full">
<Button
variant="outline"
className={`w-full text-active text-small ${lastLoginMethod === 'github' ? 'bg-teal-1000 border-teal-700 text-teal-100 text-small hover:bg-teal-800 hover:border-teal-500' : 'bg-bg'}`}
onClick={() => handleLogin('github')}
className={`w-full text-active text-small ${lastSignInMethod === 'github' ? 'bg-teal-1000 border-teal-700 text-teal-100 text-small hover:bg-teal-800 hover:border-teal-500' : 'bg-bg'}`}
onClick={() => handleLogin(SignInMethod.GITHUB)}
>
<GitHubLogoIcon className="w-4 h-4 mr-2" /> Login with GitHub
</Button>
{lastLoginMethod === 'github' && (
{lastSignInMethod === 'github' && (
<p className="text-teal-500 text-small mt-1">
You used this last time
</p>
Expand All @@ -54,13 +63,13 @@ const Login = () => {
<div className="flex flex-col items-center w-full">
<Button
variant="outline"
className={`w-full text-active text-small ${lastLoginMethod === 'google' ? 'bg-teal-1000 border-teal-700 text-teal-100 text-small hover:bg-teal-800 hover:border-teal-500' : 'bg-bg'}`}
onClick={() => handleLogin('google')}
className={`w-full text-active text-small ${lastSignInMethod === 'google' ? 'bg-teal-1000 border-teal-700 text-teal-100 text-small hover:bg-teal-800 hover:border-teal-500' : 'bg-bg'}`}
onClick={() => handleLogin(SignInMethod.GOOGLE)}
>
<img src={google_logo} className="w-4 h-4 mr-2" alt="Google logo" />{' '}
Login with Google
</Button>
{lastLoginMethod === 'google' && (
{lastSignInMethod === 'google' && (
<p className="text-teal-500 text-small mt-1">
You used this last time
</p>
Expand Down Expand Up @@ -92,6 +101,6 @@ const Login = () => {
</div>
</div>
);
};
});

export default Login;
export default SignIn;

0 comments on commit 48c0417

Please sign in to comment.