Skip to content

Commit

Permalink
Merge pull request #484 from Sid-80/feat/480
Browse files Browse the repository at this point in the history
feat: profile and dashboard
  • Loading branch information
subhadeeproy3902 authored Jul 19, 2024
2 parents 85724b1 + 00d5e29 commit 071f7b7
Show file tree
Hide file tree
Showing 13 changed files with 322 additions and 164 deletions.
9 changes: 8 additions & 1 deletion src/app/Redux/Auth/auth-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,15 @@ export const auth = createSlice({
isAuth: true,
};
},
updateUser: (state, action: PayloadAction<any>) => {
state.user = {
...state.user,
firstName:action.payload.firstName,
lastName:action.payload.lastName,
};
},
},
});

export const { logIn, logOut } = auth.actions;
export const { logIn, logOut, updateUser } = auth.actions;
export default auth.reducer;
17 changes: 17 additions & 0 deletions src/app/api/dashboard/public/save/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import FileModel from "@/models/file";
import { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export const PUT = async (req: NextRequest, res: NextResponse) => {
try {
const {whiteboard, document, fileId} = await req.json();
console.log(document,whiteboard)

await FileModel.updateOne({_id:fileId},{whiteboard, document});

return NextResponse.json({ status: "Updated" }, { status: 200 });
} catch (error) {
console.error("Error in health endpoint:", error);
return NextResponse.json({ message: 'Error occurred!' }, { status: 500 });
}
};
34 changes: 34 additions & 0 deletions src/app/api/dashboard/save/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { AuthMiddleware } from "@/Middleware/AuthMiddleware";
import FileModel from "@/models/file";
import { ApiUser } from "@/types/types";
import { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export const PUT = async (req: NextRequest, res: NextResponse) => {
try {
const result = await AuthMiddleware(req);
// If middleware returns NextResponse.next(), proceed with API logic
if (result instanceof NextResponse) {

const {whiteboard, document, fileId} = await req.json();
console.log(whiteboard,document)


if(!whiteboard || !document || !fileId){
return NextResponse.json(`Access Denied!!`, {status:404});
}

const user: ApiUser = JSON.parse(req.headers.get("user") || "{}");

await FileModel.updateOne({_id:fileId},{whiteboard, document});

return NextResponse.json({ status: "Updated" }, { status: 200 });
} else {
// Handle any errors from the middleware
return result;
}
} catch (error) {
console.error("Error in health endpoint:", error);
return NextResponse.json({ message: 'Error occurred!' }, { status: 500 });
}
};
48 changes: 24 additions & 24 deletions src/app/api/files/getFileById/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@ import FileModel from "@/models/file";
import { NextResponse } from "next/server";

export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {

request: Request,
{ params }: { params: { id: string } }
) {
try {
const result = await AuthMiddleware(request);
if (result instanceof NextResponse) {
try {
const { id } = params;

if (!id) return new Response("Parameters missing!!", { status: 401 });

await mongoDB();
const files = await FileModel.findById({_id:id}).populate("createdBy")
return NextResponse.json(files,{ status: 200 });
} catch (err) {
return NextResponse.json(`Err : ${err}`, {status:500});
}
} else {
return result;
}
}

const { id } = params;

if (!id) return new Response("Parameters missing!!", { status: 401 });

await mongoDB();

const files = await FileModel.findById({ _id: id }).populate("createdBy");

if (!files.filePrivate) return NextResponse.json(files, { status: 200 });

if (result instanceof NextResponse) {
return NextResponse.json(files, { status: 200 });
} else {
return result;
}
} catch (err) {
return NextResponse.json(`Err : ${err}`, { status: 500 });
}
}
1 change: 0 additions & 1 deletion src/app/api/files/update/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export async function PUT(
await mongoDB();

const {fileName, filePrivate, fileId, archive} = await request.json()
console.log(fileName, filePrivate, fileId, archive)

if(!fileName || filePrivate === undefined || archive === undefined || !fileId){
return NextResponse.json(`Access Denied!!`, {status:404});
Expand Down
32 changes: 32 additions & 0 deletions src/app/api/user/update/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { AuthMiddleware } from "@/Middleware/AuthMiddleware";
import UserModel from "@/models/user";
import { ApiUser } from "@/types/types";
import { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export const PUT = async (req: NextRequest, res: NextResponse) => {
try {
const result = await AuthMiddleware(req);
// If middleware returns NextResponse.next(), proceed with API logic
if (result.status==200) {

const {firstName, lastName} = await req.json();

if(!firstName || !lastName ){
return NextResponse.json(`Access Denied!!`, {status:404});
}

const user: ApiUser = JSON.parse(req.headers.get("user") || "{}");

await UserModel.updateOne({_id:user._id},{firstName, lastName});

return NextResponse.json({ status: "Updated" }, { status: 200 });
} else {
// Handle any errors from the middleware
return result;
}
} catch (error) {
console.error("Error in health endpoint:", error);
return NextResponse.json({ message: 'Error occurred!' }, { status: 500 });
}
};
71 changes: 44 additions & 27 deletions src/app/dashboard/settings/_components/SettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,46 +14,53 @@ import {
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { toast } from "sonner";
import { useConvex } from "convex/react";
import { api } from "../../../../../convex/_generated/api";
import { Id } from "../../../../../convex/_generated/dataModel";

type USER = {
name: string;
image: string;
email: string;
_id:string;
};
import { USER } from "@/types/types";
import createAxiosInstance from "@/config/AxiosProtectedRoute";
import { updateProfileUrl } from "@/lib/API-URLs";
import { useDispatch } from "react-redux";
import { updateUser } from "@/app/Redux/Auth/auth-slice";

type Props = {
savedData: USER;
image:string;
};

const FormSchema = z.object({
newName: z.string().min(1, {
message: "Username required!",
firstName: z.string().min(1, {
message: "Minimum Length should be 3!",
}),
lastName: z.string().min(3, {
message: "Minimum Length should be 3!",
}),
});

export function SettingsForm({ savedData,image }: Props) {
const convex = useConvex();

const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues: {
newName: savedData.name,
firstName: savedData.firstName,
lastName: savedData.lastName,
},
});

const axiosInstance = createAxiosInstance(savedData.accessToken);
const dispatch = useDispatch();

async function onSubmit(data: z.infer<typeof FormSchema>) {
const res = await convex.mutation(api.user.updateUser,{
_id:savedData._id as Id<"user">,
name:data.newName,
email:savedData.email,
image:image
})
toast("User updated !!")

const { firstName, lastName} = data;

try {
const res = await axiosInstance.put(updateProfileUrl,{firstName, lastName});
if(res.status === 200) {
dispatch(updateUser({firstName,lastName}));
toast.success("User updated !!")
}
} catch (err) {
console.log(err);
}

}

return (
Expand All @@ -76,16 +83,26 @@ export function SettingsForm({ savedData,image }: Props) {
</FormItem>
<FormField
control={form.control}
name="newName"
name="firstName"
render={({ field }) => (
<FormItem className="w-full">
<FormLabel className="px-2">First Name</FormLabel>
<FormControl>
<Input placeholder="First Name..." {...field} className="" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="lastName"
render={({ field }) => (
<FormItem className="w-full">
<FormLabel className="px-2">Username</FormLabel>
<FormLabel className="px-2">Last Name</FormLabel>
<FormControl>
<Input placeholder="Name..." {...field} className="" />
<Input placeholder="Last Name..." {...field} className="" />
</FormControl>
<FormDescription className="px-2">
Enter username here!
</FormDescription>
<FormMessage />
</FormItem>
)}
Expand Down
32 changes: 8 additions & 24 deletions src/app/dashboard/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,23 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import Navbar from "./_components/Navbar";
import { Separator } from "@/components/ui/separator";
import { useEffect, useState } from "react";
import { useConvex } from "convex/react";
import { api } from "../../../../convex/_generated/api";
import { SettingsForm } from "./_components/SettingsForm";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Card } from "@/components/ui/card";
import { PencilIcon } from "lucide-react";
import { toast } from "sonner";
import { RootState } from "@/config/store";
import { useSelector } from "react-redux";
import { USER } from "@/types/types";

export default function Page() {
const convex = useConvex();
const [savedData, setSavedData] = useState<any>(null);
const [image, setImage] = useState<string>("");
const user = useSelector((state:RootState)=>state.auth.user)

useEffect(() => {
const getData = async () => {
const result = await convex.query(api.user.getUser, {
email: user.email,
});
setSavedData(result[0]);
setImage(result[0].image);
};
if (user.isAuth) {
getData();
}
}, [user]);
const user:USER = useSelector((state:RootState)=>state.auth.user)

return (
<div className="flex flex-col">
<Navbar />
{user && savedData && (
{user && (
<div className="flex w-full h-full xl:p-5 items-center justify-center">
<Card className="flex w-[300px] rounded-lg overflow-hidden relative sm:w-[700px] flex-col items-center justify-center my-5 sm:my-0 p-10 gap-6">
<div className="absolute w-full h-[100px] sm:h-[140px] z-0 gradientBackground top-0"></div>
Expand All @@ -51,12 +35,12 @@ export default function Page() {
<AvatarImage src={image} />
<AvatarFallback className=" text-2xl">
{user.firstName.charAt(0)}
{user?.lastName.charAt(0)}
{user.lastName.charAt(0)}
</AvatarFallback>
</Avatar>
<div className="flex flex-col items-center justify-center">
<h1 className=" font-bold">{savedData.name}</h1>
<p className=" text-gray-400">{savedData.email}</p>
<h1 className=" font-bold">{user.firstName}{" "}{user.lastName}</h1>
<p className=" text-gray-400">{user.email}</p>
</div>
<div className="flex flex-col sm:flex-row gap-3">
<Button variant={"secondary"}>Change Picture</Button>
Expand All @@ -71,7 +55,7 @@ export default function Page() {
</Button>
</div>
<Separator />
<SettingsForm image={image} savedData={savedData} />
<SettingsForm image={image} savedData={user} />
</Card>
</div>
)}
Expand Down
Loading

0 comments on commit 071f7b7

Please sign in to comment.