Skip to content

Commit

Permalink
User Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
fevziatanoglu committed Nov 16, 2024
1 parent b7176fb commit 6ac952f
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 28 deletions.
58 changes: 37 additions & 21 deletions components/forms/AccountProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use client";

import { FormEvent, useEffect, useRef, useState } from "react";
import { updateUser } from "@/libs/actions/user.actions";
import { usePathname, useRouter } from "next/navigation";
import { FormEvent, useState } from "react";

interface Props {
user: {
Expand All @@ -15,37 +17,49 @@ interface Props {
}

export default function AccountProfile({ user, btnTitle }: Props) {
// ADD VALIDATION
const [imgUrl, setImgUrl] = useState<string | null>(user.image);
const imgUrlRef = useRef<HTMLInputElement>(null);
const pathname = usePathname();
const router = useRouter();
// SUBMIT
async function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const data = new FormData(event.currentTarget);
await updateUser(
user.id,
data.get("username") as string,
data.get("name") as string,
data.get("bio") as string,
// data.get("image") as string,
(imgUrl || "/profile.svg") as string,
pathname
)
.then((res) => {
console.log(res);
if (pathname == "/profile/edit") {
router.back();
} else {
router.push("/");
}
})
.catch((err) => {
console.log(err);
});
}

function handleImgChange(event: React.ChangeEvent<HTMLInputElement>) {
const file = event.target.files?.[0];
if (file) {
const reader = new FileReader();

// When the file is loaded, set the image URL to its data URL
reader.onload = () => {
setImgUrl(reader.result as string);
};

reader.readAsDataURL(file); // Read the file as a data URL
reader.readAsDataURL(file);
} else {
setImgUrl(null); // Clear the preview if no file is selected
setImgUrl(null);
}
}

function deleteSelectedImg() {
setImgUrl(null);
}

function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
// const data = new FormData(event.currentTarget);
const data = new FormData(event.currentTarget);

console.log(Object.fromEntries(data.entries()), imgUrl, data.get("image"));
}

return (
<div>
Account Settings
Expand All @@ -66,15 +80,15 @@ export default function AccountProfile({ user, btnTitle }: Props) {
>
Choose a profile picture
</label>
{imgUrl && (
{/* {imgUrl && (
<button
type="button"
className="bg-red-500 px-2 rounded-full text-white"
onClick={deleteSelectedImg}
>
X
</button>
)}
)} */}

<input
id="image"
Expand Down Expand Up @@ -118,6 +132,7 @@ export default function AccountProfile({ user, btnTitle }: Props) {
id="username"
name="username"
type="text"
defaultValue={user.username}
required
className="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"
/>
Expand All @@ -134,6 +149,7 @@ export default function AccountProfile({ user, btnTitle }: Props) {
<textarea
id="bio"
name="bio"
defaultValue={user.bio}
className="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"
></textarea>
</div>
Expand Down
39 changes: 34 additions & 5 deletions libs/actions/user.actions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,38 @@
"use server"
"use server";

import connectToDB from "../mongoose"
import { revalidatePath } from "next/cache";
import User from "../models/user.model";
import connectToDB from "../mongoose";

export async function updateUser(
userId: string,
username: string ,
name: string,
bio: string,
image: string,
path: string
): Promise<void> {
connectToDB();

export async function updateUser(): Promise<void> {
connectToDB();
try {
await User.findOneAndUpdate(
{ id: userId },
{
username: username.toLowerCase(),
name,
bio,
image,
onboarded: true,
},
// upsert => update if exist , create if not exist
{ upsert: true }
);

}
// update cached data at profile/edit path (without waiting revalidation period)
if (path === "profile/edit") {
revalidatePath(path);
}
} catch (error: any) {
throw new Error(error.message);
}
}
17 changes: 17 additions & 0 deletions libs/models/user.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import mongoose from "mongoose";


const userSchema = new mongoose.Schema({
id: { type:String , require: true},
username : { type:String , require: true},
name : { type:String },
bio : { type:String },
image : { type:String },
posts: [{ type: mongoose.Schema.Types.ObjectId, ref: "Post" }],
onboarded : { type:Boolean , default: false}

});

// from database || create new model
const User = mongoose.models.User || mongoose.model("User" , userSchema);
export default User;
3 changes: 3 additions & 0 deletions libs/mongoose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ let isConnectedDB = false;
export default async function connectToDB() {
if (!process.env.MONGODB_URL) return console.log("DB URL NOT FOUND");
if (isConnectedDB) return console.log("Already connected to MongoDB");
console.log(process.env.MONGODB_URL)
try {
await mongoose.connect(process.env.MONGODB_URL);
console.log("Connected to MongoDB");

} catch (err) {
console.log(err);
}
Expand Down
17 changes: 17 additions & 0 deletions libs/validations/userValidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as z from "zod";

export const UserValidation = z.object({
image: z.string().url().nonempty(),
name: z
.string()
.min(3, { message: "Minimum 3 characters." })
.max(30, { message: "Maximum 30 caracters." }),
username: z
.string()
.min(3, { message: "Minimum 3 characters." })
.max(30, { message: "Maximum 30 caracters." }),
bio: z
.string()
.min(3, { message: "Minimum 3 characters." })
.max(1000, { message: "Maximum 1000 caracters." }),
});
12 changes: 11 additions & 1 deletion package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"mongoose": "^8.8.1",
"next": "15.0.3",
"react": "19.0.0-rc-66855b96-20241106",
"react-dom": "19.0.0-rc-66855b96-20241106"
"react-dom": "19.0.0-rc-66855b96-20241106",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "^20",
Expand Down

0 comments on commit 6ac952f

Please sign in to comment.