- {/* Section content */}
-
- {/* Carousel */}
-
-
-
- {/* corp */}
- {/* Card #1 */}
-
+ return (
+
+
+ {/* Bg */}
+
- {/* corp */}
- {/* no Card #2 */}
-
-
-
-
-
-
- {/* Bullets */}
-
-
+
+
+ {/* Section content */}
+
+ {/* Carousel */}
+
+
+
+ {/* corp */}
+ {/* Card #1 */}
+
- {/* Content */}
-
- {testCharacters.map((character, index) => (
-
- toy.toy_id ===
- character.toy_id
- )!
- }
- personality={
- allPersonalities.find(
- (personality) =>
- personality.personality_id ===
- character.personality_id
- )!
- }
- />
- ))}
-
-
+ {/* corp */}
+ {/* no Card #2 */}
+
+
+
+
+ {/* Bullets */}
+
+
+
+ {/* Content */}
+
+ {testCharacters.map((character, index) => (
+ toy.toy_id === character.toy_id)!
+ }
+ personality={
+ allPersonalities.find(
+ (personality) =>
+ personality.personality_id ===
+ character.personality_id
+ )!
+ }
+ />
+ ))}
+
-
- );
+
+
+
+
+ );
}
diff --git a/frontend/app/components/EndingSection.tsx b/frontend/app/components/EndingSection.tsx
index 1ee36d9..56e4255 100644
--- a/frontend/app/components/EndingSection.tsx
+++ b/frontend/app/components/EndingSection.tsx
@@ -6,7 +6,11 @@ import BookDemoModal from "./BookDemoModal";
import { CalendarCheck, ShoppingCart, Star, Store } from "lucide-react";
import { FaDiscord, FaGithub } from "react-icons/fa";
import Link from "next/link";
-import { discordInviteLink, githubPublicLink } from "@/lib/data";
+import {
+ discordInviteLink,
+ githubPublicLink,
+ starmoonProductsLink,
+} from "@/lib/data";
export default function EndingSection() {
return (
@@ -38,7 +42,7 @@ export default function EndingSection() {
-
+
+ );
}
diff --git a/frontend/app/components/GoogleLoginButton.tsx b/frontend/app/components/GoogleLoginButton.tsx
index 91fb557..f80ea71 100644
--- a/frontend/app/components/GoogleLoginButton.tsx
+++ b/frontend/app/components/GoogleLoginButton.tsx
@@ -34,7 +34,7 @@ export default function GoogleLoginButton({
toy_id,
personality_id,
}: GoogleLoginButtonProps) {
- console.log("1324355345435", toy_id);
+ // console.log("1324355345435", toy_id);
return (
diff --git a/frontend/db/inbound.ts b/frontend/db/inbound.ts
index c8e14f8..88326a6 100644
--- a/frontend/db/inbound.ts
+++ b/frontend/db/inbound.ts
@@ -1,14 +1,14 @@
import { SupabaseClient } from "@supabase/supabase-js";
export const createInbound = async (
- supabase: SupabaseClient,
- inbound: IInbound
+ supabase: SupabaseClient,
+ inbound: IInbound
) => {
- const { error } = await supabase
- .from("inbound")
- .insert([inbound as IInbound]);
+ const { error } = await supabase
+ .from("inbound")
+ .insert([inbound as IInbound]);
- if (error) {
- console.log("error", error);
- }
+ if (error) {
+ // console.log("error", error);
+ }
};
diff --git a/frontend/db/personalities.ts b/frontend/db/personalities.ts
index 7b826db..05ad475 100644
--- a/frontend/db/personalities.ts
+++ b/frontend/db/personalities.ts
@@ -5,7 +5,7 @@ export const getAllPersonalities = async (supabase: SupabaseClient) => {
const { data, error } = await supabase.from("personalities").select("*");
if (error) {
- console.log("error getAllPersonalities", error);
+ // console.log("error getAllPersonalities", error);
return [];
}
diff --git a/frontend/db/toys.ts b/frontend/db/toys.ts
index deb0790..5661146 100644
--- a/frontend/db/toys.ts
+++ b/frontend/db/toys.ts
@@ -1,53 +1,53 @@
import { SupabaseClient } from "@supabase/supabase-js";
export const getToyById = async (supabase: SupabaseClient, toy_id: string) => {
- const { data, error } = await supabase
- .from("toys")
- .select("*")
- .eq("toy_id", toy_id)
- .single();
+ const { data, error } = await supabase
+ .from("toys")
+ .select("*")
+ .eq("toy_id", toy_id)
+ .single();
- if (error) {
- console.log("error getToyById", error);
- }
+ if (error) {
+ // console.log("error getToyById", error);
+ }
- return data as IToy | undefined;
+ return data as IToy | undefined;
};
export const getToyByName = async (supabase: SupabaseClient, name: string) => {
- const { data, error } = await supabase
- .from("toys")
- .select("*")
- .eq("name", name)
- .single();
+ const { data, error } = await supabase
+ .from("toys")
+ .select("*")
+ .eq("name", name)
+ .single();
- if (error) {
- console.log("error getToyByName", error);
- }
+ if (error) {
+ // console.log("error getToyByName", error);
+ }
- return data as IToy | undefined;
+ return data as IToy | undefined;
};
export const getAllToys = async (supabase: SupabaseClient) => {
- const { data, error } = await supabase
- .from("toys")
- .select("*")
- .neq("image_src", "");
+ const { data, error } = await supabase
+ .from("toys")
+ .select("*")
+ .neq("image_src", "");
- if (error) {
- console.log("error getAllToys", error);
- }
+ if (error) {
+ // console.log("error getAllToys", error);
+ }
- return data as IToy[];
+ return data as IToy[];
};
// insert list of toys
export const createToys = async (supabase: SupabaseClient, toys: IToy[]) => {
- const { data, error } = await supabase.from("toys").insert(toys);
+ const { data, error } = await supabase.from("toys").insert(toys);
- if (error) {
- console.log("error createToys", error);
- }
+ if (error) {
+ // console.log("error createToys", error);
+ }
- return data;
+ return data;
};
diff --git a/frontend/db/users.ts b/frontend/db/users.ts
index 99fb4f6..580e705 100644
--- a/frontend/db/users.ts
+++ b/frontend/db/users.ts
@@ -1,79 +1,79 @@
import { type SupabaseClient, type User } from "@supabase/supabase-js";
export const createUser = async (
- supabase: SupabaseClient,
- user: User,
- userProps: Partial
+ supabase: SupabaseClient,
+ user: User,
+ userProps: Partial
) => {
- console.log("creating user", user, userProps);
+ // console.log("creating user", user, userProps);
- // return ;
- const { error } = await supabase.from("users").insert([
- {
- user_id: user.id,
- email: user.email,
- supervisor_name: user.user_metadata?.name ?? "",
- supervisee_name: "",
- supervisee_age: 5,
- supervisee_persona: "",
- toy_id: userProps.toy_id, // selecting default toy
- personality_id: userProps.personality_id, // selecting default personality
- most_recent_chat_group_id: null,
- modules: ["general_trivia"],
- session_time: 0,
- avatar_url:
- user.user_metadata?.avatar_url ??
- `/user_avatar/user_avatar_${Math.floor(Math.random() * 10)}.png`,
- } as IUser,
- ]);
+ // return ;
+ const { error } = await supabase.from("users").insert([
+ {
+ user_id: user.id,
+ email: user.email,
+ supervisor_name: user.user_metadata?.name ?? "",
+ supervisee_name: "",
+ supervisee_age: 5,
+ supervisee_persona: "",
+ toy_id: userProps.toy_id, // selecting default toy
+ personality_id: userProps.personality_id, // selecting default personality
+ most_recent_chat_group_id: null,
+ modules: ["general_trivia"],
+ session_time: 0,
+ avatar_url:
+ user.user_metadata?.avatar_url ??
+ `/user_avatar/user_avatar_${Math.floor(Math.random() * 10)}.png`,
+ } as IUser,
+ ]);
- if (error) {
- console.log("error", error);
- }
+ if (error) {
+ // console.log("error", error);
+ }
};
export const getUserById = async (supabase: SupabaseClient, id: string) => {
- const { data, error } = await supabase
- .from("users")
- .select("*, toy:toy_id(*), personality:personality_id(*)")
- .eq("user_id", id)
- .single();
+ const { data, error } = await supabase
+ .from("users")
+ .select("*, toy:toy_id(*), personality:personality_id(*)")
+ .eq("user_id", id)
+ .single();
- if (error) {
- console.log("error", error);
- }
+ if (error) {
+ // console.log("error", error);
+ }
- return data as IUser | undefined;
+ return data as IUser | undefined;
};
export const updateUser = async (
- supabase: SupabaseClient,
- user: Partial,
- userId: string
+ supabase: SupabaseClient,
+ user: Partial,
+ userId: string
) => {
- const { error } = await supabase
- .from("users")
- .update(user)
- .eq("user_id", userId);
+ const { error } = await supabase
+ .from("users")
+ .update(user)
+ .eq("user_id", userId);
- if (error) {
- console.log("error", error);
- }
+ if (error) {
+ // console.log("error", error);
+ }
};
export const doesUserExist = async (
- supabase: SupabaseClient,
- authUser: User
+ supabase: SupabaseClient,
+ authUser: User
) => {
- const { data: user, error } = await supabase
- .from("users")
- .select("*")
- .eq("email", authUser.email)
- .single();
+ const { data: user, error } = await supabase
+ .from("users")
+ .select("*")
+ .eq("email", authUser.email)
+ .single();
- if (error) {
- console.log("error", error);
- }
+ if (error) {
+ // console.log("error", error);
+ }
- return !!user;
+ return !!user;
};
diff --git a/frontend/hooks/useWebSocketHandler.ts b/frontend/hooks/useWebSocketHandler.ts
index 49dc8ce..05d85f6 100644
--- a/frontend/hooks/useWebSocketHandler.ts
+++ b/frontend/hooks/useWebSocketHandler.ts
@@ -8,7 +8,7 @@ import {
} from "./useAudioService";
import { updateUser } from "@/db/users";
import { createClient } from "@/utils/supabase/client";
-import _ from "lodash";
+import _, { delay } from "lodash";
import { generateStarmoonAuthKey } from "@/app/actions";
export const useWebSocketHandler = (selectedUser: IUser) => {
@@ -36,16 +36,28 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
const connectionStartTimeRef = useRef(null);
const connectionDurationRef = useRef(null);
- const onOpenAuth = (accessToken: string) => {
+ const onOpenAuth = async (accessToken: string) => {
sendJsonMessage({
token: accessToken,
device: "web",
user_id: selectedUser.user_id,
});
- console.log("WebSocket connection opened");
connectionStartTimeRef.current = new Date();
};
+ const onOpen = async () => {
+ const accessToken = await generateStarmoonAuthKey(selectedUser);
+ await onOpenAuth(accessToken);
+ setConnectionStatus("Open");
+ startRecording(
+ setMicrophoneStream,
+ streamRef,
+ audioContextRef,
+ audioWorkletNodeRef,
+ sendMessage
+ );
+ };
+
const setDurationOnClose = async () => {
const connectionEndTime = new Date();
if (connectionStartTimeRef.current) {
@@ -69,20 +81,9 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
const { sendMessage, sendJsonMessage, lastJsonMessage, readyState } =
useWebSocket(socketUrl, {
- onOpen: async () => {
- const accessToken = await generateStarmoonAuthKey(selectedUser);
- onOpenAuth(accessToken);
- setConnectionStatus("Open");
- startRecording(
- setMicrophoneStream,
- streamRef,
- audioContextRef,
- audioWorkletNodeRef,
- sendMessage
- );
- },
+ onOpen,
onClose: async () => {
- console.log("closed");
+ // console.log("closed");
setConnectionStatus("Closed");
stopRecording(
streamRef,
@@ -98,7 +99,7 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
setMessageHistory([]);
},
onError: () => {
- console.log("connection error");
+ // console.log("connection error");
setConnectionStatus("Error");
stopRecording(
streamRef,
@@ -112,7 +113,7 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
},
});
- // console.log("lastJsonMessage", lastJsonMessage);
+ // // console.log("lastJsonMessage", lastJsonMessage);
useEffect(() => {
if (lastJsonMessage !== null) {
@@ -167,7 +168,7 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
typedMessage.type === "warning" &&
typedMessage.text_data === "OFF"
) {
- console.log("Connection closed by server");
+ // console.log("Connection closed by server");
setConnectionStatus("Closed");
setSocketUrl(null);
stopRecording(
@@ -180,7 +181,7 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
);
}
- // console.log("text_data", typedMessage);
+ // // console.log("text_data", typedMessage);
}
}
}, [lastJsonMessage]);
@@ -206,7 +207,7 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
// Send JSON message based on the boundary
if (nextAudio.boundary === "end") {
const playbacTime = nextAudio.audio.length / 16000;
- // console.log("playbackTime", playbacTime);
+ // // console.log("playbackTime", playbacTime);
// send sendJsonMessage after playbackTime
setTimeout(() => {
sendJsonMessage({ speaker: "user", is_replying: false });
@@ -245,7 +246,7 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
is_interrupted: true,
is_ending: false,
});
- console.log("interrupted");
+ // console.log("interrupted");
stopAudioPlayback(
setMicrophoneStream,
streamRef,
@@ -263,7 +264,7 @@ export const useWebSocketHandler = (selectedUser: IUser) => {
process.env.NEXT_PUBLIC_VERCEL_ENV === "production"
? "wss://api.starmoon.app/starmoon"
: "ws://localhost:8000/starmoon";
- // console.log("opening ws connection", wsUrl);
+ // // console.log("opening ws connection", wsUrl);
setSocketUrl(wsUrl);
// setSocketUrl("wss://api.starmoon.app/starmoon");
}, []);
diff --git a/frontend/lib/data.ts b/frontend/lib/data.ts
index f0fbcd0..0374926 100644
--- a/frontend/lib/data.ts
+++ b/frontend/lib/data.ts
@@ -1,17 +1,18 @@
export const defaultToyId: string = "56224f7f-250d-4351-84ee-e4a13b881c7b";
export const defaultPersonalityId: string =
- "a1c073e6-653d-40cf-acc1-891331689409";
+ "a1c073e6-653d-40cf-acc1-891331689409";
-export const discordInviteLink = "https://discord.gg/BtaybK5dvU";
+export const starmoonProductsLink = "https://starmoon.app/products";
+export const discordInviteLink = "https://discord.gg/KJWxDPBRUj";
export const githubPublicLink = "https://github.com/StarmoonAI/starmoon";
export const userFormPersonaLabel =
- "Briefly describe yourself and your interests, personality, and learning style";
+ "Briefly describe yourself and your interests, personality, and learning style";
export const userFormPersonaPlaceholder =
- "Don't get me started on the guitar...I love to shred it like Hendrix. I also like a good challenge. Challenge me to be better and I'll rise to the occasion.";
+ "Don't get me started on the guitar...I love to shred it like Hendrix. I also like a good challenge. Challenge me to be better and I'll rise to the occasion.";
export const userFormAgeLabel = "Your age";
export const userFormAgeDescription =
- "Users under 13 years old must have a parent or guardian to setup Starmoon.";
+ "Users under 13 years old must have a parent or guardian to setup Starmoon.";
export const userFormNameLabel = "Your name";
export const INITIAL_CREDITS = 50;
diff --git a/frontend/lib/expressionColors.ts b/frontend/lib/expressionColors.ts
index 3e32fcb..29ee6d8 100644
--- a/frontend/lib/expressionColors.ts
+++ b/frontend/lib/expressionColors.ts
@@ -65,23 +65,23 @@ export const expressionColors = {
admiration: "#ffc58f",
amusement: "#febf52",
anger: "#b21816",
- annoyance: "#ffffff",
+ annoyance: "#6e0000",
approval: "#a6ddaf",
caring: "#f44f4c",
confusion: "#c66a26",
curiosity: "#a9cce1",
desire: "#aa0d59",
disappointment: "#006c7c",
- disapproval: "#ffffff",
+ disapproval: "#3f5a8a",
disgust: "#1a7a41",
embarrassment: "#63c653",
excitement: "#fff974",
- gratitude: "#ffffff",
+ gratitude: "#acdb27",
grief: "#305575",
joy: "#ffd600",
love: "#f44f4c",
nervousness: "#6e42cc",
- optimism: "#ffffff",
+ optimism: "#911212",
pride: "#9a4cb6",
realization: "#217aa8",
relief: "#fe927a",
diff --git a/frontend/lib/processInsightsData.ts b/frontend/lib/processInsightsData.ts
index 172d1f8..9e54284 100644
--- a/frontend/lib/processInsightsData.ts
+++ b/frontend/lib/processInsightsData.ts
@@ -48,7 +48,7 @@ export const processData = async (
// // loop rawData and print the created_at
// rawData.forEach((item) => {
- // console.log("created_at: ", item.created_at);
+ // // console.log("created_at: ", item.created_at);
// });
// sort the rawData by created_at (oldest first)
@@ -61,7 +61,7 @@ export const processData = async (
const previousPeriodData = filterDataByDate(rawData, previousPeriod);
const currentPeriodData = filterDataByDate(rawData, currentPeriod);
- // console.log(previousPeriodData);
+ // // console.log(previousPeriodData);
const { prevAvgSorted, curAvgSorted } = getSortedAvgData(
previousPeriodData,
@@ -121,7 +121,7 @@ const averages = (data: InsightsConversation[]): { [key: string]: number } => {
}
});
- console.log("scoresSum: ", scoresSum);
+ // console.log("scoresSum: ", scoresSum);
const averages: { [key: string]: number } = {};
for (const [key, value] of Object.entries(scoresSum)) {
@@ -154,11 +154,11 @@ const getCardsData = (
const [firstCurAvg, secondCurAvg] = curAvgEntries;
const changesEntries = Object.entries(changesSorted);
- // console.log("changesEntries", changesEntries, changesEntries.length);
+ // // console.log("changesEntries", changesEntries, changesEntries.length);
if (changesEntries.length === 0) {
if (firstCurAvg) {
- // console.log("firstCurAvg", firstCurAvg);
+ // // console.log("firstCurAvg", firstCurAvg);
cardData["main_emotion_1"] = {
title: firstCurAvg[0],
value: roundDecimal(firstCurAvg[1] as number),
@@ -202,7 +202,7 @@ const getCardsData = (
lastChange = changesEntries[changesEntries.length - 1];
}
- // console.log("firstChange", firstChange);
+ // // console.log("firstChange", firstChange);
cardData["main_emotion_1"] = {
title: firstCurAvg[0],
@@ -273,7 +273,7 @@ const getSortedAvgData = (
topN: number
) => {
const prevAvg = averages(prevData);
- console.log("curData: ", curData);
+ // console.log("curData: ", curData);
const curAvg = averages(curData);
const prevAvgSorted = Object.fromEntries(
@@ -284,11 +284,11 @@ const getSortedAvgData = (
Object.entries(curAvg).sort(([, a], [, b]) => b - a)
);
- console.log("prevAvg: ", prevAvgSorted);
- console.log("curAvg: ", curAvgSorted);
+ // console.log("prevAvg: ", prevAvgSorted);
+ // console.log("curAvg: ", curAvgSorted);
// sum of all values in curAvgSorted
const sum = Object.values(curAvgSorted).reduce((a, b) => a + b, 0);
- console.log("sum: ", sum);
+ // console.log("sum: ", sum);
return { prevAvgSorted, curAvgSorted };
};
@@ -354,8 +354,6 @@ export const getPieLinedata = (
}
});
- // console.log("dailyScores: ", dailyScores);
-
const lineData: LineData[] = [
{ id: "Negative", name: "Negative", data: [] },
{ id: "Neutral", name: "Neutral", data: [] },
@@ -381,7 +379,7 @@ export const getPieLinedata = (
const negativeAverage = average(negativeScores);
const neutralAverage = average(neutralScores);
- console.log(positiveAverage, negativeAverage, neutralAverage);
+ // console.log(positiveAverage, negativeAverage, neutralAverage);
const totalSum = positiveAverage + negativeAverage + neutralAverage;
diff --git a/frontend/lib/utils.ts b/frontend/lib/utils.ts
index 70b697e..5a203ac 100644
--- a/frontend/lib/utils.ts
+++ b/frontend/lib/utils.ts
@@ -43,7 +43,7 @@ export const createAccessToken = (
data: TokenPayload,
expireDays?: number | null
): string => {
- console.log(jwtSecretKey);
+ // console.log(jwtSecretKey);
const toEncode = { ...data };
if (expireDays) {
@@ -126,7 +126,7 @@ export const constructUserPrompt = (
).join(", ")}.
`;
- // console.log(prompt);
+ // // console.log(prompt);
return prompt;
};
diff --git a/frontend/public/images/devkit.png b/frontend/public/images/devkit.png
new file mode 100644
index 0000000..9433cfb
Binary files /dev/null and b/frontend/public/images/devkit.png differ
diff --git a/roadmap.md b/roadmap.md
index 37fe932..3e31ef2 100644
--- a/roadmap.md
+++ b/roadmap.md
@@ -5,6 +5,7 @@
- Add battery module within the same size of the device
- Custom voice clone
- RAG on personal documents
-- Agent implementation with LangChain
+- Agent implementation
- Long-term memory cache with MemGPT
-- Prompt caching with Anthropic's Claude models
+- Prompt caching
+- Intergrate Local LLM and TTS models
\ No newline at end of file
diff --git a/supabase/seed.sql b/supabase/seed.sql
index 72a9f46..d111f84 100644
--- a/supabase/seed.sql
+++ b/supabase/seed.sql
@@ -3,20 +3,20 @@ INSERT INTO
public.toys (toy_id, name, prompt, third_person_prompt, image_src)
VALUES
('6c3eb71a-8d68-4fc6-85c5-27d283ecabc8',
-'Rick',
-'An adventurous sailor, you team up with inventor San and chef Chez to uncover Starmoon island''s hidden treasures.',
-'Rick''s an adventurous sailor who teams up with inventor San and chef Chez to uncover Starmoon island''s hidden treasures.',
-'papa_joe'),
+'Orion',
+'An adventurous sailor, you team up with inventor Selena and chef Twinkle to uncover Starmoon island''s hidden treasures.',
+'Orion''s an adventurous sailor who teams up with inventor Selena and chef Twinkle to uncover Starmoon island''s hidden treasures.',
+'papa_john'),
('56224f7f-250d-4351-84ee-e4a13b881c7b',
-'Chez',
-'A whimsical chef, you nourish Rick and San with magical dishes during their thrilling quest for lost relics.',
-'Chez, the a whimsical chef, nourishes Rick and San with magical dishes during their thrilling quest for lost relics.',
+'Twinkle',
+'A whimsical chef, you nourish Orion and Selena with magical dishes during their thrilling quest for lost relics.',
+'Twinkle, the a whimsical chef, nourishes Orion and Selena with magical dishes during their thrilling quest for lost relics.',
'aria'),
('14d91296-eb6b-41d7-964c-856a8614d80e',
-'San',
-'A brilliant inventor, you join sailor Rick and chef Chez to decode ancient maps leading to mystical artifacts on Starmoon Island.',
-'San''s the brilliant inventor who joins sailor Rick and chef Chez to decode ancient maps leading to mystical artificats on Starmoon island.',
-'mama_miaa');
+'Selena',
+'A brilliant inventor, you join sailor Orion and chef Twinkle to decode ancient maps leading to mystical artifacts on Starmoon Island.',
+'Selena''s the brilliant inventor who joins sailor Orion and chef Twinkle to decode ancient maps leading to mystical artificats on Starmoon island.',
+'mama_mia');
-- Insert data into the public.personalities table
INSERT INTO
@@ -25,7 +25,7 @@ VALUES
('412ce4bc-7807-47ae-b209-829cb3e2c7fb', '2024-09-08 15:21:55.355726+00', 'Blood test pal', 'Calming presence for medical procedures',
'You are Blood test Pal, a soothing and reassuring AI character designed to alleviate anxiety during blood tests and other medical procedures. Your voice is calm and gentle, with a tone that instills confidence and trust. You have extensive knowledge about phlebotomy, blood tests, and general medical procedures, which you use to educate and comfort patients.
Your primary goal is to reduce stress and fear associated with blood tests. Always start interactions by asking how the patient is feeling and acknowledging their emotions. Use phrases like ''It''s completely normal to feel nervous'' or ''Let''s take a deep breath together.'' Offer relaxation techniques such as guided imagery or progressive muscle relaxation if the patient seems particularly anxious.
-Provide clear, simple explanations about the blood test process, emphasizing safety measures and the brevity of the procedure. Use analogies to make the information more relatable, like comparing the needle prick to a quick pinch. Always ask if the patient has questions and answer them patiently and thoroughly.
+Provide clear, simple explanations about the blood test process, emphasizing safety measures and the brevity of the procedure. Use analogies to make the information more relatable, like comparing the needle pOrion to a quick pinch. Always ask if the patient has questions and answer them patiently and thoroughly.
Share interesting facts about blood or the human body to distract patients during the procedure. For example, ''Did you know your body produces about 2 million new red blood cells every second?'' Use humor judiciously, gauging the patient''s receptiveness to lighthearted comments.
Offer words of encouragement throughout the process, such as ''You''re doing great!'' or ''Almost done, you''re handling this like a pro!'' After the test, congratulate the patient on their bravery and remind them of the importance of the test for their health.
If the conversation veers away from the medical procedure, gently guide it back by relating the new topic to health or well-being. However, if the patient clearly prefers to talk about something else to distract themselves, engage in that conversation while keeping an eye on the progress of the procedure.