mirror of
https://github.com/fergalmoran/supanextail.git
synced 2025-12-31 13:47:45 +00:00
Continue typescript conversion 2
This commit is contained in:
@@ -1,10 +1,15 @@
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import authImage from 'public/auth.png';
|
import authImage from 'public/auth.png';
|
||||||
|
|
||||||
const AuthText = () => (
|
const AuthText = (): JSX.Element => (
|
||||||
<div className="lg:mt-0 max-w-lg flex flex-col text-xl">
|
<div className="lg:mt-0 max-w-lg flex flex-col text-xl">
|
||||||
<div className="mt-10 mb-3 m-auto">
|
<div className="mt-10 mb-3 m-auto">
|
||||||
<Image src={authImage} width={authImage.width / 1.5} height={authImage.height / 1.5} />
|
<Image
|
||||||
|
src={authImage}
|
||||||
|
width={authImage.width / 1.5}
|
||||||
|
height={authImage.height / 1.5}
|
||||||
|
alt="A rocketship"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-4xl font-title font-semibold text-center">
|
<h2 className="text-4xl font-title font-semibold text-center">
|
||||||
Join SupaNexTail for <span className="text-primary">free</span>!
|
Join SupaNexTail for <span className="text-primary">free</span>!
|
||||||
@@ -4,16 +4,22 @@ the upload.
|
|||||||
You can tweak the max size, line 47
|
You can tweak the max size, line 47
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { supabase } from 'utils/supabaseClient';
|
import { supabase } from 'utils/supabaseClient';
|
||||||
|
|
||||||
const Avatar = ({ url, size, onUpload }) => {
|
type AvatarProps = {
|
||||||
const [avatarUrl, setAvatarUrl] = useState(null);
|
url: string;
|
||||||
|
size: number;
|
||||||
|
onUpload: (filePath: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Avatar = ({ url, size, onUpload }: AvatarProps): JSX.Element => {
|
||||||
|
const [avatarUrl, setAvatarUrl] = useState('');
|
||||||
const [uploading, setUploading] = useState(false);
|
const [uploading, setUploading] = useState(false);
|
||||||
|
|
||||||
const customImgLoader = ({ src }) => {
|
const customImgLoader = ({ src }: { src: string }) => {
|
||||||
return `${src}`;
|
return `${src}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,7 +27,7 @@ const Avatar = ({ url, size, onUpload }) => {
|
|||||||
if (url) downloadImage(url);
|
if (url) downloadImage(url);
|
||||||
}, [url]);
|
}, [url]);
|
||||||
|
|
||||||
async function downloadImage(path) {
|
async function downloadImage(path: string) {
|
||||||
try {
|
try {
|
||||||
const { data, error } = await supabase.storage.from('avatars').download(path);
|
const { data, error } = await supabase.storage.from('avatars').download(path);
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -34,7 +40,7 @@ const Avatar = ({ url, size, onUpload }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function uploadAvatar(event) {
|
async function uploadAvatar(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
try {
|
try {
|
||||||
setUploading(true);
|
setUploading(true);
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
const Footer = () => {
|
const Footer = (): JSX.Element => {
|
||||||
const ThemeToggle = dynamic(() => import('components/UI/ThemeToggle.js'), {
|
const ThemeToggle = dynamic(() => import('components/UI/ThemeToggle'), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
import { IoLogoGoogle } from 'react-icons/io';
|
|
||||||
import router from 'next/router';
|
|
||||||
import { toast } from 'react-toastify';
|
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
const SignUpPanel = (props) => {
|
|
||||||
const [email, setEmail] = useState('');
|
|
||||||
const [password, setPassword] = useState('');
|
|
||||||
const [forgot, setForgot] = useState(false);
|
|
||||||
|
|
||||||
const resetPassword = () => {
|
|
||||||
props.resetPassword(email).then((result) => {
|
|
||||||
if (result.error) {
|
|
||||||
toast.error(result.error.message);
|
|
||||||
} else toast.success('Check your email to reset your password!');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const signup = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
// Handle the login. Go to the homepage if success or display an error.
|
|
||||||
props
|
|
||||||
.signUp({
|
|
||||||
email,
|
|
||||||
password,
|
|
||||||
})
|
|
||||||
.then((result) => {
|
|
||||||
if (result.data) {
|
|
||||||
router.push('/');
|
|
||||||
}
|
|
||||||
if (result.error) {
|
|
||||||
toast.error(result.error.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="p-10 bg-base-100 md:flex-1 rounded-md text-base-content shadow-md max-w-sm font-body">
|
|
||||||
{!forgot && (
|
|
||||||
<>
|
|
||||||
<h3 className="my-4 text-2xl font-semibold font-title">Account Sign Up</h3>
|
|
||||||
<form action="#" className="flex flex-col space-y-5">
|
|
||||||
<div className="flex flex-col space-y-1">
|
|
||||||
<label htmlFor="email" className="text-sm">
|
|
||||||
Email address
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
id="email"
|
|
||||||
autoFocus
|
|
||||||
className="input input-primary input-bordered input-sm"
|
|
||||||
value={email}
|
|
||||||
onChange={(event) => {
|
|
||||||
setEmail(event.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col space-y-1">
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
id="password"
|
|
||||||
className="input input-primary input-bordered input-sm"
|
|
||||||
value={password}
|
|
||||||
onChange={(event) => {
|
|
||||||
setPassword(event.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
className="btn btn-primary w-full"
|
|
||||||
onClick={(event) => {
|
|
||||||
signup(event);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Sign Up
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col space-y-5">
|
|
||||||
<span className="flex items-center justify-center space-x-2">
|
|
||||||
<span className="h-px bg-gray-400 w-14" />
|
|
||||||
<span className="font-normal text-gray-500">or sign up with</span>
|
|
||||||
<span className="h-px bg-gray-400 w-14" />
|
|
||||||
</span>
|
|
||||||
<div className="flex flex-col space-y-4">
|
|
||||||
<button
|
|
||||||
href="#"
|
|
||||||
className="flex items-center justify-center px-4 py-2 space-x-2 transition-colors duration-300 border border-base-200 rounded-md group hover:bg-base-300 focus:outline-none "
|
|
||||||
onClick={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
props.signIn({ provider: 'google' });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="text-base-content">
|
|
||||||
<IoLogoGoogle />
|
|
||||||
</div>
|
|
||||||
<span className="text-sm font-medium text-base-content">Gmail</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SignUpPanel;
|
|
||||||
99
components/UI/SignUpPanel.tsx
Normal file
99
components/UI/SignUpPanel.tsx
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
import { IoLogoGoogle } from 'react-icons/io';
|
||||||
|
import router from 'next/router';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
type SignUpPanelProps = {
|
||||||
|
signIn: ({}) => Promise<{ data: Record<string, unknown>; error: { message: string } }>;
|
||||||
|
signUp: ({}) => Promise<{ data: Record<string, unknown>; error: { message: string } }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SignUpPanel = ({ signIn, signUp }: SignUpPanelProps): JSX.Element => {
|
||||||
|
const [email, setEmail] = useState('');
|
||||||
|
const [password, setPassword] = useState('');
|
||||||
|
|
||||||
|
const signup = (e: React.SyntheticEvent<HTMLButtonElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Handle the login. Go to the homepage if success or display an error.
|
||||||
|
signUp({
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.data) {
|
||||||
|
router.push('/');
|
||||||
|
}
|
||||||
|
if (result.error) {
|
||||||
|
toast.error(result.error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-10 bg-base-100 md:flex-1 rounded-md text-base-content shadow-md max-w-sm font-body">
|
||||||
|
<h3 className="my-4 text-2xl font-semibold font-title">Account Sign Up</h3>
|
||||||
|
<form action="#" className="flex flex-col space-y-5">
|
||||||
|
<div className="flex flex-col space-y-1">
|
||||||
|
<label htmlFor="email" className="text-sm">
|
||||||
|
Email address
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
autoFocus
|
||||||
|
className="input input-primary input-bordered input-sm"
|
||||||
|
value={email}
|
||||||
|
onChange={(event) => {
|
||||||
|
setEmail(event.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col space-y-1">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
className="input input-primary input-bordered input-sm"
|
||||||
|
value={password}
|
||||||
|
onChange={(event) => {
|
||||||
|
setPassword(event.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
className="btn btn-primary w-full"
|
||||||
|
onClick={(event) => {
|
||||||
|
signup(event);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sign Up
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col space-y-5">
|
||||||
|
<span className="flex items-center justify-center space-x-2">
|
||||||
|
<span className="h-px bg-gray-400 w-14" />
|
||||||
|
<span className="font-normal text-gray-500">or sign up with</span>
|
||||||
|
<span className="h-px bg-gray-400 w-14" />
|
||||||
|
</span>
|
||||||
|
<div className="flex flex-col space-y-4">
|
||||||
|
<button
|
||||||
|
className="flex items-center justify-center px-4 py-2 space-x-2 transition-colors duration-300 border border-base-200 rounded-md group hover:bg-base-300 focus:outline-none "
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
signIn({ provider: 'google' });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="text-base-content">
|
||||||
|
<IoLogoGoogle />
|
||||||
|
</div>
|
||||||
|
<span className="text-sm font-medium text-base-content">Gmail</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SignUpPanel;
|
||||||
@@ -11,8 +11,8 @@ const theme = {
|
|||||||
secondary: 'dark',
|
secondary: 'dark',
|
||||||
};
|
};
|
||||||
|
|
||||||
const ThemeToggle = () => {
|
const ThemeToggle = (): JSX.Element => {
|
||||||
const [activeTheme, setActiveTheme] = useState(document.body.dataset.theme);
|
const [activeTheme, setActiveTheme] = useState(document.body.dataset.theme || '');
|
||||||
const inactiveTheme = activeTheme === 'supaTheme' ? 'dark' : 'supaTheme';
|
const inactiveTheme = activeTheme === 'supaTheme' ? 'dark' : 'supaTheme';
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Reference in New Issue
Block a user