-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fixed google auth, added auth provider, fixed logout, added tabs comp…
…onent, added dependencies for typing gapi auth/oauth2/drive
- Loading branch information
Showing
9 changed files
with
211 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 27 additions & 115 deletions
142
SteamOrganizer.Web/src/components/elements/GoogleLogin.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,119 +1,31 @@ | ||
import React, {useState, useEffect, useRef} from 'react'; | ||
import { gapi } from 'gapi-script'; | ||
import {saveFile} from "@/services/gdrive.ts"; | ||
|
||
interface User { | ||
name: string; | ||
profileImg: string; | ||
email:string; | ||
} | ||
|
||
|
||
interface GoogleLoginProps { | ||
apiKey:string; | ||
clientId: string; | ||
discoveryDocs?:string[]; | ||
scope?: string; | ||
} | ||
|
||
export const GoogleLogin: React.FC<GoogleLoginProps> = ({ | ||
clientId, apiKey, | ||
scope = 'https://www.googleapis.com/auth/drive.file', | ||
discoveryDocs=['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'], | ||
}) => { | ||
let gay=true; | ||
const [user, setUser] = useState<User|null>(null | ||
|
||
/* | ||
{email: "[email protected]", | ||
profileImg: "https://ui-avatars.com/api/?background=c7d2fe&color=3730a3&bold=true", | ||
name:"John doe"}*/) | ||
const signIn = () => { | ||
|
||
if(gay){ | ||
console.log(JSON.stringify(user)); | ||
gapi.auth2.getAuthInstance().signIn(); | ||
} | ||
|
||
}; | ||
|
||
/** | ||
* Called when the signed in status changes, to update the UI | ||
* appropriately. After a sign-in, the API is called. | ||
*/ | ||
const updateUser = (isSignedIn: boolean) => { | ||
if (isSignedIn) { | ||
let currentUser= gapi.auth2.getAuthInstance().currentUser.get().getBasicProfile(); | ||
const name = currentUser.getName(); | ||
const profileImg = currentUser.getImageUrl(); | ||
const email =currentUser.getEmail(); | ||
setUser({ | ||
name, | ||
profileImg, | ||
email, | ||
}); | ||
saveFile(); | ||
} else { | ||
signIn(); | ||
} | ||
}; | ||
|
||
const initClient = () => { | ||
gapi.client | ||
.init({ | ||
apiKey: apiKey, | ||
clientId: clientId, | ||
discoveryDocs: discoveryDocs, | ||
scope: scope, | ||
}) | ||
.then( | ||
function () { | ||
// Listen for sign-in state changes. | ||
gapi.auth2.getAuthInstance().isSignedIn.listen(updateUser); | ||
// Handle the initial sign-in state. | ||
updateUser(gapi.auth2.getAuthInstance().isSignedIn.get()); | ||
} | ||
); | ||
}; | ||
|
||
const HandleSignIn = () => { | ||
//After the platform library loads, load the auth2 library: | ||
gapi.load('client:auth2', initClient); | ||
}; | ||
|
||
const HandleSignOut = () => { | ||
gay=false; | ||
const auth2 = gapi.auth2.getAuthInstance(); | ||
auth2.signOut().then(() => { | ||
setUser(null); | ||
//console.log('User signed out.'); | ||
}); | ||
}; | ||
if(user) { | ||
return ( | ||
<div> | ||
<img | ||
src={user.profileImg} | ||
alt="" | ||
className="w-10 h-10 rounded-md" | ||
/> | ||
<div className="pl-2 flex-col flex justify-center text-nowrap w-full truncate relative"> | ||
<h4 className="text-fg-3 text-sm">{user.name}</h4> | ||
<span className="text-fg-1 text-xs">{user.email}</span> | ||
<div className="absolute w-1/3 h-full right-0 bg-gradient-to-r from-transparent to-pr-2"/> | ||
import React from 'react'; | ||
import {useAuth} from "@/providers/authProvider.tsx"; | ||
|
||
export const GoogleLogin: React.FC = () => { | ||
const { user, signIn, signOut } = useAuth(); | ||
|
||
return (user.isLoggedIn ? ( | ||
<div> | ||
<img | ||
src={user.profileImg} | ||
alt="" | ||
className="w-10 h-10 rounded-md" | ||
/> | ||
<div className="pl-2 flex-col flex justify-center text-nowrap w-full truncate relative"> | ||
<h4 className="text-fg-3 text-sm">{user.name}</h4> | ||
<span className="text-fg-1 text-xs">{user.email}</span> | ||
<div className="absolute w-1/3 h-full right-0 bg-gradient-to-r from-transparent to-pr-2"/> | ||
</div> | ||
<div className="btn" onClick={signOut}> | ||
Logout | ||
</div> | ||
</div> | ||
<div className="btn" onClick={HandleSignOut}> | ||
Logout | ||
) : ( | ||
<div> | ||
<div className="btn" onClick={signIn}> | ||
<p>{user.isLoggedIn === undefined ? "loading..." : "Sign in"} </p> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<div> | ||
<div className="btn" onClick={HandleSignIn}> | ||
Login | ||
</div> | ||
</div> | ||
) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import {AnimatePresence, motion} from "framer-motion"; | ||
import React, {FC, Key, ReactNode, useState} from "react"; | ||
import clsx from "clsx"; | ||
|
||
interface ITabProps { | ||
children: ReactNode, | ||
title: ReactNode, | ||
} | ||
|
||
interface ITabPanelProps { | ||
children: React.ReactElement<ITabProps> | React.ReactElement<ITabProps>[]; | ||
activeKey: Key | ||
} | ||
|
||
export const TabPanel: FC<ITabPanelProps> = ({ children, activeKey }) => { | ||
const [active, setActive] = useState(activeKey) | ||
let renderContent: ReactNode; | ||
|
||
return ( | ||
<div className="flex items-center flex-col"> | ||
<div className="flex gap-3 mb-10 bg-primary p-2 rounded-lg "> | ||
{ | ||
React.Children.map(children, (child) => { | ||
let isActive: boolean = false; | ||
if (child.key == active) { | ||
renderContent = child | ||
isActive = true | ||
} | ||
return ( | ||
<button key={child.key} onClick={() => setActive(child.key!)} | ||
className={clsx("relative px-3 py-1.5 text-sm font-medium text-black transition-colors", | ||
isActive ? "text-background" : "text-foreground")}> | ||
{isActive && | ||
(<motion.div layoutId="active-pill" style={{borderRadius: 8}} | ||
transition={{type: "spring", duration: 0.6}} | ||
className="absolute inset-0 bg-secondary"/>) | ||
} | ||
<span className="relative z-10">{child.props.title}</span> | ||
</button> | ||
) | ||
}) | ||
} | ||
</div> | ||
|
||
<div> | ||
<AnimatePresence> | ||
<motion.div initial={{opacity: 0, marginTop: 20}} key={active} | ||
animate={{opacity: 1, marginTop: 0}}> | ||
{renderContent} | ||
</motion.div> | ||
</AnimatePresence> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
export const Tab: FC<ITabProps> = ({ children}) => ( | ||
<> | ||
{children} | ||
</> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
export class EventEmitter<T> { | ||
private listeners: Array<(data: T) => void> = new Array<(data: T) => void>(); | ||
|
||
subscribe(listener: (data: T) => void): void { | ||
this.listeners.push(listener); | ||
} | ||
|
||
unsubscribe(listener: (data: T) => void): void { | ||
const index = this.listeners.indexOf(listener); | ||
if (index > -1) { | ||
this.listeners.splice(index, 1); | ||
} | ||
} | ||
|
||
emit(data: T): void { | ||
this.listeners.forEach(listener => listener(data)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React, {createContext, useContext, useState, ReactNode, useEffect} from 'react'; | ||
import {getUserProfile, initGapi, signIn, signOut, subscribe, unsubscribe} from "@/services/gAuthService.ts"; | ||
|
||
interface IAuthUser { | ||
isLoggedIn?: boolean | undefined; | ||
name?: string; | ||
profileImg?: string; | ||
email?:string; | ||
} | ||
|
||
interface AuthContextType { | ||
signIn: () => void; | ||
signOut: () => void; | ||
user: IAuthUser; | ||
} | ||
|
||
const AuthContext = createContext<AuthContextType>(undefined!); | ||
|
||
export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => { | ||
const [user, setUser] = useState<IAuthUser>({}); | ||
|
||
useEffect(() => { | ||
const stateCallback = (state: boolean) => { | ||
let info; | ||
if(state) { | ||
const profile = getUserProfile() | ||
info ={ | ||
isLoggedIn: state, | ||
email: profile.getEmail(), | ||
name: profile.getName(), | ||
profileImg: profile.getImageUrl() | ||
} | ||
} | ||
setUser(info ?? { isLoggedIn: state }) | ||
} | ||
|
||
subscribe(stateCallback) | ||
initGapi() | ||
|
||
return () => unsubscribe(stateCallback) | ||
},[]) | ||
|
||
|
||
return ( | ||
<AuthContext.Provider value={{ user, signIn, signOut }}> | ||
{children} | ||
</AuthContext.Provider> | ||
); | ||
}; | ||
|
||
export const useAuth = () => useContext(AuthContext); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { gapi } from 'gapi-script'; | ||
import {EventEmitter} from "@/lib/eventEmitter.ts"; | ||
|
||
export let isAuthorized : boolean; | ||
const authSubscribers: EventEmitter<boolean> = new EventEmitter<boolean>() | ||
|
||
const setAuthState = (state: boolean) => { | ||
isAuthorized = state; | ||
authSubscribers.emit(state) | ||
} | ||
|
||
const onClientInitializing = async () => { | ||
await gapi.client.init({ | ||
apiKey: "AIzaSyCWCk7kXhV2kmsPs8Bv6Abe8hAx4RDa_z0", | ||
clientId: "1051364021046-9rkovhkatqt70kmubg8fv7ukbalobj8q.apps.googleusercontent.com", | ||
discoveryDocs: [ "https://www.googleapis.com/discovery/v1/apis/drive/v3/rest" ], | ||
scope: "https://www.googleapis.com/auth/drive.file", | ||
}) | ||
|
||
const instance = gapi.auth2.getAuthInstance(); | ||
setAuthState(instance.isSignedIn.get()) | ||
instance.isSignedIn.listen(setAuthState) | ||
} | ||
|
||
export const signIn = () => | ||
gapi.auth2.getAuthInstance().signIn( { ux_mode: "popup" } ); | ||
|
||
export const signOut = () => | ||
gapi.auth2.getAuthInstance().disconnect(); | ||
|
||
export const subscribe = (callback: (data: boolean) => void ) => | ||
authSubscribers.subscribe(callback) | ||
|
||
export const unsubscribe = (callback: (data: boolean) => void ) => | ||
authSubscribers.unsubscribe(callback); | ||
|
||
export const getUserProfile = () => | ||
gapi.auth2.getAuthInstance().currentUser.get().getBasicProfile(); | ||
|
||
export const initGapi = () => | ||
gapi.load('client:auth2', onClientInitializing); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters