Skip to content
This repository has been archived by the owner on Aug 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #23 from trashtrack-team/feat/user
Browse files Browse the repository at this point in the history
  • Loading branch information
yehezkieldio authored Mar 1, 2024
2 parents a50a192 + 2c3057d commit 18e5505
Show file tree
Hide file tree
Showing 18 changed files with 1,204 additions and 29 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ note.txt
.DS_Store
Thumbs.db

.nx/cache
.nx/cache

# to be removed later
libs/utils/src/app-constants.ts
2 changes: 2 additions & 0 deletions apps/api/src/model/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ export class UserService extends BaseService<UserModel, UserCreateDTO, UserUpdat
throw new BadRequestException(`New Password Does Not Match Confirmation Password`);
}

payload.newPassword = await encryption.hash(payload.newPassword);

const model: UserModel = await this.prismaService[this.modelName].update({
where: { id },
data: { password: payload.newPassword },
Expand Down
14 changes: 10 additions & 4 deletions apps/app/src/components/operator-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { Icons, OperatorContext } from "@trashtrack/ui";
import OperatorDashboard from "../pages/operator/dashboard";
import { useContext } from "react";
import { UsersPage } from "../pages/operator/user/users.page";
import { DetailedUserPage } from "../pages/operator/user/detailed-user.page";
import { ChangeUserPage } from "../pages/operator/user/change-user.page";
import { CreateUserPage } from "../pages/operator/user/create-user.page";
import { DetailedUserPage } from "../pages/operator/user/detailed-user.page";
import ChangePasswordPage from "../pages/operator/user/change-password.page";

const OperatorTabs: React.FC = () => {
const operator = useContext(OperatorContext);
Expand All @@ -22,8 +23,13 @@ const OperatorTabs: React.FC = () => {

<Route path="/operator/tabs/user" render={() => <UsersPage />} exact={true} />
<Route path="/operator/tabs/user/create" render={() => <CreateUserPage />} exact={true} />
<Route path="/operator/tabs/user/details/:user-id" render={() => <DetailedUserPage />} exact={true} />
<Route path="/operator/tabs/user/update/:user-id" render={() => <ChangeUserPage />} exact={true} />
<Route path="/operator/tabs/user/details/:user_id" render={() => <DetailedUserPage />} exact={true} />
<Route path="/operator/tabs/user/update/:user_id" render={() => <ChangeUserPage />} exact={true} />
<Route
path="/operator/tabs/user/change-password/:user_id"
render={() => <ChangePasswordPage />}
exact={true}
/>

<Route path="/operator/tabs" render={() => <Redirect to="/operator/tabs/dashboard" />} exact={true} />
</IonRouterOutlet>
Expand All @@ -39,7 +45,7 @@ const OperatorTabs: React.FC = () => {
{isAdmin && (
<IonTabButton tab="userOperatorTab" href="/operator/tabs/user">
<Icons.user strokeWidth={1} className="pt-2 w-[32px] h-[30px]" />
<IonLabel className="pt-2 pb-2">User</IonLabel>
<IonLabel className="pt-2 pb-2">{t("tabs.user")}</IonLabel>
</IonTabButton>
)}
</IonTabBar>
Expand Down
13 changes: 10 additions & 3 deletions apps/app/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"riwayat": "History",
"trashbin": "Trash Bin",
"report": "Report",
"user": "User",
"back": "Back"
},
"home": {
Expand Down Expand Up @@ -122,12 +123,16 @@
"username": "Username",
"phoneNumber": "Phone Number",
"description": "Description",
"active": "Active",
"active_select": "Select Active",
"role": "Role",
"role_select": "Select Role",
"submit": "Create User",
"back": "Back",
"validation": {
"name": "Name must be at least 8 characters long.",
"username": "Username must be at least 8 characters long.",
"name": "Name must be at least 4 characters long.",
"username": "Username must be at least 4 characters long.",
"password": "Password must be at least 8 characters long.",
"phoneNumber": "Phone number must be at least 8 characters long.",
"description": "Description must be at least 8 characters long."
}
Expand All @@ -152,12 +157,14 @@
"change_password": {
"subtitle": "Change Password",
"oldPassword": "Old Password",
"confirmPassword": "Confirm Password",
"newPassword": "New Password",
"submit": "Change Password",
"back": "Back",
"validation": {
"old_password": "Old password must be at least 8 characters long.",
"new_password": "New password must be at least 8 characters long."
"new_password": "New password must be at least 8 characters long.",
"confirm_password": "Confirm password must be at least 8 characters long."
}
}
},
Expand Down
8 changes: 7 additions & 1 deletion apps/app/src/locales/id.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"riwayat": "Riwayat",
"trashbin": "Tempat Sampah",
"report": "Laporan",
"user": "Pengguna",
"back": "Kembali"
},
"home": {
Expand Down Expand Up @@ -122,7 +123,10 @@
"username": "Username",
"phoneNumber": "Nomor Telepon",
"description": "Deskripsi",
"active": "Status Aktif",
"select_active": "Pilih Status Aktif",
"role": "Role",
"role_select": "Pilih Role",
"submit": "Buat Pengguna",
"back": "Kembali",
"validation": {
Expand Down Expand Up @@ -154,11 +158,13 @@
"subtitle": "Ubah Kata Sandi",
"oldPassword": "Kata Sandi Lama",
"newPassword": "Kata Sandi Baru",
"confirmPassword": "Konfirmasi Kata Sandi",
"submit": "Ubah Kata Sandi",
"back": "Kembali",
"validation": {
"old_password": "Kata sandi lama harus memiliki setidaknya 8 karakter.",
"new_password": "Kata sandi baru harus memiliki setidaknya 8 karakter."
"new_password": "Kata sandi baru harus memiliki setidaknya 8 karakter.",
"confirm_password": "Konfirmasi kata sandi harus sama dengan kata sandi baru."
}
}
},
Expand Down
25 changes: 25 additions & 0 deletions apps/app/src/pages/operator/user/change-password.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { IonContent, IonPage } from "@ionic/react";
import { ChangePasswordForm, CreateTrashBinForm, CreateUserForm } from "@trashtrack/ui";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";

export function ChangePasswordPage() {
const { user_id } = useParams<{ user_id: string }>();
const { t } = useTranslation();

return (
<IonPage>
<IonContent className="ion-padding" fullscreen>
<div className="pt-12">
<h1 className="font-bold text-left text-xl">TrashTrack</h1>
<p className="text-xs text-left text-slate-600">{t("operator.user.change_password.subtitle")}</p>
</div>
<div className="flex flex-col pt-8 gap-2">
<ChangePasswordForm userId={user_id} />
</div>
</IonContent>
</IonPage>
);
}

export default ChangePasswordPage;
22 changes: 19 additions & 3 deletions apps/app/src/pages/operator/user/change-user.page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import { IonContent, IonPage } from "@ionic/react";
import { ChangeTrashbinForm, ChangeUserForm } from "@trashtrack/ui";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";

export function ChangeUserPage() {
const { user_id } = useParams<{ user_id: string }>();
const { t } = useTranslation();

return (
<div>
<div></div>
</div>
<IonPage>
<IonContent className="ion-padding" fullscreen>
<div className="pt-12">
<h1 className="font-bold text-left text-xl">TrashTrack</h1>
<p className="text-xs text-left text-slate-600">{t("operator.user.change_user.subtitle")}</p>
</div>
<div className="flex flex-col pt-8 gap-2">
<ChangeUserForm userId={user_id} />
</div>
</IonContent>
</IonPage>
);
}
22 changes: 19 additions & 3 deletions apps/app/src/pages/operator/user/create-user.page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import { IonContent, IonPage } from "@ionic/react";
import { CreateTrashBinForm, CreateUserForm } from "@trashtrack/ui";
import { useTranslation } from "react-i18next";

export function CreateUserPage() {
const { t } = useTranslation();

return (
<div>
<div></div>
</div>
<IonPage>
<IonContent className="ion-padding" fullscreen>
<div className="pt-12">
<h1 className="font-bold text-left text-xl">TrashTrack</h1>
<p className="text-xs text-left text-slate-600">{t("operator.user.create_user.subtitle")}</p>
</div>
<div className="flex flex-col pt-8 gap-2">
<CreateUserForm />
</div>
</IonContent>
</IonPage>
);
}

export default CreateUserPage;
Loading

0 comments on commit 18e5505

Please sign in to comment.