Sign in is the default: the landing names the account, and an admin lands on /admin
This commit is contained in:
@@ -290,10 +290,13 @@ export function Workspace() {
|
||||
// Recipes made in this session, guest ones included. A guest's copy lives
|
||||
// here and nowhere else, so reloading the page is what deletes it.
|
||||
const [created, setCreated] = useState<Recipe[]>([]);
|
||||
// null = closed. /app?auth=1 opens the studio's dialog straight on the sign-up
|
||||
// tab; the landing page runs the same dialog in place instead of linking here.
|
||||
const [authMode, setAuthMode] = useState<'login' | 'signup' | null>(() =>
|
||||
(new URLSearchParams(window.location.search).has('auth') ? 'signup' : null));
|
||||
// null = closed. /app?auth=1 opens the studio's dialog straight on the sign-in
|
||||
// tab (sign-in is the default; ?auth=signup asks for the other one); the
|
||||
// landing page runs the same dialog in place instead of linking here.
|
||||
const [authMode, setAuthMode] = useState<'login' | 'signup' | null>(() => {
|
||||
const asked = new URLSearchParams(window.location.search).get('auth');
|
||||
return asked ? (asked === 'signup' ? 'signup' : 'login') : null;
|
||||
});
|
||||
|
||||
const renderToken = useRef(0);
|
||||
// Which previewMax the bytes in previewBytes were made at, so the upgrade
|
||||
|
||||
@@ -117,7 +117,7 @@ export function Landing() {
|
||||
// studio: the visitor keeps their scroll position and lands back on the reel.
|
||||
const [auth, setAuth] = useState<'login' | 'signup' | null>(() => {
|
||||
const asked = new URLSearchParams(window.location.search).get('auth');
|
||||
return asked === 'login' ? 'login' : asked ? 'signup' : null;
|
||||
return asked === 'signup' ? 'signup' : asked ? 'login' : null;
|
||||
});
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const filePick = useRef<HTMLInputElement>(null);
|
||||
@@ -138,11 +138,16 @@ export function Landing() {
|
||||
// The community half of the reel: whoever is signed in gets a picker, and
|
||||
// everybody sees the result on the next load. A guest is sent to sign up.
|
||||
const reload = useCallback(() => {
|
||||
api.me().then((r) => setUser(r.user)).catch(() => undefined);
|
||||
api.listPhotos().then((r) => setPhotos(r.photos)).catch(() => undefined);
|
||||
return api.me().then((r) => {
|
||||
setUser(r.user);
|
||||
return r.user;
|
||||
}).catch(() => null);
|
||||
}, []);
|
||||
|
||||
useEffect(reload, [reload]);
|
||||
useEffect(() => {
|
||||
reload();
|
||||
}, [reload]);
|
||||
|
||||
const contribute = useCallback(async (file: File) => {
|
||||
setUploading(true);
|
||||
@@ -284,10 +289,24 @@ export function Landing() {
|
||||
{lang.toUpperCase()}
|
||||
</button>
|
||||
</span>
|
||||
{/* Register: the dialog opens here, on the page the visitor is on. */}
|
||||
<button type="button" className="lp-btn lp-sm" data-key="nav-signup" onClick={() => setAuth('signup')}>
|
||||
{t('nav.signup')}
|
||||
</button>
|
||||
{/* Sign in is the default: the dialog opens here, on the page the
|
||||
visitor is on, and flips to sign-up from its own toggle. Once
|
||||
signed in the same slot names the account, so the session is
|
||||
visible on the page that took the credentials. */}
|
||||
{user ? (
|
||||
<a
|
||||
className="lp-btn lp-sm"
|
||||
data-key="nav-account"
|
||||
href={user.admin ? '/admin' : '/app'}
|
||||
title={user.email}
|
||||
>
|
||||
{user.email.split('@')[0]}
|
||||
</a>
|
||||
) : (
|
||||
<button type="button" className="lp-btn lp-sm" data-key="nav-login" onClick={() => setAuth('login')}>
|
||||
{t('nav.login')}
|
||||
</button>
|
||||
)}
|
||||
<button type="button" className="lp-btn lp-sm lp-primary" onClick={() => showToast(toastDownload)}>
|
||||
{c({ en: 'Download RecipesCam', vi: 'Tải RecipesCam' })}
|
||||
</button>
|
||||
@@ -299,14 +318,20 @@ export function Landing() {
|
||||
<div className="lp-sheet">
|
||||
{nav.map((entry) => <a key={entry.href} href={entry.href} onClick={() => setMenu(false)}>{c(entry.label)}</a>)}
|
||||
<a href="/app" onClick={() => setMenu(false)}>{c({ en: 'Open studio', vi: 'Mở studio' })}</a>
|
||||
<button
|
||||
type="button"
|
||||
className="lp-btn"
|
||||
data-key="sheet-signup"
|
||||
onClick={() => { setMenu(false); setAuth('signup'); }}
|
||||
>
|
||||
{t('nav.signup')}
|
||||
</button>
|
||||
{user ? (
|
||||
<a className="lp-btn" data-key="sheet-account" href={user.admin ? '/admin' : '/app'} onClick={() => setMenu(false)}>
|
||||
{user.email.split('@')[0]}
|
||||
</a>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="lp-btn"
|
||||
data-key="sheet-login"
|
||||
onClick={() => { setMenu(false); setAuth('login'); }}
|
||||
>
|
||||
{t('nav.login')}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="lp-btn lp-primary"
|
||||
@@ -361,8 +386,8 @@ export function Landing() {
|
||||
{uploading ? t('photo.uploading') : t('photo.contribute')}
|
||||
</button>
|
||||
) : (
|
||||
/* A guest gets the same button; it opens the sign-up dialog. */
|
||||
<button type="button" className="lp-btn lp-primary" data-key="contribute" onClick={() => setAuth('signup')}>
|
||||
/* A guest gets the same button; it opens the sign-in dialog. */
|
||||
<button type="button" className="lp-btn lp-primary" data-key="contribute" onClick={() => setAuth('login')}>
|
||||
{t('photo.contribute')}
|
||||
</button>
|
||||
)}
|
||||
@@ -670,7 +695,9 @@ export function Landing() {
|
||||
onClose={() => setAuth(null)}
|
||||
onDone={() => {
|
||||
setAuth(null);
|
||||
reload();
|
||||
// An admin signs in here to moderate, so send them on to the page
|
||||
// that asked for the session in the first place.
|
||||
reload().then((u) => u?.admin && window.location.assign('/admin'));
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user