Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/daodaoedu/daodao-f2e into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentxuu committed Dec 13, 2024
2 parents ff9b4e1 + f50db5e commit ccc6542
Show file tree
Hide file tree
Showing 55 changed files with 1,643 additions and 795 deletions.
11 changes: 10 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,22 @@ module.exports = {
settings: {
'import/resolver': {
alias: {
extensions: ['.js', '.jsx'],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
map: [['@', '.']],
},
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx']
},
},
},
rules: {
"import/no-extraneous-dependencies": ["error", { devDependencies: ["./*.js"] }],
'import/extensions': ['error', 'ignorePackages', {
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
}],
'react/no-unescaped-entities': 'off',
'@next/next/no-page-custom-font': 'off',
'react/prop-types': [0],
Expand Down
9 changes: 7 additions & 2 deletions components/Group/Form/Form.styled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ export const StyledDescription = styled.p`

export const StyledContainer = styled.main`
position: relative;
display: flex;
align-items: center;
flex-direction: column;
background: #f3fcfc;
padding: 60px 0;
min-height: 100vh;
margin: 0 auto;
width: 720px;
.MuiInputBase-input,
.MuiFormControlLabel-label {
Expand All @@ -30,7 +35,6 @@ export const StyledContainer = styled.main`
@media (max-width: 760px) {
padding: 20px;
width: 100%;
}
`;

Expand Down Expand Up @@ -58,6 +62,7 @@ export const StyledGroup = styled.div`
export const StyledFooter = styled.div`
display: flex;
justify-content: center;
width: 100%;
`;

export const StyledChip = styled(Chip)`
Expand Down
18 changes: 7 additions & 11 deletions components/Group/Form/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Button from '@/shared/components/Button';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import { activityCategoryList } from '@/constants/activityCategory';
import { ProtectedComponent } from '@/contexts/Auth';
import StyledPaper from '../Paper.styled';
import {
StyledHeading,
Expand Down Expand Up @@ -40,7 +41,6 @@ export default function GroupForm({
onSubmit,
}) {
const {
notLogin,
control,
values,
errors,
Expand All @@ -66,14 +66,10 @@ export default function GroupForm({
<Checkbox size="small" onClick={() => setIsChecked((pre) => !pre)} />
);

if (notLogin) {
return <Box sx={{ minHeight: '50vh' }} />;
}

return (
<Box sx={{ background: '#f3fcfc', py: '60px' }}>
<ProtectedComponent>
<StyledContainer>
<StyledPaper sx={{ p: '40px', mb: '16px' }}>
<StyledPaper className="p-10 mb-4 md:w-[720px]">
<StyledHeading>
{isCreateMode ? '發起揪團' : '編輯揪團'}
</StyledHeading>
Expand Down Expand Up @@ -149,7 +145,7 @@ export default function GroupForm({
placeholder="希望在什麼時間舉行?"
/>
</StyledPaper>
<StyledPaper sx={{ p: '40px', mb: '16px' }}>
<StyledPaper className="p-10 mb-4 md:w-[720px]">
<Fields.TextField
label="想找的夥伴"
name="partnerStyle"
Expand Down Expand Up @@ -219,7 +215,7 @@ export default function GroupForm({
helperText="標籤填寫完成後,會用 Hashtag 的形式呈現,例如: #一起學日文"
/>
</StyledPaper>
<StyledPaper>
<StyledPaper className="md:w-[720px]">
<Fields.DateRadio
label="揪團期限"
name="deadline"
Expand All @@ -230,7 +226,7 @@ export default function GroupForm({
/>
</StyledPaper>
{!isCreateMode && (
<StyledPaper sx={{ p: '40px', mt: '16px' }}>
<StyledPaper className="p-10 mb-4 md:w-[720px]">
<StyledSwitchWrapper>
{values.isGrouping ? '開放揪團中' : '已關閉揪團'}
<Switch
Expand Down Expand Up @@ -277,6 +273,6 @@ export default function GroupForm({
</Button>
</StyledFooter>
</StyledContainer>
</Box>
</ProtectedComponent>
);
}
25 changes: 6 additions & 19 deletions components/Group/Form/useGroupForm.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import dayjs from 'dayjs';
import { useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { useRef, useState } from 'react';
import { ZodType, z } from 'zod';
import { useSnackbar } from '@/contexts/Snackbar';
import { CATEGORIES } from '@/constants/category';
import { AREAS } from '@/constants/areas';
import { EDUCATION_STEP } from '@/constants/member';
import { BASE_URL } from '@/constants/common';
import openLoginWindow from '@/utils/openLoginWindow';
import { activityCategoryList } from '@/constants/activityCategory';
import useLeaveConfirm from '@/hooks/useLeaveConfirm';
import { useAuth } from '@/contexts/Auth';

const _eduOptions = EDUCATION_STEP.filter(
(edu) => !['master', 'doctor', 'other'].includes(edu.value),
Expand Down Expand Up @@ -84,9 +83,8 @@ const rules = {
};

export default function useGroupForm(defaultValue) {
const { user, token } = useAuth();
const [isDirty, setIsDirty] = useState(false);
const me = useSelector((state) => state.user);
const notLogin = !me?._id;
const [values, setValues] = useState(() => ({
...INITIAL_VALUES,
...defaultValue,
Expand All @@ -96,7 +94,7 @@ export default function useGroupForm(defaultValue) {
rule.safeParse(defaultValue[key])?.data ?? INITIAL_VALUES[key],
])
),
userId: me?._id,
userId: user?._id,
}));
const [errors, setErrors] = useState({});
const { pushSnackbar } = useSnackbar();
Expand Down Expand Up @@ -136,7 +134,7 @@ export default function useGroupForm(defaultValue) {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${me.token}`,
Authorization: `Bearer ${token}`,
},
});
};
Expand All @@ -154,7 +152,7 @@ export default function useGroupForm(defaultValue) {
const response = await fetch(`${BASE_URL}/image`, {
method: 'POST',
headers: {
Authorization: `Bearer ${me.token}`,
Authorization: `Bearer ${token}`,
},
body: formData,
});
Expand Down Expand Up @@ -211,20 +209,9 @@ export default function useGroupForm(defaultValue) {
onValid({ ...result.data, photoURL });
};

useEffect(() => {
let timer;
if (notLogin) {
timer = setTimeout(() => {
openLoginWindow();
}, 100);
}
return () => clearTimeout(timer);
}, [notLogin]);

useLeaveConfirm({ shouldConfirm: isDirty });

return {
notLogin,
control,
errors,
values,
Expand Down
6 changes: 3 additions & 3 deletions components/Group/detail/index.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useRouter } from 'next/navigation';
import { useSelector } from 'react-redux';
import Box from '@mui/material/Box';
import Skeleton from '@mui/material/Skeleton';
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
import { useAuth } from '@/contexts/Auth';
import Image from '@/shared/components/Image';
import ContactButton from '@/shared/components/ContactButton';
import { StyledStatus } from '../GroupList/GroupCard.styled';
Expand All @@ -22,8 +22,8 @@ import ShareButtonGroup from './ShareButtonGroup';

function GroupDetail({ id, source, isLoading }) {
const router = useRouter();
const me = useSelector((state) => state.user);
const isMyGroup = source?.userId === me?._id && !!me?._id;
const { user } = useAuth();
const isMyGroup = source?.userId === user?._id && !!user?._id;

return (
<Box sx={{ background: '#f3fcfc', pb: '48px' }}>
Expand Down
15 changes: 13 additions & 2 deletions components/Marathon/Banner/index.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useRouter } from 'next/router';
import { useRouter } from 'next/navigation';
import styled from '@emotion/styled';
import Button from '@/shared/components/Button';
import groupBannerImg from '@/public/assets/group-banner.png';
import Image from '@/shared/components/Image';
import InfoCompletionGuard from '@/shared/components/InfoCompletionGuard';
import { useAuth, useAuthDispatch } from '@/contexts/Auth';

const StyledBanner = styled.div`
position: relative;
Expand Down Expand Up @@ -48,6 +49,16 @@ const StyledBannerContent = styled.div`

const Banner = () => {
const router = useRouter();
const { isLoggedIn, isTemporary } = useAuth();
const { openLoginModal } = useAuthDispatch();

const handleClick = () => {
if (isLoggedIn || isTemporary) {
router.push('/learning-marathon/signup');
} else {
openLoginModal('/learning-marathon/signup');
}
};

return (
<StyledBanner>
Expand All @@ -64,7 +75,7 @@ const Banner = () => {
<h1>島島盃 - 學習馬拉松 2025 春季賽</h1>
<p>註冊並加入我們,立即報名!</p>
<InfoCompletionGuard>
<Button onClick={() => router.push('/learning-marathon/login')}>立即報名</Button>
<Button onClick={handleClick}>立即報名</Button>
</InfoCompletionGuard>
</StyledBannerContent>
</StyledBanner>
Expand Down
6 changes: 4 additions & 2 deletions components/Marathon/SignUp/ConfirmForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Radio,
FormControlLabel,
} from '@mui/material';
import { useAuthDispatch } from '@/contexts/Auth';

import {
StyledSection,
Expand Down Expand Up @@ -217,6 +218,7 @@ export default function ConfirmForm({
const token = useSelector((state) => { return state.user.token; });
const [newMarathon, setNewMarathon] = useState(reduxInitMarathonState);
const router = useRouter();
const { openLoginModal } = useAuthDispatch();
const [user, setUser] = useState({
name: "",
token: "",
Expand Down Expand Up @@ -259,9 +261,9 @@ export default function ConfirmForm({
location: userLocation
});
} else {
router.push('/learning-marathon/login');
openLoginModal();
}
}, [userState]);
}, [userState, openLoginModal]);
const onSubmit = async () => {
if (!marathonState) {
console.error('no data to submit');
Expand Down
3 changes: 0 additions & 3 deletions components/Marathon/SignUp/UserProfileForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,6 @@ export default function UserProfileForm({
};

useEffect(() => {
if (!user._id && (user.userType !== 'no_data')) {
router.push('/');
}
if (user._id) {
Object.entries(user).forEach(([key, value]) => {
if (key === 'contactList') {
Expand Down
3 changes: 3 additions & 0 deletions components/Marathon/SignUp/useEditProfile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useReducer, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import { updateUser, createUser } from '@/redux/actions/user';
import { z } from 'zod';
import { useAuthDispatch } from '@/contexts/Auth';

const initialState = {
name: '',
Expand Down Expand Up @@ -112,6 +113,7 @@ const userReducer = (state, payload) => {
const useEditProfile = () => {
const reduxDispatch = useDispatch();
const [userState, stateDispatch] = useReducer(userReducer, initialState);
const authDispatch = useAuthDispatch();
const [errors, setErrors] = useState({});
const refs = useRef({});

Expand Down Expand Up @@ -230,6 +232,7 @@ const useEditProfile = () => {
} else {
reduxDispatch(createUser(payload));
}
authDispatch.updateUser(payload);
return true;
};

Expand Down
7 changes: 4 additions & 3 deletions components/Partner/Banner/index.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useSelector } from 'react-redux';
import styled from '@emotion/styled';
import { useRouter } from 'next/router';
import { Box } from '@mui/material';
import Button from '@/shared/components/Button';
import Image from '@/shared/components/Image';
import partnerImg from '@/public/assets/partner-banner.png';
import { useSelector } from 'react-redux';
import { useAuth } from '@/contexts/Auth';

const StyledBanner = styled(Box)(({ theme }) => ({
height: '398px',
Expand Down Expand Up @@ -62,15 +63,15 @@ const StyledContent = styled(Box)(({ theme }) => ({
const Banner = () => {
const router = useRouter();
// select token from user
const { token } = useSelector((state) => state.user);
const { isLoggedIn } = useAuth();

return (
<StyledBanner>
<StyledContent>
<h1>尋找夥伴</h1>
<p>想找到一起交流的學習夥伴嗎</p>
<p>註冊加入會員,並填寫個人資料,你的資訊就會刊登在頁面上囉!</p>
{!token && (
{!isLoggedIn && (
<Button onClick={() => router.push('/login')}>註冊找夥伴</Button>
)}
</StyledContent>
Expand Down
Loading

0 comments on commit ccc6542

Please sign in to comment.