Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manage User and content adjustment on the dashboard menu #31

Merged
merged 31 commits into from
Jan 9, 2025
Merged
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3252210
new dev
DimzsArdiminda Jan 7, 2025
275e67a
feat: db seed
DimzsArdiminda Jan 7, 2025
048bbda
feat: show on table
DimzsArdiminda Jan 7, 2025
3faba8b
feat: show by slug
DimzsArdiminda Jan 7, 2025
3e51322
feat: show by slug (fiks)
DimzsArdiminda Jan 7, 2025
5380709
feat: add artikel
DimzsArdiminda Jan 7, 2025
53dfa15
fiks: bug button back
DimzsArdiminda Jan 7, 2025
3727fc3
fiks: coloumn on article
DimzsArdiminda Jan 7, 2025
fca8a89
fiks: double slug
DimzsArdiminda Jan 7, 2025
f093d0d
fiks: ui show-article
DimzsArdiminda Jan 7, 2025
2f7311c
on dev
DimzsArdiminda Jan 8, 2025
315f6ea
Merge branch 'main' of https://github.com/gdsc-um/homesite-refactor i…
DimzsArdiminda Jan 8, 2025
0d21ab9
feat: update
DimzsArdiminda Jan 8, 2025
d534c9d
feat: delete
DimzsArdiminda Jan 8, 2025
b6c2e2f
feat: search
DimzsArdiminda Jan 8, 2025
1ef67d3
feat: show artikel on dashboard
DimzsArdiminda Jan 8, 2025
8f6e2e2
feat: show artikel on blog
DimzsArdiminda Jan 8, 2025
b85a265
feat: show list user on admin's dashboard
DimzsArdiminda Jan 8, 2025
574f230
feat: show list user on member's dashboard
DimzsArdiminda Jan 8, 2025
c71c04c
feat: delete user
DimzsArdiminda Jan 9, 2025
09e10fb
build: update user
DimzsArdiminda Jan 9, 2025
50cf8d9
feat: add user
DimzsArdiminda Jan 9, 2025
63102f3
feat: add user
DimzsArdiminda Jan 9, 2025
a2f6be9
feat: mboh lali garap opo
DimzsArdiminda Jan 9, 2025
da9cc9c
feat: search on manage user
DimzsArdiminda Jan 9, 2025
36a3834
fiks: build error
DimzsArdiminda Jan 9, 2025
fa12fc2
fiks: build error 2
DimzsArdiminda Jan 9, 2025
abcfdb8
fiks: build error 3
DimzsArdiminda Jan 9, 2025
c3a8a35
fiks: build error 4
DimzsArdiminda Jan 9, 2025
6e26f6e
fiks: build error 5
DimzsArdiminda Jan 9, 2025
69758ac
fiks: build error 5
DimzsArdiminda Jan 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
build: update user
DimzsArdiminda committed Jan 9, 2025

Verified

This commit was signed with the committer’s verified signature.
fiji-flo Florian Dieminger
commit 09e10fb114dde3cb85b96134ed04e23e61fcb3e7
54 changes: 54 additions & 0 deletions app/admin/dashboard/manage-user/[email]/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"use client";

import React, { FC } from "react";
import { notFound } from "next/navigation";
import UserForm from "../../components/userForm";
import { Userssss } from "../../lib/definition";

interface EditUserPageProps {
params: Promise<{ email: string }>; // `params` adalah Promise
}

const EditUserPage: FC<EditUserPageProps> = ({ params }) => {
const { email } = React.use(params); // Unwrap `params` menggunakan `React.use()`

const [user, setUser] = React.useState<Userssss | null>(null);
const [loading, setLoading] = React.useState<boolean>(true);

React.useEffect(() => {
const fetchUser = async () => {
try {
const res = await fetch(`/api/user/${email}`);
if (!res.ok) {
throw new Error("User not found");
}
const userData: Userssss = await res.json();
setUser(userData);
} catch (error) {
console.error("Error fetching user:", error);
setUser(null);
} finally {
setLoading(false);
}
};

fetchUser();
}, [email]);

if (loading) {
return <div>Loading...</div>;
}

if (!user) {
return <div>User not found</div>;
}

return (
<div className="px-6 py-4 max-w-[80rem] mx-auto flex flex-col gap-4">
<h3 className="text-3xl font-semibold">Edit User</h3>
<UserForm type="EDIT" user={user} />
</div>
);
};

export default EditUserPage;
62 changes: 0 additions & 62 deletions app/admin/dashboard/manage-user/[id]/edit/page.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ const ActionButton: FC<ActionButtonProps> = ({ data }) => {
}

const handleEditClick = () => {
const url = `manage-user/${data.id}/edit`; // Changed to const
const url = `manage-user/${data.email}/edit`; // Changed to const
router.push(url);
}

260 changes: 206 additions & 54 deletions app/admin/dashboard/manage-user/components/userForm.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,217 @@
"use client";

import React, { FC } from 'react'
import { User, UserRole } from '../lib/definition'
import { Label } from '@/components/ui/label'
import { Input } from '@/components/ui/input'
import React, { FC } from "react";
import { Userssss, UserRole, TimRole } from "../lib/definition";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";

import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Button } from '@/components/ui/button'
import { useRouter } from 'next/navigation'
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { useRouter } from "next/navigation";
import toast from "react-hot-toast";

interface UserFormProps {
user?: User,
type: "ADD" | "EDIT"
user?: Userssss;
type: "ADD" | "EDIT";
}

const UserForm: FC<UserFormProps> = ({ user, type }) => {
const router = useRouter();
const router = useRouter();

const userRoles = Object.values(UserRole);
const userRoles = Object.values(UserRole);
const timRoles = Object.values(TimRole);

return (
<>
<form className='flex flex-col gap-6'>
{/* add for profile picture */}
<div className='space-y-1 md:space-y-2'>
<Label className='text-lg ' htmlFor='picture'>Profile Picture </Label> <br />
<small> use link cdn only </small>
<Input type='url' defaultValue={type === "ADD" ? '' : user?.picture} name='picture' id='picture' required />
</div>
<div className='space-y-1 md:space-y-2'>
<Label className='text-lg ' htmlFor='name'>Name</Label> <br />
<small> as listed on bevy </small>
<Input type='text' defaultValue={type === "ADD" ? '' : user?.name} name='name' id='name' required />
</div>
<div className='space-y-1 md:space-y-2'>
<Label className='text-lg ' htmlFor='email'>Email</Label> <br />
<small> as listed on bevy </small>
<Input type='email' defaultValue={type === "ADD" ? '' : user?.email} name='email' id='email' required />
</div>
<div className='space-y-1 md:space-y-2'>
<Label className='text-lg ' htmlFor='role'>Role</Label>
<Select defaultValue={type === "ADD" ? '' : user?.role} name='role' required>
<SelectTrigger className="">
<SelectValue placeholder="Select a role" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{userRoles.map(role => {
return <SelectItem key={role} value={role}>{role}</SelectItem>
})}
</SelectGroup>
</SelectContent>
</Select>
</div>
<div className='flex justify-end gap-4 mt-4 lg:mt-10'>
<Button type='button' onClick={() => router.back()} variant='ghost'>{type === "ADD" ? 'Cancel' : 'Back'}</Button>
<Button>Save</Button>
</div>
</form>
</>
)
}
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

const formData = new FormData(e.currentTarget);
const data = Object.fromEntries(formData.entries());
const method = type === 'EDIT' ? 'PUT' : 'POST';
const url = type === 'EDIT' ? `/api/user/${user?.email}` : '/api/user';

try {
const response = await fetch(url,{
method,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})

// Handle status
if (response.ok) {
const updatedUser = await response.json();
toast.success('User updated successfully');
router.push('/admin/dashboard/manage-user');
}else{
const error = await response.json();
if (response.status === 400 && error.error === 'Slug already exists') {
toast.error('Slug already exists. Please choose a different one.');
} else {
// toast.error('Sek Error');
// console.log(errorResponse);
toast.error('Something went wrong');
}
}
} catch (error) {
toast.error('An error occurred while submitting the form');
}
};

return (
<>
<form className="flex flex-col gap-6" onSubmit={handleSubmit}>
<div className="space-y-1 md:space-y-2">
<Label className="text-lg " htmlFor="name">
Name
</Label>
<br />
<small> as listed on bevy </small>
<Input
type="text"
defaultValue={type === "ADD" ? "" : user?.name}
name="name"
id="name"
required
/>
</div>
<div className="space-y-1 md:space-y-2">
<Label className="text-lg " htmlFor="nim">
NIM
</Label>
<br />
<Input
type="text"
defaultValue={type === "ADD" ? "" : user?.nim}
name="nim"
id="nim"
required
/>
</div>
<div className="space-y-1 md:space-y-2">
<Label className="text-lg " htmlFor="email">
Email
</Label>
<br />
<small> as listed on bevy </small>
<Input
type="email"
defaultValue={type === "ADD" ? "" : user?.email}
name="email"
id="email"
required
readOnly={type === "EDIT"}
/>
</div>
<div className="space-y-1 md:space-y-2">
<Label className="text-lg " htmlFor="email">
Password
</Label>
<br />
{type === "EDIT" ? <small> Leave blank to keep the same password </small> : <small> as listed on bevy </small>}
<Input
type="text"
defaultValue={type === "ADD" ? "" : user?.password}
name="text"
id="text"
required
// readOnly={type === "EDIT"}
/>
</div>
<div className="space-y-1 md:space-y-2">
<Label className="text-lg " htmlFor="profil_bevy">
Profile Bevy
</Label>
<br />
<small> use link for bevy </small>
<Input
type="url"
defaultValue={type === "ADD" ? "" : user?.profil_bevy}
name="profil_bevy"
id="profil_bevy"
required
/>
</div>
<div className="space-y-1 md:space-y-2">
<Label className="text-lg " htmlFor="picture">
Profile Picture
</Label>
<br />
<small> use link cdn only </small>
<Input
type="url"
defaultValue={type === "ADD" ? "" : user?.avatar}
name="avatar"
id="picture"
required
/>
</div>
<div className="space-y-1 md:space-y-2">
<Label className="text-lg " htmlFor="role_tim">
Role Team
</Label>
<Select
defaultValue={type === "ADD" ? "" : user?.role_tim}
name="role_tim"
required
>
<SelectTrigger>
<SelectValue placeholder="Select a role" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{timRoles.map((role) => (
<SelectItem key={role} value={role}>
{role}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</div>
<div className="space-y-1 md:space-y-2">
<Label className="text-lg " htmlFor="role">
Role
</Label>
<Select
defaultValue={type === "ADD" ? "" : user?.role}
name="role"
required
>
<SelectTrigger>
<SelectValue placeholder="Select a role" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{userRoles.map((role) => (
<SelectItem key={role} value={role}>
{role}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</div>
<div className="flex justify-end gap-4 mt-4 lg:mt-10">
<Button
type="button"
onClick={() => router.back()}
variant="ghost"
>
{type === "ADD" ? "Cancel" : "Back"}
</Button>
<Button type="submit">Save</Button>
</div>
</form>
</>
);
};

export default UserForm
export default UserForm;
Loading