diff --git a/src/components/pages/Dashboard/Edit/index.tsx b/src/components/pages/Dashboard/Edit/index.tsx
new file mode 100644
index 0000000..df9a9d8
--- /dev/null
+++ b/src/components/pages/Dashboard/Edit/index.tsx
@@ -0,0 +1,66 @@
+import { Button } from "@/components/ui/Button";
+import { Textfield } from "@/components/ui/Textfield";
+import useFetch from "@/hooks/useFetch";
+import { dashboardService } from "@/services/api/dashboard.service";
+import { useParams } from "react-router-dom";
+import useEdit from "./useEdit";
+import { useCallback, useEffect } from "react";
+import { MyNpubsCardProps } from "../MyNpubsCard";
+const sampleData: MyNpubsCardProps = {
+ username: "Ehsan@nosrt.eco",
+ npub: "npub1h5h535j4809uf23j8y9t4n23090",
+ id: "1",
+};
+
+const NpubEditForm = () => {
+ const { id } = useParams();
+
+ const fetchUsernames = useCallback(() => {
+ return dashboardService
+ .getMyUsername(id as string)
+ .then(res => res.data.data);
+ }, []);
+ const { data, loading } = useFetch(fetchUsernames);
+
+ const { handleSubmit, register, errors, setValue } = useEdit();
+ useEffect(() => {
+ if (data) {
+ setValue("npub", data?.npub);
+ }
+ }, []);
+
+ if (loading) return "Loading...";
+
+ return (
+
+ );
+};
+
+export default NpubEditForm;
diff --git a/src/components/pages/Dashboard/Edit/useEdit.ts b/src/components/pages/Dashboard/Edit/useEdit.ts
new file mode 100644
index 0000000..3a7bcf7
--- /dev/null
+++ b/src/components/pages/Dashboard/Edit/useEdit.ts
@@ -0,0 +1,51 @@
+import * as yup from "yup";
+import { useForm } from "react-hook-form";
+import { yupResolver } from "@hookform/resolvers/yup";
+import { useState } from "react";
+import { useNavigate, useParams } from "react-router-dom";
+import { dashboardService } from "@/services/api/dashboard.service";
+
+const schema = yup
+ .object({
+ npub: yup.string().required("npub is required"),
+ })
+ .required();
+
+const useEdit = () => {
+ const navigate = useNavigate();
+ const [loading, setLoading] = useState(false);
+ const { id } = useParams();
+
+ const {
+ register,
+ handleSubmit,
+ setValue,
+ formState: { errors },
+ } = useForm({
+ resolver: yupResolver(schema),
+ });
+
+ const onSubmit = async (data: { npub: string }) => {
+ try {
+ setLoading(true);
+ await dashboardService.editMyUsernames(id as string, data);
+ navigate("");
+ } catch (error) {
+ console.log(error);
+ navigate("");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return {
+ setValue,
+ register,
+ onSubmit,
+ errors,
+ handleSubmit: handleSubmit(onSubmit),
+ loading,
+ };
+};
+
+export default useEdit;
diff --git a/src/components/pages/Dashboard/MyNpubsCard.tsx b/src/components/pages/Dashboard/MyNpubsCard.tsx
new file mode 100644
index 0000000..5efbaab
--- /dev/null
+++ b/src/components/pages/Dashboard/MyNpubsCard.tsx
@@ -0,0 +1,65 @@
+import { buttonVariants } from "@/components/ui/Button/buttonVariants";
+import Tag from "@/components/ui/Tag";
+import { cn } from "@/lib/utils";
+import { Link } from "react-router-dom";
+
+export type MyNpubsCardProps = {
+ id: string;
+ username: string;
+ npub: string;
+ // items: { name: string; value: string }[];
+};
+
+const MyNpubsCard = ({ username, id, npub }: MyNpubsCardProps) => {
+ return (
+
+
+
+
+ {username}
+
+
+ {" "}
+ Edit
+
+
+
+
+ {/* {items.map((item, key) => (
+
+
{item.name}
+
+ {item.value}
+
+
+ ))} */}
+
+
+
+ );
+};
+
+export default MyNpubsCard;
diff --git a/src/components/pages/Dashboard/index.tsx b/src/components/pages/Dashboard/index.tsx
new file mode 100644
index 0000000..c8633e3
--- /dev/null
+++ b/src/components/pages/Dashboard/index.tsx
@@ -0,0 +1,66 @@
+import { dashboardService } from "@/services/api/dashboard.service";
+import MyNpubsCard, { MyNpubsCardProps } from "./MyNpubsCard";
+import { Skeleton } from "@/components/ui/skeleton";
+import AnimateWrapper from "@/components/AnimateWrapper";
+import useFetch from "@/hooks/useFetch";
+import { useCallback } from "react";
+const sampleData: MyNpubsCardProps[] = [
+ {
+ username: "Ehsan@nosrt.eco",
+ npub: "npub1h5h535j4809uf23j8y9t4n23090",
+ id: "1",
+ // items: [
+ // {
+ // name: "npub",
+ // value: "npub1h5h535j4809uf23j8y9t4n23090",
+ // },
+ // ],
+ },
+];
+
+const Dashboard = () => {
+ const fetchUsernames = useCallback(() => {
+ return dashboardService.getMyUsernames().then(res => res.data.data);
+ }, []);
+ const { data, loading, error } = useFetch(fetchUsernames);
+
+ if (error)
+ return (
+
+ Error: {error.message}
+
+ );
+
+ return (
+
+
+ Hi, welcome
+ {/* TODO: add username */}
+
+
+ {loading ? (
+ <>
+
+
+ >
+ ) : data && data.length > 0 ? (
+ data?.map((card, key) => (
+
+
+
+ ))
+ ) : sampleData ? (
+ sampleData?.map((card, key) => (
+
+
+
+ ))
+ ) : (
+ "Not any username"
+ )}
+
+
+ );
+};
+
+export default Dashboard;
diff --git a/src/components/pages/SetUserName/NameSuggestions.tsx b/src/components/pages/SetUserName/NameSuggestions.tsx
index b4921b9..2ccca88 100644
--- a/src/components/pages/SetUserName/NameSuggestions.tsx
+++ b/src/components/pages/SetUserName/NameSuggestions.tsx
@@ -1,25 +1,14 @@
import { Skeleton } from "@/components/ui/skeleton";
import Tag from "@/components/ui/Tag";
+import useFetch from "@/hooks/useFetch";
import { usernameService } from "@/services/api/username.service";
-import { useEffect, useState } from "react";
const NameSuggestions = () => {
- const [data, setData] = useState();
- const [loading, setLoading] = useState(false);
- useEffect(() => {
- const fetch = async () => {
- try {
- setLoading(true);
- const res = await usernameService.getSuggestions();
- setData(res.data.data);
- } catch (error) {
- console.log(error);
- } finally {
- setLoading(false);
- }
- };
- fetch();
- }, []);
+ const fetchUsernames = () =>
+ usernameService.getSuggestions().then(res => res.data.data);
+
+ const { data, loading } = useFetch(fetchUsernames);
+
return (
diff --git a/src/hooks/useFetch.ts b/src/hooks/useFetch.ts
new file mode 100644
index 0000000..d80a003
--- /dev/null
+++ b/src/hooks/useFetch.ts
@@ -0,0 +1,39 @@
+import { useState, useEffect, useCallback } from "react";
+
+type UseFetchState = {
+ data: T | null;
+ loading: boolean;
+ error: Error | null;
+};
+
+function useFetch(fetchFunction: () => Promise) {
+ const [state, setState] = useState>({
+ data: null,
+ loading: false,
+ error: null,
+ });
+
+ const [trigger, setTrigger] = useState(0);
+
+ const fetchData = useCallback(async () => {
+ setState({ data: null, loading: true, error: null });
+ try {
+ const data = await fetchFunction();
+ setState({ data, loading: false, error: null });
+ } catch (error) {
+ setState({ data: null, loading: false, error: error as Error });
+ }
+ }, [fetchFunction]);
+
+ useEffect(() => {
+ fetchData();
+ }, [fetchData, trigger]);
+
+ const refetch = useCallback(() => {
+ setTrigger(prev => prev + 1);
+ }, []);
+
+ return { ...state, refetch };
+}
+
+export default useFetch;
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index 10fd0a4..ee22d17 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -5,6 +5,8 @@ import { HomePage, NotFoundPage } from "@/components/pages";
import AvailabilityPage from "@/components/pages/Availability";
import SetUserName from "@/components/pages/SetUserName";
import PaymentResult from "@/components/pages/PaymentResult";
+import Dashboard from "@/components/pages/Dashboard";
+import NpubEditForm from "@/components/pages/Dashboard/Edit";
export const router = createBrowserRouter([
{
@@ -31,6 +33,15 @@ export const router = createBrowserRouter([
path: "*",
element: ,
},
+
+ {
+ path: "/dashboard",
+ element: ,
+ },
+ {
+ path: "/dashboard/edit/:id",
+ element: ,
+ },
],
},
]);
diff --git a/src/services/api/dashboard.service.ts b/src/services/api/dashboard.service.ts
new file mode 100644
index 0000000..60b34c6
--- /dev/null
+++ b/src/services/api/dashboard.service.ts
@@ -0,0 +1,12 @@
+import { MyNpubsCardProps } from "@/components/pages/Dashboard/MyNpubsCard";
+import { mainApi } from "../../config/axios.config";
+import { ApiResponse } from "../../types/api.types";
+
+export const dashboardService = {
+ getMyUsernames: () =>
+ mainApi.get>(`/usernames`),
+ getMyUsername: (id: string) =>
+ mainApi.get>(`/usernames/username/${id}`),
+ editMyUsernames: (id: string, data: { npub: string }) =>
+ mainApi.put>(`/usernames/username/${id}`, data),
+};