incubrain / astrotribe

Where astronomers and space-tech enthusiast get their news
https://astronera.org
6 stars 2 forks source link

feat: profile/settings with user updates #23

Open Drew-Macgibbon opened 1 year ago

Drew-Macgibbon commented 1 year ago

We will start simple and expand functionality as the application grows. A strong foundation is key here, as we scale the application we will add tabs for other settings like notifications and billing etc..

Let's start by creating the structure as JSON:

[
  {
    "account": {
      "given_name": "Drew",
      "surname": "MacGibbon",
      "introduction": "some info about the person",
      "favourite_quote": "fav quote"
    },
    "notifications": "placeholder",
    "billing": "placeholder",
  }
]

Technologies to use:

Things to consider:

use this design as reference

Image

v0.5: settings page with tabs, basic func

v1(mvp): image upload, cropping & optimization

Drew-Macgibbon commented 1 year ago

@aayu5hgit create a new branch for this like last time.

This is an app page astrotribe/settings, think about the requirements listed and add your questions as a comment.

aayu5hgit commented 1 year ago

@Drew-Macgibbon so what I understood from above is that the initial step is to create a user settings section in the pages/astrotribe directory which will consist of the user details and one can modify the same. Am I correct?

Drew-Macgibbon commented 1 year ago

@aayu5hgit correct, I think the best approach is to use tabs on the page. nuxthq/ui doesn't have a tabs component yet, so for the time being we can just create the layout with disabled buttons since we just have the account information to start.

By the time we need to use tabs they will have created the component: https://volta.net/nuxtlabs/ui/issues/162

aayu5hgit commented 1 year ago

@Drew-Macgibbon I have created a directory astrotribe/settings where we have dynamic page settings/[username] and likewise each user can view/update their detail(s). I will use the JSON file (users.json under data/app/accounts) for practicing/testing the functionality of updating the data, is that okay (for now)?

aayu5hgit commented 1 year ago

@Drew-Macgibbon Jist of today's work:

aayu5hgit commented 1 year ago

@Drew-Macgibbon sharing the progress,

Have a look at the recording below and suggest the changes (if any)

https://github.com/incubrain/astrotribe/assets/86314754/7f815ceb-aadc-45b5-81e8-af64f2b79566

Drew-Macgibbon commented 1 year ago

@aayu5hgit Speedy! Great work πŸ˜„

If you're up for it, you can look into creating the server/api/user/update-[id].ts endpoint. The other server/api files can be used as reference. Use Prisma update I've sent a supabase invite to your email.

aayu5hgit commented 1 year ago

@Drew-Macgibbon thanks πŸ˜„

Sure, I'll start understanding how things work in prisma and will implement it for updating the data once I get the knowledge. Also, will accept the supabse invite.

aayu5hgit commented 1 year ago

@Drew-Macgibbon I was going through server/api/user/update-[id].ts and I wanted to ask that I have to use the endpoint for the profile updation whenever user does so (which will update the same in supabase), right?

To add on, is it okay if I take some time to understand the process thoroughly? (as I'll be working with all of it for a longer period of time so I think it's better to get the knowledge of the procedure and apply it step by step)

Drew-Macgibbon commented 1 year ago

@aayu5hgit sure, take your time.

Yes that endpoint will host the prisma.update call. You can use the prisma client (defined in server/utils) in any api file without having to import it.

You can also name the endpoint update-[id].post.ts to only allow post requests. Then you can send a body with:

useFetch(`/api/user/update-${id}`, { addBody })

unwrapping it on the endpoint with useBody(event).

aayu5hgit commented 1 year ago

@Drew-Macgibbon thanks, will get on to it as the way you suggested and I'll ping if I have doubt(s).

Drew-Macgibbon commented 1 year ago

@aayu5hgit sorry it's const body = await readBody(req) not useBody

this might be helpful: https://www.jsdocs.io/package/h3#package-functions

Also I was working on an API route today, so this might be helpful.

const { data, error } = useFetch('/api/starred-repos', {
  watch: [page, direction],
  body: { direction },
  method: 'POST'
})

note that watch: calls useFetch again if page or direction refs change.

then I am just watching the necessary properties and updating when needed. (this will be refactored, just an example)

watch(data, (newData) => {
  if (newData) {
    const body = newData.body
    list.value = body.repos
    totalItems.value = body.totalCount
  }
})

watch(error, (newError) => {
  if (newError) {
    throw createError(`Error fetching starred repos: ${newError}`)
  }
})
aayu5hgit commented 1 year ago

@Drew-Macgibbon I am using the same format as yours, sharing a snip of it

I've to remove the scope where I was working with accounts.json data because it's creating a bit of confusion as now I've to connect and make changes into the supabase database.

  const { data, error } = await useFetch(`/api/users/update-${user.id}`, {
    method: 'POST',
    body: JSON.stringify(user.account)
  })
  console.log(data)
  console.log(user)
aayu5hgit commented 1 year ago

@Drew-Macgibbon can you share (WhatsApp) the Database URL that we are importing in the prisma.schema

aayu5hgit commented 1 year ago

@Drew-Macgibbon I'm not able to understand the following error of prisma client while updating the user account as the following is shown:

image

I've passed the id to check the user id and update the body of that user id if there is any change

 const { data, error } = await useFetch(`/api/users/update-${name}`, {
    id: user.account.id,
    method: 'POST',
    body: JSON.stringify(user?.account)
  })
Drew-Macgibbon commented 1 year ago

@aayu5hgit Show me the prisma client call.

Also, passing id like that probably won't work. It can be passed as part of the body. My initial thoughts are that you either don't have access to the variable you're trying to use (id) or it's the wrong type. Or the id doesn't match the database id for shweta.

I also just noticed the error says you're using findFirst which is a READ query, so you will not be able to update the data. We should be using update:

const user = await prisma.public_users.update({
  where: { id: 1 },
  data: { email: 'alice@prisma.io' },
})

finally, if you're still having issues try a fresh Run of prisma db pull to update the Prisma schema and prisma generate to update Prisma Client.

fyi this might be helpful for the profile image update: https://formkit.com/inputs/file, however if you've already made a start let me know.

aayu5hgit commented 1 year ago

@Drew-Macgibbon I'll evaluate the id part and will pass in the body.

Also, I am using prisma.public_users.update query to update but I guess the file you initially had created for the prisma client had the findFirst and that file is getting called when I pass something (or access) to the prisma client.

This is what my client looks like:

const user = await client.public_users.update({
    where: {
      id: Number(id)
    },
    data: {
      email: body.email,
      username: body.username,
      given_name: body.name,
      surname: body.surname,
      avatar: body.avatar_url,
      updated_at: new Date()
    }
  })
Drew-Macgibbon commented 1 year ago

@aayu5hgit ahh I found the issue, for some reason the users/[id].ts file is getting called even when calling update-[id] endpoint. To fix this just change the folder structure to this users/update/[id].post.ts, then you can call like so:

const test = async () => {
  const id = 1
  await useFetch(`/api/users/update/${id}`, {
    method: 'POST',
    body: JSON.stringify({ quote: 'dynamic test' })
  })
}

await client.public_users.update({
      where: {
        id: Number(id)
      },
      data: {
        quote: 'testing updating the quote'
      }
    })

FYI: this is the live database, so create a new row in the users table to test the updating functionality

aayu5hgit commented 1 year ago

@Drew-Macgibbon thanks, will make the changes and let you know the progress.

aayu5hgit commented 1 year ago

@Drew-Macgibbon I tried to update the details with some hard-code (just to test) and it's working good I guess, have a look

image

Now have to pass all the user profile values and link it with handleSubmit function which will submit and update the passed data to supabase directly.

aayu5hgit commented 1 year ago

@Drew-Macgibbon Um, did you clear the users table from supabase? Because I'm not able to fetch any user Id to get and update their details...

Here's the code error:

image

image

And this is the users table (which I see empty rn):

image

aayu5hgit commented 1 year ago

@Drew-Macgibbon everything's running as it should be but the details are not getting passed in the body of [id].post.ts Can you identify and correct me where am I getting things wrong?

image

image

According to me, I'm messing up over here, with the "body"

image

Error Lies somewhere here only, as I'm not able to fetch the data of the body

const body = Request.body 

  const client = useClient()

  try {
    const user = await client.users.update({
      where: {
        id
      },
      data: {
        // Error Scope
         given_name: body.given_name,
         surname: body.surname,
         email: body.email,
         introduction: body.introduction,
         quote: body.quote
      }
    })
aayu5hgit commented 1 year ago

@Drew-Macgibbon Finally, understood the error and solved!πŸ₯³

// We didn't had to call the request instead pass the event param to collect the data present in the body
const body = await readBody(event)

image

I've completed the supabase users table updation tast where a user can modify/update the text data of their profile. Will be looking forward to change the profile pictures too, but we can have discussions on that initially.

aayu5hgit commented 1 year ago

@Drew-Macgibbon I have committed the code.

Just want you to know that the initial (default) user details sometimes don't load on my localhost, so if the same happens in your machine, can you look out and tell me?

aayu5hgit commented 1 year ago

@Drew-Macgibbon no need to worry regarding the above comment, I've fixed things properly.

Took me so much time to understand and fix this minute (🀏🏻) change, but I'm happy that I did it. will push the changes in a few!

aayu5hgit commented 1 year ago

@Drew-Macgibbon Did some minor changes, made a successToast() function using a library to enhance UX.

Visit the following preview link for a black box review: https://astrotribe-h5ifmgm2k-incubrain.vercel.app/astrotribe/settings/33

Drew-Macgibbon commented 1 year ago

@aayu5hgit great, hold work on this until I finish reviewing the initial changes.

Drew-Macgibbon commented 1 year ago

@aayu5hgit ok done making changes. I'll do a better job giving you direction in the future.

I'd also appreciate it if you make smaller/more frequent commits, that way I can give you feedback earlier.

Reason for changes:

pull the code down and assess the changes, I've added some comments. I left your code, copy over anything needed then rename the settings/index.vue file to [id].vue

Tasks Left:

let me know if you have any questions.

aayu5hgit commented 1 year ago

@Drew-Macgibbon sure, I'll make smaller and frequent commits.

Talking about the things I'll need to work upon are:

Am I correct?

Drew-Macgibbon commented 1 year ago

@aayu5hgit yes correct.

aayu5hgit commented 1 year ago

@Drew-Macgibbon I have commited the code and did the following:

Check: Preview