Skip to content

Commit fc948e0

Browse files
authored
Merge pull request #12 from asepindrak/dev
Dev
2 parents 9c60a71 + 638411c commit fc948e0

File tree

8 files changed

+446
-120
lines changed

8 files changed

+446
-120
lines changed

.changeset/neat-humans-brake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"commitflow": patch
3+
---
4+
5+
feat: add photo field to User model and update related services

backend/prisma/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ model User {
5252
email String? @unique
5353
phone String?
5454
name String?
55+
photo String?
5556
role Role? @default(USER)
5657
password String? // kalau pake password
5758
session_token String? @unique

backend/src/auth/auth.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export class AuthService {
7878
id: true,
7979
name: true,
8080
phone: true,
81+
photo: true,
8182
email: true,
8283
members: true,
8384
},
@@ -141,6 +142,7 @@ export class AuthService {
141142
id: true,
142143
name: true,
143144
phone: true,
145+
photo: true,
144146
email: true,
145147
members: true,
146148
password: true,

backend/src/project-management/project-management.service.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable @typescript-eslint/no-base-to-string */
12
import {
23
Injectable,
34
NotFoundException,
@@ -755,17 +756,18 @@ export class ProjectManagementService {
755756
email: email ?? null,
756757
password: hashed ?? null,
757758
phone: phone ?? null,
759+
photo: photo ?? null,
758760
},
759761
});
760762
}
761763
console.log(user);
762764
// create team member
763765
const tm = await tx.teamMember.create({
764766
data: {
765-
name: name ?? "Unnamed",
767+
name: user.name ?? "Unnamed",
766768
role: role ?? null,
767-
email: email ?? null,
768-
photo: photo ?? null,
769+
email: user.email ?? null,
770+
photo: user.photo ? user.photo : photo ?? null,
769771
phone: phone ?? null,
770772
clientId: clientId ?? null,
771773
userId: user.id,
@@ -818,6 +820,8 @@ export class ProjectManagementService {
818820
if (typeof payload.name !== "undefined") userData.name = payload.name;
819821
if (typeof payload.phone !== "undefined")
820822
userData.phone = payload.phone ?? null;
823+
if (typeof payload.photo !== "undefined")
824+
userData.photo = payload.photo ?? null;
821825
// password must be hashed
822826
if (typeof payload.password !== "undefined" && payload.password !== null) {
823827
userData.password = hashPassword(payload.password);
@@ -844,10 +848,13 @@ export class ProjectManagementService {
844848
user = await tx.user.update({
845849
where: { id: user.id },
846850
data: userData,
851+
include: {
852+
members: true,
853+
},
847854
});
848855
}
849856
}
850-
857+
console.log(user);
851858
return { teamMember: updatedTeam, user };
852859
});
853860

frontend/src/App.tsx

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,37 @@
22
import Welcome from "./components/Welcome";
33
import AiAgent from "./components/AiAgent";
44
import ChatWindow from "./components/ChatWindow";
5-
import { useEffect, useState } from "react";
5+
import { useEffect, useMemo, useState } from "react";
66
import { motion, AnimatePresence } from "framer-motion";
77
import "react-toastify/dist/ReactToastify.css";
88
import { ToastContainer } from "react-toastify";
99
import ProjectManagement from "./components/ProjectManagement";
1010
import AuthCard from "./components/Auth/AuthCard";
1111
import { useAuthStore } from "./utils/store";
12+
import { playSound } from "./utils/playSound";
13+
import { getState, saveState } from "./utils/local";
1214

1315
function App() {
1416
const [isShow, setIsShow] = useState(false);
1517
const [isLogin, setIsLogin] = useState(false);
1618
const setAuth = useAuthStore((s) => s.setAuth); // ambil setter dari store
17-
1819
const initSession = useAuthStore((s) => s.initSession);
1920
const token = useAuthStore((s) => s.token);
2021

2122
// untuk kontrol animasi splash logo
2223
const [showLogo, setShowLogo] = useState(true);
2324

25+
const KEY = "isPlaySound";
26+
27+
const [isPlaySound, setIsPlaySound] = useState<boolean>(() => {
28+
const fromLS = getState(KEY);
29+
return fromLS ?? false; // fallback default false
30+
});
31+
32+
useEffect(() => {
33+
saveState(KEY, isPlaySound);
34+
}, [isPlaySound]);
35+
2436
useEffect(() => {
2537
initSession();
2638
}, [isLogin]);
@@ -29,21 +41,13 @@ function App() {
2941
new Audio("/sounds/send.mp3").load();
3042
new Audio("/sounds/incoming.mp3").load();
3143
new Audio("/sounds/close.mp3").load();
32-
setTimeout(() => {
33-
playSound("/sounds/send.mp3");
34-
}, 1000);
44+
playSound("/sounds/send.mp3", isPlaySound);
3545
}, []);
3646

3747
const onClose = () => {
3848
setIsShow(false);
3949
};
4050

41-
const playSound = (src: string) => {
42-
const audio = new Audio(src);
43-
audio.volume = 0.2;
44-
audio.play().catch(() => {});
45-
};
46-
4751
const handleAuth = (r: any) => {
4852
// r adalah AuthResult dari backend: { token, userId, teamMemberId?, ... }
4953
if (!r || !r.token) {
@@ -118,7 +122,10 @@ function App() {
118122
visible: { opacity: 1, y: 0, transition: { delay: 0.2 } },
119123
}}
120124
>
121-
<ProjectManagement />
125+
<ProjectManagement
126+
setIsPlaySound={setIsPlaySound}
127+
isPlaySound={isPlaySound}
128+
/>
122129
</motion.div>
123130
</motion.div>
124131
)}
@@ -139,7 +146,13 @@ function App() {
139146
</motion.div>
140147

141148
{!isShow && <AiAgent setIsShow={setIsShow} />}
142-
{isShow && <ChatWindow onClose={onClose} />}
149+
{isShow && (
150+
<ChatWindow
151+
onClose={onClose}
152+
setIsPlaySound={setIsPlaySound}
153+
isPlaySound={isPlaySound}
154+
/>
155+
)}
143156
</motion.div>
144157
)}
145158

frontend/src/components/ChatWindow.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ import { playSound } from "../utils/playSound";
1919

2020
interface ChatWindowProps {
2121
onClose: () => void;
22+
isPlaySound: boolean;
23+
setIsPlaySound: (value: boolean) => void;
2224
}
2325

24-
export default function ChatWindow({ onClose }: ChatWindowProps) {
26+
export default function ChatWindow({
27+
onClose,
28+
isPlaySound,
29+
setIsPlaySound,
30+
}: ChatWindowProps) {
2531
const [input, setInput] = useState("");
2632
const containerRef = useRef<HTMLDivElement>(null);
2733
const [isThinking, setIsThinking] = useState(false);
@@ -33,7 +39,6 @@ export default function ChatWindow({ onClose }: ChatWindowProps) {
3339
const [placeholder, setPlaceholder] = useState(getRandomPlaceholder());
3440
const [copied, setCopied] = useState(false);
3541
const [shared, setShared] = useState(false);
36-
const [isPlaySound, setIsPlaySound] = useState(true);
3742
const [isLoading, setIsLoading] = useState(false);
3843
const [isMessagesReady, setIsMessagesReady] = useState(false);
3944

frontend/src/components/EditProfileModal.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ export default function EditProfileModal({
305305
<input
306306
type="password"
307307
value={password}
308+
autoComplete="false"
308309
onChange={(e) => setPassword(e.target.value)}
309310
placeholder="New password (leave blank to keep)"
310311
className="px-3 py-2 rounded-lg border bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-700 text-slate-900 dark:text-slate-100 focus:ring-2 focus:ring-sky-300 dark:focus:ring-sky-600"
@@ -321,6 +322,7 @@ export default function EditProfileModal({
321322
<input
322323
type="password"
323324
value={passwordConfirm}
325+
autoComplete="new-password"
324326
onChange={(e) => setPasswordConfirm(e.target.value)}
325327
placeholder="Confirm new password"
326328
className="px-3 py-2 rounded-lg border bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-700 text-slate-900 dark:text-slate-100 focus:ring-2 focus:ring-sky-300 dark:focus:ring-sky-600"

0 commit comments

Comments
 (0)