diff --git a/web/src/components/Memo.tsx b/web/src/components/Memo.tsx
index e6ef48f2..56fdd98c 100644
--- a/web/src/components/Memo.tsx
+++ b/web/src/components/Memo.tsx
@@ -175,8 +175,8 @@ const Memo: React.FC<Props> = (props: Props) => {
           <Only when={memo.pinned}>
             <span className="status-text">PINNED</span>
           </Only>
-          <Only when={memo.visibility === "PUBLIC" && !isVisitorMode}>
-            <span className="status-text">PUBLIC</span>
+          <Only when={memo.visibility !== "PRIVATE" && !isVisitorMode}>
+            <span className="status-text">{memo.visibility}</span>
           </Only>
         </div>
         <div className={`btns-container ${userService.isVisitorMode() ? "!hidden" : ""}`}>
diff --git a/web/src/components/MemoCardDialog.tsx b/web/src/components/MemoCardDialog.tsx
index 209b39d8..962d6e03 100644
--- a/web/src/components/MemoCardDialog.tsx
+++ b/web/src/components/MemoCardDialog.tsx
@@ -9,6 +9,7 @@ import { showDialog } from "./Dialog";
 import Image from "./Image";
 import { formatMemoContent } from "./Memo";
 import "../less/memo-card-dialog.less";
+import Selector from "./common/Selector";
 
 interface LinkedMemo extends Memo {
   createdAtStr: string;
@@ -26,6 +27,11 @@ const MemoCardDialog: React.FC<Props> = (props: Props) => {
   const [linkMemos, setLinkMemos] = useState<LinkedMemo[]>([]);
   const [linkedMemos, setLinkedMemos] = useState<LinkedMemo[]>([]);
   const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []).map((s) => s.replace(IMAGE_URL_REG, "$1"));
+  const visibilityList = [
+    { text: "PUBLIC", value: "PUBLIC" },
+    { text: "PROTECTED", value: "PROTECTED" },
+    { text: "PRIVATE", value: "PRIVATE" },
+  ];
 
   useEffect(() => {
     const fetchLinkedMemos = async () => {
@@ -98,25 +104,16 @@ const MemoCardDialog: React.FC<Props> = (props: Props) => {
     setMemo(memo);
   }, []);
 
-  const handleEditMemoBtnClick = useCallback(() => {
+  const handleEditMemoBtnClick = () => {
     props.destroy();
     editorStateService.setEditMemoWithId(memo.id);
-  }, [memo.id]);
-
-  const handlePinClick = async () => {
-    if (memo.pinned) {
-      await memoService.unpinMemo(memo.id);
-    } else {
-      await memoService.pinMemo(memo.id);
-    }
-    setMemo({
-      ...memo,
-      pinned: !memo.pinned,
-    });
   };
 
-  const handleVisibilityClick = async () => {
-    const visibility = memo.visibility === "PRIVATE" ? "PUBLIC" : "PRIVATE";
+  const handleVisibilitySelectorChange = async (visibility: Visibility) => {
+    if (memo.visibility === visibility) {
+      return;
+    }
+
     await memoService.patchMemo({
       id: memo.id,
       visibility: visibility,
@@ -135,12 +132,12 @@ const MemoCardDialog: React.FC<Props> = (props: Props) => {
           <div className="btns-container">
             <Only when={!userService.isVisitorMode()}>
               <>
-                <button className="btn" onClick={handlePinClick}>
-                  <i className={`fa-solid fa-thumbtack icon-img ${memo.pinned ? "" : "opacity-20"}`}></i>
-                </button>
-                <button className="btn" onClick={handleVisibilityClick}>
-                  <i className={`fa-solid fa-eye icon-img ${memo.visibility === "PUBLIC" ? "" : "opacity-20"}`}></i>
-                </button>
+                <Selector
+                  className="w-24"
+                  dataSource={visibilityList}
+                  value={memo.visibility}
+                  handleValueChanged={(value) => handleVisibilitySelectorChange(value as Visibility)}
+                />
                 <button className="btn edit-btn" onClick={handleEditMemoBtnClick}>
                   <i className="fa-solid fa-pen-to-square icon-img"></i>
                 </button>
diff --git a/web/src/less/memo-card-dialog.less b/web/src/less/memo-card-dialog.less
index a71e07ce..29f14606 100644
--- a/web/src/less/memo-card-dialog.less
+++ b/web/src/less/memo-card-dialog.less
@@ -15,8 +15,7 @@
       }
 
       > .header-container {
-        .flex(row, space-between, center);
-        @apply w-full h-auto pb-0 my-0;
+        @apply flex flex-row justify-between items-center w-full h-auto z-10 pb-0 my-0;
 
         > .time-text {
           @apply text-sm text-gray-500 font-mono;
diff --git a/web/src/types/modules/memo.d.ts b/web/src/types/modules/memo.d.ts
index 867cb794..0056fad7 100644
--- a/web/src/types/modules/memo.d.ts
+++ b/web/src/types/modules/memo.d.ts
@@ -1,6 +1,6 @@
 type MemoId = number;
 
-type Visibility = "PUBLIC" | "PRIVATE";
+type Visibility = "PUBLIC" | "PROTECTED" | "PRIVATE";
 
 interface Memo {
   id: MemoId;