diff --git a/components/Projects/Form/Select.tsx b/components/Projects/Form/Select.tsx
index cf9e9d56..efb55aeb 100644
--- a/components/Projects/Form/Select.tsx
+++ b/components/Projects/Form/Select.tsx
@@ -1,5 +1,6 @@
import { useState } from 'react';
import { cn } from '@/utils/cn';
+import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
/**
* @typedef {Object} Option
@@ -20,73 +21,79 @@ interface SelectProps {
}
const Select = ({ options, className, isDisabled = false }: SelectProps) => {
+ const [isOpen, setIsOpen] = useState(false);
+ const [selectedLabel, setSelectedLabel] = useState("全部計畫");
+ const handleSelect = (label: string) => {
+ setSelectedLabel(label);
+ setIsOpen(false);
+ };
+
if (!options.length) {
console.error('no option');
return false;
}
- const [isOpen, setIsOpen] = useState(false);
- const [selectedValue, setSelectedValue] = useState("全部計畫");
- const handleSelect = (value: string, label: string) => {
- setSelectedValue(label);
- setIsOpen(false);
- console.log("Selected:", value);
- };
return (
-
+
-
{options.map((option) => (
- handleSelect(option.value, option.label)}
- className="px-4 py-2 rounded-[5px]
- text-basic-400
- hover:bg-primary-lightest
- cursor-pointer"
+ className="px-0"
>
- {option.label}
+
))}
diff --git a/components/Projects/GoBackButton.tsx b/components/Projects/GoBackButton.tsx
index b9e0ee25..2e2101ad 100644
--- a/components/Projects/GoBackButton.tsx
+++ b/components/Projects/GoBackButton.tsx
@@ -1,5 +1,5 @@
-import KeyboardArrowLeftIcon from '@mui/icons-material/KeyboardArrowLeft';
import { cn } from '@/utils/cn';
+import React from 'react';
/**
* Button component for rendering customizable buttons.
@@ -15,6 +15,8 @@ import { cn } from '@/utils/cn';
* - The text displayed on the button.
* @param {string} [className]
* - Optional custom classes to apply to the button (uses Tailwind CSS).
+ * @param {React.ReactNode} [icon]
+ * - Optional custom icon to apply on the button. Typically, a MUI Icon component.
* @param {() => void} onClick
* - Function to call when the button is clicked.
* @returns {JSX.Element} The button element.
@@ -22,6 +24,7 @@ import { cn } from '@/utils/cn';
interface ButtonProps {
id: string,
+ icon?: React.ReactNode,
buttonText: string;
className?: string;
onClick: () => void;
@@ -32,6 +35,7 @@ const GoBackButton = ({
className = "",
id = "",
onClick = () => { },
+ icon = null,
}: ButtonProps
) => {
return (
@@ -40,12 +44,12 @@ const GoBackButton = ({
name={id}
type="button"
onClick={onClick}
- className={cn(`flex flex-row items-center group`, className)}
+ className={cn(
+ "flex flex-row items-center group",
+ className
+ )}
>
-
+ {icon && icon}
{
- if (id) {
- setProjectId(projectId);
- } else {
- setProjectId(null);
- }
- }, [id]);
+ const projectId = searchParams.get('id');
return (
diff --git a/pages/manage/projects/index.jsx b/pages/manage/projects/index.jsx
index 6b49b93e..276c1b59 100644
--- a/pages/manage/projects/index.jsx
+++ b/pages/manage/projects/index.jsx
@@ -1,27 +1,28 @@
-import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import { useSelector } from 'react-redux';
+import KeyboardArrowLeftIcon from '@mui/icons-material/KeyboardArrowLeft';
import Select from '@/components/Projects/Form/Select';
-import AccessDenied from '@/components/Projects/AccessDenied';
+import AccessDenied from '@/shared/components/AccessDenied';
import GoBackButton
from '@/components/Projects/GoBackButton';
import { ProtectedComponent } from '@/contexts/Auth';
import emptyCoverImg from '@/public/assets/empty-cover.png';
import CircleIcon from '@mui/icons-material/Circle';
-import MoreVertIcon from '@mui/icons-material/MoreVert';
import More from '@/components/Projects/More';
+import Button from '@/shared/components/Button';
+import { cn } from '@/utils/cn';
const Projects = () => {
const maxProjects = 3;
const router = useRouter();
- const [isEditPermitted, setIsEditPermitted] = useState(false);
- const [isAddedPermitted, setIsAddedPermitted] = useState(true);
const userState = useSelector((state) => state.user);
+ const projects = Array.isArray(userState.marathons) ? userState.marathons : [];
+ const isEditPermitted = Boolean(projects.length);
+ const isAddedDenied = projects.length >= maxProjects;
const options = [
{ value: "all", label: "全部計畫" },
{ value: "learning-marathon", label: "學習馬拉松" },
];
- const [projects, setProjects] = useState([]);
const getProjectType = (eventId) => {
switch (eventId) {
case "2025S1":
@@ -31,21 +32,6 @@ const Projects = () => {
}
};
- useEffect(() => {
- if (userState._id) {
- if (userState.marathons.length) {
- setProjects(userState.marathons);
- setIsEditPermitted(true);
- }
- }
- }, [userState]);
-
- useEffect(() => {
- if (projects.length > (maxProjects - 1)) {
- setIsAddedPermitted(false);
- }
- }, [projects]);
-
return (
@@ -59,11 +45,22 @@ const Projects = () => {
id: 'island'
}
})}
+ icon={
+ (
+
+ )}
buttonText="返回 我的小島"
/>
學習計畫
{
options={options}
className="max-w-[200px]"
/>
-
+
{
- !isAddedPermitted && (
+ isAddedDenied && (
島上空間有限,計畫滿三個就不能再增加了{`><`}
@@ -135,12 +132,7 @@ const Projects = () => {
{project.isPublic ? '公開' : '不公開'}
- {/*
*/}
-
- {/*
*/}
+
diff --git a/components/Projects/AccessDenied.tsx b/shared/components/AccessDenied.tsx
similarity index 70%
rename from components/Projects/AccessDenied.tsx
rename to shared/components/AccessDenied.tsx
index f7a3d9f8..302b4687 100644
--- a/components/Projects/AccessDenied.tsx
+++ b/shared/components/AccessDenied.tsx
@@ -1,6 +1,6 @@
import { useRouter } from 'next/router';
import AccessDeniedImg from '@/public/assets/projects/access-denied.png';
-import Button from "./Form/Button";
+import Button from "@/shared/components/Button";
const AccessDenied = () => {
const router = useRouter();
@@ -12,11 +12,11 @@ const AccessDenied = () => {
rounded-2xl"
>
這裡目前只開放給
@@ -33,19 +33,19 @@ const AccessDenied = () => {
);
diff --git a/shared/components/Button.tsx b/shared/components/Button.tsx
index 2022c9da..592a0479 100644
--- a/shared/components/Button.tsx
+++ b/shared/components/Button.tsx
@@ -54,7 +54,7 @@ function Button({
variant === ButtonVariantEnum.Outline && [
'rounded-full border border-solid transition-colors',
color === ButtonColorEnum.Primary &&
- 'border-primary-base text-basic-400 hover:bg-primary hover:text-basic-white',
+ 'border-primary-base text-primary-base hover:bg-primary-base hover:text-basic-white',
color === ButtonColorEnum.White &&
'border-basic-white text-basic-white hover:bg-basic-white hover:text-primary-base',
],