Skip to content

Commit

Permalink
feat: allow users to delete profile; fix issue with website input
Browse files Browse the repository at this point in the history
  • Loading branch information
ericrallen committed Jan 15, 2025
1 parent b533a14 commit 2fca457
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 30 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ NEXT_PUBLIC_SUPABASE_PROJECT_ID=""
NEXT_PUBLIC_SUPABASE_URL="https://$NEXT_PUBLIC_SUPABASE_PROJECT_ID.supabase.co"
NEXT_PUBLIC_SUPABASE_STORAGE_URL="https://$NEXT_PUBLIC_SUPABASE_PROJECT_ID.supabase.in"
NEXT_PUBLIC_SUPABASE_ANON_KEY=""
# NEVER prefix this with `NEXT_PUBLIC_`; this is only used to delete a user's profile and bypass the RLS that prevents it
SUPABASE_SERVICE_ROLE_KEY=""

# How do users request new psychometrics?
NEXT_PUBLIC_PSYCHOMETRIC_REQUEST_URL=""
Expand Down
30 changes: 16 additions & 14 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
token: ${{ secrets.GH_AUTH_TOKEN }}

Expand All @@ -32,21 +32,23 @@ jobs:
git config --global user.email "bot@workwithme.app"
git config --global user.name "Work w/ Me Release Bot"
- uses: actions/setup-node@v2
- uses: actions/setup-node@v4
with:
node-version: 14

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
cache: 'npm'
cache-dependency-path: package-lock.json

# - name: Cache node modules
# uses: actions/cache@v4
# env:
# cache-name: cache-node-modules
# with:
# path: ~/.npm
# key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
# restore-keys: |
# ${{ runner.os }}-build-${{ env.cache-name }}-
# ${{ runner.os }}-build-
# ${{ runner.os }}-

- name: Install dependencies
run: npm ci
Expand Down
25 changes: 18 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/EditProfile/Website/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Website = (): React.ReactElement => {
return (
<FormControl marginBottom="20px">
<FormLabel>Website</FormLabel>
<Input onChange={onWebsiteChange} value={website} />
<Input onBlur={onWebsiteChange} defaultValue={website} />
<FormHelperText>
Provide a URL where people can learn more about you. We recommend a personal blog or
LinkedIn profile, but you do you.
Expand Down
1 change: 0 additions & 1 deletion src/context/UserProfileContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ export const UserProfileProvider = ({
if (typeof username !== 'undefined' && username !== null) {
gitHubUserDetails(username)
.then((gitHubProfile) => {
console.log(gitHubProfile)
const { avatar_url: avatarUrl } = gitHubProfile
// @ts-expect-error avatar_url is defined as a string; not sure why tsc isn't cooperating
setAvatarUrl(avatarUrl)
Expand Down
32 changes: 32 additions & 0 deletions src/pages/api/user/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { createClient } from '@supabase/supabase-js'

import type { NextApiRequest, NextApiResponse } from 'next'

async function handler(req: NextApiRequest, res: NextApiResponse): Promise<void> {
const { userId } = req.body

console.log('userId:', userId)

if (typeof userId !== 'undefined') {
console.log('KEY:', process.env.SUPABASE_SERVICE_ROLE_KEY)

const supabaseAdmin = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL ?? '',
process.env.SUPABASE_SERVICE_ROLE_KEY ?? ''
)

const { error } = await supabaseAdmin.auth.api.deleteUser(userId)

if (error !== null) {
res.status(200)
} else {
res.status(406).json({ error })
}
} else {
res.status(401)
}

res.end()
}

export default handler
27 changes: 25 additions & 2 deletions src/pages/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,25 @@ import Website from '../components/EditProfile/Website'
import useProfile from '../hooks/useProfile'

const Profile: NextPage = (): React.ReactElement => {
const { updateProfile, deleteProfile } = useProfile()
const { updateProfile, deleteProfile, logOut } = useProfile()

const onClickDeleteProfile = (): void => {
const reallyDeleteProfile = confirm(
'Are you sure you want to delete your profile? This action is irreversible.'
)

if (reallyDeleteProfile) {
deleteProfile()
.then(() => {
logOut().catch((error) => {
console.error(error)
})
})
.catch((error) => {
console.error(error)
})
}
}

return (
<Page authenticated>
Expand All @@ -27,7 +45,12 @@ const Profile: NextPage = (): React.ReactElement => {
<Button onClick={updateProfile} colorScheme="teal">
Update Profile
</Button>
<Button onClick={deleteProfile} colorScheme="red" variant="link" fontWeight="normal">
<Button
onClick={onClickDeleteProfile}
colorScheme="red"
variant="link"
fontWeight="normal"
>
Delete Profile
</Button>
</ButtonGroup>
Expand Down
11 changes: 7 additions & 4 deletions src/services/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,13 @@ export const updateUserProfile = async (

export const deleteUserProfile = async (userId: definitions['profiles']['id']): Promise<void> => {
try {
await supabase
.from<definitions['profiles']>('profiles')
.delete({ returning: 'minimal' })
.match({ id: userId })
await fetch('/api/user/delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ userId }),
})

await supabase.storage.from('avatars').remove([`public/${userId}.png`])
} catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion src/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { extendTheme, ThemeConfig } from '@chakra-ui/react'
import { extendTheme, type ThemeConfig } from '@chakra-ui/react'

const config: ThemeConfig = {
initialColorMode: 'system',
Expand Down

0 comments on commit 2fca457

Please sign in to comment.