mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 02:45:07 +03:00
Finalise the react guide (until I add a video)
This commit is contained in:
1 parent
4218b62de7
commit
b24bad98a2
6 files changed
+64
-44
No files matched your search
+1
-6
@@ -1,11 +1,6 @@
|
||||
/**
|
||||
* src/Account.js
|
||||
* Allow a logged-in user to manage their account.
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import Avatar from './Avatar'
|
||||
import { supabase } from './supabaseClient'
|
||||
import Avatar from './Avatar'
|
||||
|
||||
export default function Account({ session }) {
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import './index.css'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { supabase } from './supabaseClient'
|
||||
import Auth from './Auth'
|
||||
import Account from './Account'
|
||||
import { supabase } from './supabaseClient'
|
||||
|
||||
export default function Home() {
|
||||
const [session, setSession] = useState(null)
|
||||
|
||||
-5
@@ -1,8 +1,3 @@
|
||||
/**
|
||||
* ./src/Auth.js
|
||||
* Component to manage logins and sign ups.
|
||||
*/
|
||||
|
||||
import { useState } from 'react'
|
||||
import { supabase } from './supabaseClient'
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ This example provides the steps to build a simple user management app (from scra
|
||||
- [Row Level Security](/docs/guides/auth#row-level-security): data is be protected so that individuals can only access their own data.
|
||||
- Instant [APIs](/docs/guides/api): APIs will be automatically generated when you create your database tables.
|
||||
|
||||
## Video demo
|
||||
<!-- ## Video demo
|
||||
|
||||
Coming soon.
|
||||
|
||||
@@ -35,7 +35,7 @@ Clicking this button the application will:
|
||||
- Fork the example into your own GitHub account.
|
||||
- Prepare the deployed application with all the necessary environment variables.
|
||||
|
||||
If you want to do it yourself, let's get started:
|
||||
If you want to do it yourself, let's get started: -->
|
||||
|
||||
## Project set up
|
||||
|
||||
@@ -69,7 +69,9 @@ values={[
|
||||
4. Click "Run".
|
||||
```
|
||||
|
||||
@todo - add video
|
||||
<video width="99%" muted playsInline controls="true">
|
||||
<source src="/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
|
||||
</video>
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="SQL">
|
||||
@@ -189,7 +191,7 @@ on the browser, and that's completely fine since we have [Row Level Security](/d
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
const supabaseUrl = process.env.REACT_APP_SUPABASE_URL
|
||||
const supabaseAnonKey = process.env.REACT_APP_SUPABASE_URL
|
||||
const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY
|
||||
|
||||
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
|
||||
```
|
||||
@@ -199,22 +201,20 @@ You can find the full contents of this file [here](https://github.com/supabase/s
|
||||
|
||||
### Set up a Login component
|
||||
|
||||
create an auth component
|
||||
|
||||
Component to manage logins and sign ups.
|
||||
Let's set up a React componenet to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords.
|
||||
|
||||
```jsx title="/src/Auth.js"
|
||||
import { useState } from 'react'
|
||||
import { supabase } from './supabaseClient'
|
||||
|
||||
export default function Auth({}) {
|
||||
export default function Auth() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [email, setEmail] = useState('')
|
||||
|
||||
const handleLogin = async (email: string) => {
|
||||
const handleLogin = async (email) => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const { error, user } = await supabase.auth.signIn({ email })
|
||||
const { error } = await supabase.auth.signIn({ email })
|
||||
if (error) throw error
|
||||
alert('Check your email for the login link!')
|
||||
} catch (error) {
|
||||
@@ -225,11 +225,9 @@ export default function Auth({}) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-6">
|
||||
<div className="row flex flex-center">
|
||||
<div className="col-6 form-widget">
|
||||
<h1 className="header">Supabase + React</h1>
|
||||
</div>
|
||||
<div className="col-6 auth-widget">
|
||||
<p className="description">Sign in via magic link with your email below</p>
|
||||
<div>
|
||||
<input
|
||||
@@ -258,32 +256,26 @@ export default function Auth({}) {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Account page
|
||||
|
||||
create an Account component:
|
||||
After a user is signed in we can allow them to edit their profile details and manage their account.
|
||||
|
||||
Allow a logged-in user to manage their account.
|
||||
Let's create a new component for that called `Account.js`.
|
||||
|
||||
```jsx title="src/Account.js"
|
||||
import { useState, useEffect } from 'react'
|
||||
import { supabase } from './supabaseClient'
|
||||
|
||||
export default function Account({ session }) {
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
const [username, setUsername] = useState<string | null>(null)
|
||||
const [website, setWebsite] = useState<string | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [username, setUsername] = useState(null)
|
||||
const [website, setWebsite] = useState(null)
|
||||
const [avatar_url, setAvatarUrl] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
getProfile()
|
||||
}, [session])
|
||||
|
||||
async function signOut() {
|
||||
const { error } = await supabase.auth.signOut()
|
||||
if (error) console.log('Error logging out:', error.message)
|
||||
}
|
||||
|
||||
async function getProfile() {
|
||||
try {
|
||||
setLoading(true)
|
||||
@@ -301,14 +293,15 @@ export default function Account({ session }) {
|
||||
|
||||
setUsername(data.username)
|
||||
setWebsite(data.website)
|
||||
setAvatarUrl(data.avatar_url)
|
||||
} catch (error) {
|
||||
console.log('error', error.message)
|
||||
alert(error.message)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function updateProfile() {
|
||||
async function updateProfile({ username, website, avatar_url }) {
|
||||
try {
|
||||
setLoading(true)
|
||||
const user = supabase.auth.user()
|
||||
@@ -317,6 +310,7 @@ export default function Account({ session }) {
|
||||
id: user.id,
|
||||
username,
|
||||
website,
|
||||
avatar_url,
|
||||
updated_at: new Date(),
|
||||
}
|
||||
|
||||
@@ -335,7 +329,7 @@ export default function Account({ session }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="account">
|
||||
<div className="form-widget">
|
||||
<div>
|
||||
<label htmlFor="email">Email</label>
|
||||
<input id="email" type="text" value={session.user.email} disabled />
|
||||
@@ -360,13 +354,17 @@ export default function Account({ session }) {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button className="button block primary" onClick={() => updateProfile()} disabled={loading}>
|
||||
<button
|
||||
className="button block primary"
|
||||
onClick={() => updateProfile({ username, website, avatar_url })}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? 'Loading ...' : 'Update'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button className="button block" onClick={() => signOut()}>
|
||||
<button className="button block" onClick={() => supabase.auth.signOut()}>
|
||||
Sign Out
|
||||
</button>
|
||||
</div>
|
||||
@@ -375,9 +373,39 @@ export default function Account({ session }) {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Launch!
|
||||
|
||||
Run this in a terminal window:
|
||||
Now that we have all the components in place, let's update `App.js`:
|
||||
|
||||
```jsx title="src/App.js"
|
||||
import './index.css'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { supabase } from './supabaseClient'
|
||||
import Auth from './Auth'
|
||||
import Account from './Account'
|
||||
|
||||
export default function Home() {
|
||||
const [session, setSession] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
setSession(supabase.auth.session())
|
||||
|
||||
supabase.auth.onAuthStateChange((_event, session) => {
|
||||
setSession(session)
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="container" style={{ padding: '50px 0 100px 0' }}>
|
||||
{!session ? <Auth /> : <Account key={session.user.id} session={session} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Once that's done, run this in a terminal window:
|
||||
|
||||
```bash
|
||||
npm install start
|
||||
@@ -386,6 +414,8 @@ npm install start
|
||||
And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app.
|
||||
|
||||
|
||||

|
||||
|
||||
## Bonus: Profile photos
|
||||
|
||||
Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like photos and videos.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
Binary file not shown.
Reference in new issue
Block a user