william commited on
Commit
a8dfd23
·
1 Parent(s): 594a973

add login

Browse files
src/app/page.tsx CHANGED
@@ -1,12 +1,11 @@
1
  /** @jsxImportSource @emotion/react */
2
  "use client";
3
- import { uploadImageAtom } from "@/atoms";
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, useSetAtom } from "jotai";
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 m-auto">
81
- <header className="flex justify-between items-center mx-auto py-2">
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;