Spaces:
Runtime error
Runtime error
william commited on
Commit ·
a8dfd23
1
Parent(s): 594a973
add login
Browse files- src/app/page.tsx +7 -12
- src/atoms/index.ts +0 -5
- src/components/auth-modal.tsx +61 -0
- src/components/auth.tsx +0 -25
- src/components/dropzone.tsx +3 -2
- src/components/header.tsx +26 -0
src/app/page.tsx
CHANGED
|
@@ -1,12 +1,11 @@
|
|
| 1 |
/** @jsxImportSource @emotion/react */
|
| 2 |
"use client";
|
| 3 |
-
import { uploadImageAtom } from "@/
|
| 4 |
-
import { generatedImageAtom } from "@/atoms/index";
|
| 5 |
-
import Dropzone from "@/components/dropzone";
|
| 6 |
import { css } from "@emotion/react";
|
| 7 |
import { Button } from "antd";
|
| 8 |
-
import { useAtom, useAtomValue,
|
| 9 |
|
|
|
|
| 10 |
import {
|
| 11 |
DownloadOutlined,
|
| 12 |
ReloadOutlined,
|
|
@@ -14,7 +13,6 @@ import {
|
|
| 14 |
} from "@ant-design/icons";
|
| 15 |
import { useEffect, useState } from "react";
|
| 16 |
import StyleCard from "./style-card";
|
| 17 |
-
import AuthModal, { authModalAtom } from "@/components/auth";
|
| 18 |
|
| 19 |
const STYLEs = [
|
| 20 |
{
|
|
@@ -47,12 +45,13 @@ const STYLEs = [
|
|
| 47 |
},
|
| 48 |
];
|
| 49 |
|
|
|
|
|
|
|
| 50 |
export default function Home() {
|
| 51 |
const uploadImage = useAtomValue(uploadImageAtom);
|
| 52 |
const [generatedImage, setGeneratedImage] = useAtom(generatedImageAtom);
|
| 53 |
const [loading, setLoading] = useState(false);
|
| 54 |
const [pickedStyle, setPickedStyle] = useState("anime");
|
| 55 |
-
const setModalOpen = useSetAtom(authModalAtom);
|
| 56 |
|
| 57 |
useEffect(() => {
|
| 58 |
setGeneratedImage(null);
|
|
@@ -77,12 +76,8 @@ export default function Home() {
|
|
| 77 |
|
| 78 |
return (
|
| 79 |
<>
|
| 80 |
-
<main className="min-h-screen container
|
| 81 |
-
<
|
| 82 |
-
<div />
|
| 83 |
-
<Button onClick={() => setModalOpen(true)}>Open Auth</Button>
|
| 84 |
-
</header>
|
| 85 |
-
<AuthModal />
|
| 86 |
<div className="flex flex-col items-center mx-auto px-4">
|
| 87 |
<h1 className="text-5xl font-bold text-center mt-4 mb-8">
|
| 88 |
AI Art Generator
|
|
|
|
| 1 |
/** @jsxImportSource @emotion/react */
|
| 2 |
"use client";
|
| 3 |
+
import Dropzone, { uploadImageAtom } from "@/components/dropzone";
|
|
|
|
|
|
|
| 4 |
import { css } from "@emotion/react";
|
| 5 |
import { Button } from "antd";
|
| 6 |
+
import { useAtom, useAtomValue, atom } from "jotai";
|
| 7 |
|
| 8 |
+
import Header from "@/components/header";
|
| 9 |
import {
|
| 10 |
DownloadOutlined,
|
| 11 |
ReloadOutlined,
|
|
|
|
| 13 |
} from "@ant-design/icons";
|
| 14 |
import { useEffect, useState } from "react";
|
| 15 |
import StyleCard from "./style-card";
|
|
|
|
| 16 |
|
| 17 |
const STYLEs = [
|
| 18 |
{
|
|
|
|
| 45 |
},
|
| 46 |
];
|
| 47 |
|
| 48 |
+
const generatedImageAtom = atom<string | null>(null);
|
| 49 |
+
|
| 50 |
export default function Home() {
|
| 51 |
const uploadImage = useAtomValue(uploadImageAtom);
|
| 52 |
const [generatedImage, setGeneratedImage] = useAtom(generatedImageAtom);
|
| 53 |
const [loading, setLoading] = useState(false);
|
| 54 |
const [pickedStyle, setPickedStyle] = useState("anime");
|
|
|
|
| 55 |
|
| 56 |
useEffect(() => {
|
| 57 |
setGeneratedImage(null);
|
|
|
|
| 76 |
|
| 77 |
return (
|
| 78 |
<>
|
| 79 |
+
<main className="min-h-screen container mx-auto pb-8">
|
| 80 |
+
<Header />
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
<div className="flex flex-col items-center mx-auto px-4">
|
| 82 |
<h1 className="text-5xl font-bold text-center mt-4 mb-8">
|
| 83 |
AI Art Generator
|
src/atoms/index.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
import { atom } from 'jotai';
|
| 2 |
-
|
| 3 |
-
export const uploadImageAtom = atom<string | null>(null);
|
| 4 |
-
|
| 5 |
-
export const generatedImageAtom = atom<string | null>(null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/components/auth-modal.tsx
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { createClient } from "@/utils/supabase/client";
|
| 2 |
+
import { Auth } from "@supabase/auth-ui-react";
|
| 3 |
+
import { ThemeSupa } from "@supabase/auth-ui-shared";
|
| 4 |
+
import { AuthChangeEvent } from "@supabase/supabase-js";
|
| 5 |
+
import { Modal } from "antd";
|
| 6 |
+
import { atom, useAtom, useSetAtom } from "jotai";
|
| 7 |
+
import { useEffect } from "react";
|
| 8 |
+
|
| 9 |
+
export const authModalAtom = atom(false);
|
| 10 |
+
export const authStateAtom = atom<AuthChangeEvent>("INITIAL_SESSION");
|
| 11 |
+
|
| 12 |
+
const supabase = createClient();
|
| 13 |
+
|
| 14 |
+
const AuthModal = () => {
|
| 15 |
+
const [modalOpen, setModalOpen] = useAtom(authModalAtom);
|
| 16 |
+
const setAuthState = useSetAtom(authStateAtom);
|
| 17 |
+
|
| 18 |
+
useEffect(() => {
|
| 19 |
+
supabase.auth.getSession().then(({ data }) => {
|
| 20 |
+
if (data?.session) {
|
| 21 |
+
supabase.auth.setSession(data.session);
|
| 22 |
+
}
|
| 23 |
+
});
|
| 24 |
+
|
| 25 |
+
const { data: authListener } = supabase.auth.onAuthStateChange(
|
| 26 |
+
(event, session) => {
|
| 27 |
+
setAuthState(event);
|
| 28 |
+
|
| 29 |
+
if (event === "SIGNED_IN") {
|
| 30 |
+
setModalOpen(false);
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
);
|
| 34 |
+
|
| 35 |
+
return () => {
|
| 36 |
+
authListener?.subscription?.unsubscribe();
|
| 37 |
+
};
|
| 38 |
+
}, []);
|
| 39 |
+
|
| 40 |
+
return (
|
| 41 |
+
<Modal open={modalOpen} onCancel={() => setModalOpen(false)} footer={null}>
|
| 42 |
+
<Auth
|
| 43 |
+
supabaseClient={supabase}
|
| 44 |
+
appearance={{
|
| 45 |
+
theme: ThemeSupa,
|
| 46 |
+
variables: {
|
| 47 |
+
default: {
|
| 48 |
+
colors: {
|
| 49 |
+
brand: "#1677ff",
|
| 50 |
+
brandAccent: "#4096ff",
|
| 51 |
+
},
|
| 52 |
+
},
|
| 53 |
+
},
|
| 54 |
+
}}
|
| 55 |
+
providers={[]}
|
| 56 |
+
/>
|
| 57 |
+
</Modal>
|
| 58 |
+
);
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
export default AuthModal;
|
src/components/auth.tsx
DELETED
|
@@ -1,25 +0,0 @@
|
|
| 1 |
-
import { createClient } from "@/utils/supabase/client";
|
| 2 |
-
import { Auth } from "@supabase/auth-ui-react";
|
| 3 |
-
import { ThemeSupa } from "@supabase/auth-ui-shared";
|
| 4 |
-
import { Modal } from "antd";
|
| 5 |
-
import { atom, useAtom } from "jotai";
|
| 6 |
-
|
| 7 |
-
export const authModalAtom = atom(false);
|
| 8 |
-
|
| 9 |
-
const supabase = createClient();
|
| 10 |
-
|
| 11 |
-
const AuthModal = () => {
|
| 12 |
-
const [modalOpen, setModalOpen] = useAtom(authModalAtom);
|
| 13 |
-
return (
|
| 14 |
-
<Modal
|
| 15 |
-
title="Login"
|
| 16 |
-
open={modalOpen}
|
| 17 |
-
onCancel={() => setModalOpen(false)}
|
| 18 |
-
footer={null}
|
| 19 |
-
>
|
| 20 |
-
<Auth supabaseClient={supabase} appearance={{ theme: ThemeSupa }} />
|
| 21 |
-
</Modal>
|
| 22 |
-
);
|
| 23 |
-
};
|
| 24 |
-
|
| 25 |
-
export default AuthModal;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/components/dropzone.tsx
CHANGED
|
@@ -1,16 +1,17 @@
|
|
| 1 |
-
import { uploadImageAtom } from "@/atoms";
|
| 2 |
import {
|
| 3 |
CloseSquareOutlined,
|
| 4 |
InboxOutlined,
|
| 5 |
SyncOutlined,
|
| 6 |
} from "@ant-design/icons";
|
| 7 |
import { Upload } from "antd";
|
| 8 |
-
import { useAtom } from "jotai";
|
| 9 |
import imageCompression from "browser-image-compression";
|
| 10 |
import React, { useState } from "react";
|
| 11 |
|
| 12 |
const { Dragger } = Upload;
|
| 13 |
|
|
|
|
|
|
|
| 14 |
const Dropzone: React.FC = () => {
|
| 15 |
const [file, setFile] = useAtom(uploadImageAtom);
|
| 16 |
const [compressing, setCompressing] = useState(false);
|
|
|
|
|
|
|
| 1 |
import {
|
| 2 |
CloseSquareOutlined,
|
| 3 |
InboxOutlined,
|
| 4 |
SyncOutlined,
|
| 5 |
} from "@ant-design/icons";
|
| 6 |
import { Upload } from "antd";
|
| 7 |
+
import { useAtom, atom } from "jotai";
|
| 8 |
import imageCompression from "browser-image-compression";
|
| 9 |
import React, { useState } from "react";
|
| 10 |
|
| 11 |
const { Dragger } = Upload;
|
| 12 |
|
| 13 |
+
export const uploadImageAtom = atom<string | null>(null);
|
| 14 |
+
|
| 15 |
const Dropzone: React.FC = () => {
|
| 16 |
const [file, setFile] = useAtom(uploadImageAtom);
|
| 17 |
const [compressing, setCompressing] = useState(false);
|
src/components/header.tsx
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Button } from "antd";
|
| 2 |
+
import AuthModal, { authModalAtom, authStateAtom } from "@/components/auth-modal";
|
| 3 |
+
import { useAtomValue, useSetAtom } from "jotai";
|
| 4 |
+
import { UserOutlined } from "@ant-design/icons";
|
| 5 |
+
|
| 6 |
+
const Header = () => {
|
| 7 |
+
const authState = useAtomValue(authStateAtom);
|
| 8 |
+
const setModalOpen = useSetAtom(authModalAtom);
|
| 9 |
+
const isSignedIn = authState === "SIGNED_IN";
|
| 10 |
+
|
| 11 |
+
return (
|
| 12 |
+
<>
|
| 13 |
+
<header className="flex justify-between items-center mx-auto py-2">
|
| 14 |
+
<div />
|
| 15 |
+
{isSignedIn ? (
|
| 16 |
+
<UserOutlined className="h-[32px] text-xl" />
|
| 17 |
+
) : (
|
| 18 |
+
<Button onClick={() => setModalOpen(true)}>Open Auth</Button>
|
| 19 |
+
)}
|
| 20 |
+
</header>
|
| 21 |
+
<AuthModal />
|
| 22 |
+
</>
|
| 23 |
+
);
|
| 24 |
+
};
|
| 25 |
+
|
| 26 |
+
export default Header;
|