From 750252f8509ed9dcad397fd66522b6f23e1d665e Mon Sep 17 00:00:00 2001
From: VincentXu <90778107+vincentxuu@users.noreply.github.com>
Date: Mon, 7 Oct 2024 19:59:48 +0800
Subject: [PATCH 1/2] adjust the description (#90)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* fix:adjust value of options (#86)
修正以下:
1.刪除高中以下學歷選項
2.刪除交友相關字眼,並新增選項
3.調整揪團教育階段敘述
4.調整學歷敘述
5.調整性別敘述
* Fix/adjust options (#89)
* fix:adjust value of options
* fix:adjust value of rule
---
components/Group/Form/useGroupForm.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/components/Group/Form/useGroupForm.jsx b/components/Group/Form/useGroupForm.jsx
index fd2bc81..f18a272 100644
--- a/components/Group/Form/useGroupForm.jsx
+++ b/components/Group/Form/useGroupForm.jsx
@@ -47,7 +47,7 @@ const rules = {
partnerStyle: z.string().max(50, '請勿輸入超過 50 字'),
partnerEducationStep: z
.array(z.enum(eduOptions.map(({ label }) => label)))
- .min(1, '請選擇的學習階段'),
+ .min(1, '請選擇適合的學習階段'),
description: z
.string()
.min(1, '請輸入揪團描述')
From 6fbc3b9eebaef5e42502e4a9407e2e77dfe0df31 Mon Sep 17 00:00:00 2001
From: VincentXu <90778107+vincentxuu@users.noreply.github.com>
Date: Tue, 8 Oct 2024 00:00:37 +0800
Subject: [PATCH 2/2] fix group page (#92)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* fix:adjust value of options (#86)
修正以下:
1.刪除高中以下學歷選項
2.刪除交友相關字眼,並新增選項
3.調整揪團教育階段敘述
4.調整學歷敘述
5.調整性別敘述
* Fix/adjust options (#89)
* fix:adjust value of options
* fix:adjust value of rule
* feat: optimize login flow (#91)
* fix: adjust shareButtonGroup position (#88)
---------
Co-authored-by: Johnson Mao <86179381+JohnsonMao@users.noreply.github.com>
Co-authored-by: ruby10127130 <52684045+ruby10127130@users.noreply.github.com>
---
components/Group/Form/index.jsx | 15 +-
components/Group/Form/useGroupForm.jsx | 9 +-
components/Group/detail/Contact/index.jsx | 14 +-
components/Group/detail/index.jsx | 14 +-
pages/_app.jsx | 27 ++-
pages/index.jsx | 15 +-
pages/login/index.jsx | 32 ++--
pages/login/popup/index.jsx | 158 ++++++++++++++++++
.../MainNav/Hamberger/MenuList.jsx | 8 +-
.../Navigation_v2/MainNav/SubList/index.jsx | 6 +-
shared/components/Navigation_v2/index.jsx | 2 +-
utils/openLoginWindow.js | 15 ++
utils/share.js | 2 +-
utils/storage.js | 19 +++
14 files changed, 281 insertions(+), 55 deletions(-)
create mode 100644 pages/login/popup/index.jsx
create mode 100644 utils/openLoginWindow.js
create mode 100644 utils/storage.js
diff --git a/components/Group/Form/index.jsx b/components/Group/Form/index.jsx
index 63061b0..ab635d7 100644
--- a/components/Group/Form/index.jsx
+++ b/components/Group/Form/index.jsx
@@ -24,8 +24,15 @@ export default function GroupForm({
isLoading,
onSubmit,
}) {
- const { control, values, errors, isDirty, setValues, handleSubmit } =
- useGroupForm();
+ const {
+ notLogin,
+ control,
+ values,
+ errors,
+ isDirty,
+ setValues,
+ handleSubmit,
+ } = useGroupForm();
const isCreateMode = mode === 'create';
useEffect(() => {
@@ -36,6 +43,10 @@ export default function GroupForm({
});
}, [defaultValues]);
+ if (notLogin) {
+ return ;
+ }
+
return (
diff --git a/components/Group/Form/useGroupForm.jsx b/components/Group/Form/useGroupForm.jsx
index f18a272..502ae9f 100644
--- a/components/Group/Form/useGroupForm.jsx
+++ b/components/Group/Form/useGroupForm.jsx
@@ -1,11 +1,11 @@
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
-import { useRouter } from 'next/router';
import { ZodType, z } from 'zod';
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';
const _eduOptions = EDUCATION_STEP.filter(
(edu) => !['master', 'doctor', 'other'].includes(edu.value),
@@ -57,9 +57,9 @@ const rules = {
};
export default function useGroupForm() {
- const router = useRouter();
const [isDirty, setIsDirty] = useState(false);
const me = useSelector((state) => state.user);
+ const notLogin = !me?._id;
const [values, setValues] = useState({
...DEFAULT_VALUES,
userId: me?._id,
@@ -143,10 +143,11 @@ export default function useGroupForm() {
};
useEffect(() => {
- if (!me?._id) router.push('/login');
- }, [me, router]);
+ if (notLogin) openLoginWindow('/login');
+ }, [notLogin]);
return {
+ notLogin,
control,
errors,
values,
diff --git a/components/Group/detail/Contact/index.jsx b/components/Group/detail/Contact/index.jsx
index 69e3524..5d8934a 100644
--- a/components/Group/detail/Contact/index.jsx
+++ b/components/Group/detail/Contact/index.jsx
@@ -1,7 +1,6 @@
import { useId, useState, forwardRef, useEffect } from 'react';
import { useRouter } from 'next/router';
import { useSelector } from 'react-redux';
-import Link from 'next/link';
import styled from '@emotion/styled';
import {
Avatar,
@@ -20,6 +19,7 @@ import { ROLE } from '@/constants/member';
import chatSvg from '@/public/assets/icons/chat.svg';
import useMutation from '@/hooks/useMutation';
import { mapToTable } from '@/utils/helper';
+import openLoginWindow from '@/utils/openLoginWindow';
import Feedback from './Feedback';
const ROLELIST = mapToTable(ROLE);
@@ -55,17 +55,18 @@ const StyledTextArea = styled(TextareaAutosize)`
width: 100%;
min-height: 128px;
`;
-const StyledLink = styled(Link)`
+const StyledText = styled.div`
margin-top: 6px;
margin-left: 6px;
display: block;
color: black;
font-size: 12px;
`;
-const StyledSpan = styled.span`
+const StyledLink = styled.span`
padding: 0 2px;
color: #16b9b3;
text-decoration: underline;
+ cursor: pointer;
`;
const Transition = forwardRef((props, ref) => {
@@ -152,10 +153,11 @@ function ContactButton({
{label}
{!isLogin && (
-
- 註冊或登入
+
+ router.push('/login')}>註冊或
+ openLoginWindow()}>登入
即可聯繫主揪!
-
+
)}
{isMyGroup ? (
)}
+
+
+
{isLoading ? : source?.title}
diff --git a/pages/_app.jsx b/pages/_app.jsx
index 8697a18..6604fc8 100644
--- a/pages/_app.jsx
+++ b/pages/_app.jsx
@@ -6,14 +6,14 @@ import { Provider, useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';
import Script from 'next/script';
import Head from 'next/head';
-import { initializeApp } from 'firebase/app';
import { persistStore } from 'redux-persist';
import { PersistGate } from 'redux-persist/integration/react';
import SnackbarProvider from '@/contexts/Snackbar';
import GlobalStyle from '@/shared/styles/Global';
import themeFactory from '@/shared/styles/themeFactory';
import storeFactory from '@/redux/store';
-import { checkLoginValidity } from '@/redux/actions/user';
+import { checkLoginValidity, fetchUserById } from '@/redux/actions/user';
+import { getRedirectionStorage } from '@/utils/storage';
import { initGA, logPageView } from '../utils/analytics';
import Mode from '../shared/components/Mode';
import 'regenerator-runtime/runtime'; // Speech.js
@@ -112,15 +112,36 @@ const App = ({ Component, pageProps }) => {
const ThemeComponentWrap = ({ pageProps, Component }) => {
const dispatch = useDispatch();
- const firebaseApp = initializeApp(firebaseConfig);
const mode = useSelector((state) => state?.theme?.mode ?? 'light');
const theme = useMemo(() => themeFactory(mode), [mode]);
const isEnv = useMemo(() => process.env.NODE_ENV === 'development', []);
+ const router = useRouter();
useEffect(() => {
dispatch(checkLoginValidity());
}, []);
+ useEffect(() => {
+ const receiveMessage = (e) => {
+ if (e.origin !== window.location.origin) return;
+ if (e.data.isLogin) {
+ const { token, id } = e.data;
+ const redirectionStorage = getRedirectionStorage();
+ const redirection = redirectionStorage.get();
+ dispatch(fetchUserById(id, token));
+ if (redirection) {
+ redirectionStorage.remove();
+ router.push(redirection);
+ }
+ }
+ };
+ window.addEventListener('message', receiveMessage, false);
+
+ return () => {
+ window.removeEventListener('message', receiveMessage, false);
+ };
+ }, []);
+
return (
{/* mui normalize css */}
diff --git a/pages/index.jsx b/pages/index.jsx
index b132474..2e3f97d 100644
--- a/pages/index.jsx
+++ b/pages/index.jsx
@@ -1,8 +1,6 @@
import React, { useMemo, useEffect } from 'react';
import styled from '@emotion/styled';
import { useRouter } from 'next/router';
-import { useDispatch, useSelector } from 'react-redux';
-import { fetchUserById } from '@/redux/actions/user';
import SEOConfig from '../shared/components/SEO';
import Home from '../components/Home';
import Navigation from '../shared/components/Navigation_v2';
@@ -47,14 +45,15 @@ const HomePage = () => {
[router?.asPath],
);
- // fetch signin userData with token and id from query String
-
- const dispatch = useDispatch();
const { token, id } = router.query;
+
useEffect(() => {
- if (token) {
- dispatch(fetchUserById(id, token));
- router.push('/');
+ if (id && token) {
+ window.opener?.postMessage(
+ { isLogin: true, id, token },
+ window.location.origin,
+ );
+ window.close();
}
}, [id, token]);
diff --git a/pages/login/index.jsx b/pages/login/index.jsx
index b235006..45f8e3c 100644
--- a/pages/login/index.jsx
+++ b/pages/login/index.jsx
@@ -1,7 +1,6 @@
import React, { useMemo } from 'react';
import styled from '@emotion/styled';
import { useRouter } from 'next/router';
-import Link from '@mui/material/Link';
import Script from 'next/script';
import { Box, Typography, Button, Skeleton } from '@mui/material';
import { LazyLoadImage } from 'react-lazy-load-image-component';
@@ -9,6 +8,7 @@ import SEOConfig from '@/shared/components/SEO';
import Navigation from '@/shared/components/Navigation_v2';
import Footer from '@/shared/components/Footer_v2';
import { BASE_URL } from '@/constants/common';
+import openLoginWindow from '@/utils/openLoginWindow';
// import sendDataToChromeExtension from '../../utils/sendDataToChromeExtension';
const HomePageWrapper = styled.div`
@@ -38,7 +38,7 @@ const ContentWrapper = styled.div`
`;
const LoginPage = () => {
- const LOGINPATH = `${BASE_URL}/auth/google`;
+ const LOGIN_PATH = `${BASE_URL}/auth/google`;
const router = useRouter();
const SEOData = useMemo(
@@ -101,21 +101,19 @@ const LoginPage = () => {
/>
}
/>
-
-
-
+
{`註冊即代表您同意島島阿學的 `}
diff --git a/pages/login/popup/index.jsx b/pages/login/popup/index.jsx
new file mode 100644
index 0000000..c1a5786
--- /dev/null
+++ b/pages/login/popup/index.jsx
@@ -0,0 +1,158 @@
+import React, { useMemo } from 'react';
+import styled from '@emotion/styled';
+import { useRouter } from 'next/router';
+import Link from '@mui/material/Link';
+import Script from 'next/script';
+import { Box, Typography, Button, Skeleton } from '@mui/material';
+import { LazyLoadImage } from 'react-lazy-load-image-component';
+import SEOConfig from '@/shared/components/SEO';
+import { NavigationWrapper } from '@/shared/components/Navigation_v2';
+import { BASE_URL } from '@/constants/common';
+import Logo from '@/shared/components/Navigation_v2/MainNav/Logo';
+
+const HomePageWrapper = styled.div`
+ --section-height: calc(100vh - 80px);
+ --section-height-offset: 80px;
+ background: linear-gradient(0deg, #f3fcfc, #f3fcfc), #f7f8fa;
+`;
+
+const ContentWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background-color: #fff;
+ border-radius: 8px;
+ margin: 60px auto;
+ padding: 40px 40px;
+ max-width: 440px;
+ width: 100%;
+ @media (max-width: 767px) {
+ width: 90%;
+ .title {
+ text-overflow: ellipsis;
+ width: 100%;
+ }
+ }
+`;
+
+const LoginPage = () => {
+ const LOGINPATH = `${BASE_URL}/auth/google`;
+ const router = useRouter();
+
+ const SEOData = useMemo(
+ () => ({
+ title: '登入島島|島島阿學',
+ description:
+ '「島島阿學」盼能透過建立多元的學習資源網絡,讓自主學習者能找到合適的成長方法,進一步成為自己想成為的人,從中培養共好精神。目前正積極打造「可共編的學習資源平台」。',
+ keywords: '島島阿學',
+ author: '島島阿學',
+ copyright: '島島阿學',
+ imgLink: 'https://www.daoedu.tw/preview.webp',
+ link: `${process.env.HOSTNAME}${router?.asPath}`,
+ }),
+ [router?.asPath],
+ );
+
+ return (
+ <>
+
+
+
+
+
+
+
+ 歡迎回來島島阿學!
+
+
+ }
+ />
+
+
+
+
+
+ {`註冊即代表您同意島島阿學的 `}
+ {
+ router.push('/privacypolicy');
+ }}
+ sx={{
+ color: '#16B9B3',
+ fontWeight: 700,
+ fontSize: '14px',
+ textDecoration: 'underline',
+ cursor: 'pointer',
+ }}
+ >
+ 服務條款
+
+ {` 與 `}
+ {
+ router.push('/privacypolicy');
+ }}
+ sx={{
+ color: '#16B9B3',
+ fontWeight: 700,
+ fontSize: '14px',
+ textDecoration: 'underline',
+ cursor: 'pointer',
+ }}
+ >
+ 隱私政策
+
+
+
+
+ >
+ );
+};
+
+export default LoginPage;
diff --git a/shared/components/Navigation_v2/MainNav/Hamberger/MenuList.jsx b/shared/components/Navigation_v2/MainNav/Hamberger/MenuList.jsx
index 2b8c713..06017da 100644
--- a/shared/components/Navigation_v2/MainNav/Hamberger/MenuList.jsx
+++ b/shared/components/Navigation_v2/MainNav/Hamberger/MenuList.jsx
@@ -1,9 +1,9 @@
import styled from '@emotion/styled';
-import MenuItem from './MenuItem';
-import UserAvatar from '../SubList/UserAvatar';
import { useSelector } from 'react-redux';
import { Button } from '@mui/material';
-import { BASE_URL } from '@/constants/common';
+import openLoginWindow from '@/utils/openLoginWindow';
+import UserAvatar from '../SubList/UserAvatar';
+import MenuItem from './MenuItem';
const MenuWrapper = styled.div`
position: fixed;
@@ -66,7 +66,7 @@ const Menu = ({ open, list, onCloseMenu, shiftTop = '80px' }) => {
{user._id ? (
) : (
- 登入
+ openLoginWindow()}>登入
)}
)}
diff --git a/shared/components/Navigation_v2/MainNav/SubList/index.jsx b/shared/components/Navigation_v2/MainNav/SubList/index.jsx
index a3ec13b..f32369a 100644
--- a/shared/components/Navigation_v2/MainNav/SubList/index.jsx
+++ b/shared/components/Navigation_v2/MainNav/SubList/index.jsx
@@ -1,10 +1,10 @@
import React from 'react';
import styled from '@emotion/styled';
import Link from 'next/link';
-import UserAvatar from './UserAvatar';
import { useSelector } from 'react-redux';
import { Button } from '@mui/material';
-import { BASE_URL } from '@/constants/common';
+import openLoginWindow from '@/utils/openLoginWindow';
+import UserAvatar from './UserAvatar';
const LinkListWrapper = styled.ul`
display: flex;
@@ -63,7 +63,7 @@ const SubList = () => {
) : (