Skip to content

Commit

Permalink
feat/user account (#136)
Browse files Browse the repository at this point in the history
* feat: create settiing  page

Signed-off-by: neil <[email protected]>

* feat: profile setting page

Signed-off-by: neil <[email protected]>

* feat: settings page

Signed-off-by: neil <[email protected]>

* feat: add  pages

Signed-off-by: neil <[email protected]>

* feat: fetch user info

* feat: auth redirect

Signed-off-by: neil <[email protected]>

* feat: login page

Signed-off-by: neil <[email protected]>

* feat: user profile update

Signed-off-by: neil <[email protected]>

* feat: userinfo loading

Signed-off-by: neil <[email protected]>

---------

Signed-off-by: neil <[email protected]>
  • Loading branch information
nanzm authored May 16, 2023
1 parent 39ac6da commit a6d5353
Show file tree
Hide file tree
Showing 49 changed files with 1,479 additions and 320 deletions.
11 changes: 10 additions & 1 deletion i18n/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,14 @@
},
"next": "Next",
"know_more": "Know more",
"ago": "ago"
"ago": "ago",
"signin": "Signin",
"subscribe": "My Subscribe",
"profile_setting": "Account Settings",
"signout": "SignOut",
"btn": {
"save": "Save",
"cancel": "Cancel",
"func_disabled": "The feature is temporarily disabled"
}
}
28 changes: 28 additions & 0 deletions i18n/en/setting.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"profile": {
"avatar": "Avatar",
"userinfo": "Profile",
"account_settings": "Account Settings",
"form": {
"name": "name",
"name_placeholder": "Please enter your name",
"email": "email",
"email_ques_icon": "The email is used to receive project update notifications.",
"email_placeholder": "Please enter your email address",
"error_require": "{{field}} is a required field",
"error_name_max_len": "nickname cannot exceed {{length}} characters",
"error_email_format": "email format is incorrect"
},
"connected_accounts": "Connected Accounts",
"connected": "Connected",
"disconnect": "Disconnect",
"connect_multiple_accounts_to_your_user_and_sign_in": "Connect multiple accounts to your user and sign in with any of them",
"delete_account": "Delete account",
"delete_account_btn": "Delete account",
"delete_account_warning": " Once you delete your account, there is no going back. Please be certain when taking this action.",
"can_be_used_to_submit_project_after_binding": "Can be used to submit project after binding",
"verified": "Verified",
"unverified_yet": "Unverified yet,",
"resend_verification_email": "resend verification email"
}
}
5 changes: 3 additions & 2 deletions i18n/en/submit_project.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"submit_your_project": "Submit your project",
"single_repository": "Single repository",
"your_project_hosting_on": "Your project hosting on",
"logout": "Logout",
"switch_gitee": "switch to Gitee account",
"switch_github": "switch to GitHub account",
"select_your_own_repository_on": "Select your own repository on {{providerName}}",
"type_the_address_of_any_repository": "Type the address of any repository",
"pick_your_own_repository_on": "Pick your own repository on {{providerName}}",
Expand Down Expand Up @@ -48,7 +49,7 @@
"by_creating_an_account": "By creating an account, you agree to the",
"as_well_as": "as well as",
"terms_of_use": " Terms of Use ",
"non_active_account_processing_specification": " Non-active Account Processing Specification.",
"privacy_policy": " Non-active Account Processing Specification.",
"email_verification_successful": "Email verification successful",
"the_email_address": "The email address",
"has_been_successfully": "has been successfully bound to your OSS Compass account",
Expand Down
10 changes: 9 additions & 1 deletion i18n/zh/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,13 @@
},
"next": "下一个",
"know_more": "了解更多",
"ago": ""
"ago": "",
"signin": "登录",
"profile_setting": "账号设置",
"signout": "退出",
"btn": {
"save": "保存",
"cancel": "取消",
"func_disabled": "该功能临时关闭"
}
}
28 changes: 28 additions & 0 deletions i18n/zh/setting.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"profile": {
"avatar": "头像",
"userinfo": "用户信息",
"account_settings": "账号设置",
"form": {
"name": "昵称",
"name_placeholder": "请输入昵称",
"email": "邮箱",
"email_ques_icon": "该电子邮件用于接收项目更新通知",
"email_placeholder": "请输入邮箱地址",
"error_require": "{{field}}不能为空",
"error_name_max_len": "昵称长度不能超过{{length}}",
"error_email_format": "邮件格式不正确"
},
"connected_accounts": "第三方绑定",
"connected": "绑定",
"disconnect": "解绑",
"connect_multiple_accounts_to_your_user_and_sign_in": "绑定第三方账号,即可使用任何一个账户进行登录。",
"delete_account": "删除账号",
"delete_account_btn": "删除我的账号",
"delete_account_warning": "删除账户后,就无法进行撤销。在执行此操作时,请确保您已经仔细考虑过。",
"can_be_used_to_submit_project_after_binding": "绑定后可用于提交项目",
"verified": "已验证",
"unverified_yet": "未验证,",
"resend_verification_email": "发送验证邮件"
}
}
2 changes: 1 addition & 1 deletion i18n/zh/submit_project.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"by_creating_an_account": "要创建一个帐户,您同意",
"as_well_as": "以及",
"terms_of_use": "使用条款",
"non_active_account_processing_specification": "非活跃帐户处理规范。",
"privacy_policy": "隐私协议",
"email_verification_successful": "邮件验证成功",
"the_email_address": "已成功将邮箱地址",
"has_been_successfully": "与您的 OSS Compass 帐户绑定",
Expand Down
6 changes: 5 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ const nextConfig = {
includePaths: [path.join(__dirname, 'src/styles')],
},
images: {
domains: ['portrait.gitee.com', 'avatars.githubusercontent.com'],
domains: [
'portrait.gitee.com',
'foruda.gitee.com',
'avatars.githubusercontent.com',
],
},
webpack(config) {
config.module.rules.push({
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@
"qrcode": "^1.5.1",
"query-string": "^7.1.1",
"react": "18.2.0",
"react-cropper": "^2.3.3",
"react-datepicker": "^4.11.0",
"react-dom": "18.2.0",
"react-error-boundary": "^3.1.4",
"react-hook-form": "^7.36.0",
"react-hot-toast": "^2.4.1",
"react-hotkeys-hook": "^3.4.7",
"react-i18next": "^12.0.0",
"react-icons": "^4.4.0",
Expand Down
37 changes: 23 additions & 14 deletions src/common/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { PropsWithChildren } from 'react';
import React, { ReactNode, forwardRef } from 'react';
import classnames from 'classnames';
import { cva, type VariantProps } from 'class-variance-authority';
import { twMerge } from 'tailwind-merge';
Expand All @@ -21,6 +21,7 @@ const buttonVariants = cva(
secondary: 'border border-black text-black font-bold hover:bg-gray-100',
danger:
'border-2 border-[#CC0000] text-[#CC0000] font-bold hover:bg-red-600/5',
text: '',
},
size: {
lg: 'text-base px-10 py-3',
Expand All @@ -37,17 +38,22 @@ const buttonVariants = cva(

interface ButtonVariants extends VariantProps<typeof buttonVariants> {}

const Button: React.FC<PropsWithChildren<ButtonProps & ButtonVariants>> = ({
children,
disabled = false,
loading = false,
type = 'button',
intent,
size,
className,
onClick,
...props
}) => {
const Button = forwardRef<
HTMLButtonElement,
ButtonProps & ButtonVariants & { children?: ReactNode | undefined }
>((props, ref) => {
const {
children,
disabled = false,
loading = false,
type = 'button',
intent,
size,
className,
onClick,
...restProps
} = props;

const cls = classnames(
buttonVariants({ intent, size }),
{ 'opacity-50 cursor-not-allowed hover:opacity-50': disabled },
Expand All @@ -56,6 +62,7 @@ const Button: React.FC<PropsWithChildren<ButtonProps & ButtonVariants>> = ({

return (
<button
ref={ref}
type={type}
className={twMerge(cls)}
onClick={(e) => {
Expand All @@ -65,12 +72,14 @@ const Button: React.FC<PropsWithChildren<ButtonProps & ButtonVariants>> = ({
}
onClick?.(e);
}}
{...props}
{...restProps}
>
{loading && <CgSpinner className="mr-1 animate-spin text-xl" />}
{children}
</button>
);
};
});

Button.displayName = 'Button';

export default Button;
70 changes: 70 additions & 0 deletions src/common/components/Header/User.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import Image from 'next/image';
import { AiOutlineUser } from 'react-icons/ai';
import { MdOutlineLogout } from 'react-icons/md';
import client from '@graphql/client';
import { useSignOutMutation } from '@graphql/generated';
import { resetUserInfo } from '@modules/auth/UserInfoStore';
import { useTranslation } from 'react-i18next';
import useProviderInfo from '@modules/auth/useProviderInfo';

const User = () => {
const { t } = useTranslation();
const router = useRouter();
const mutation = useSignOutMutation(client);
const { providerUser: user } = useProviderInfo();

if (!user) {
return (
<Link href="/auth/signin">
<a className={'ml-6 font-medium text-white'}>{t('common:signin')}</a>
</Link>
);
}

return (
<div className="group relative flex h-full items-center pl-6 transition">
<div className="flex h-[32px] cursor-pointer items-center justify-center overflow-hidden rounded-full group-hover:bg-[#333333]">
<Image src={user?.avatarUrl!} width={32} height={32} alt="" />
</div>

<div className="absolute top-[100%] -right-4 z-dropdown hidden w-auto group-hover:block">
<div className="mt-[2px] bg-black/90 text-white">
{/*<Link href="/settings/subscribe">*/}
{/* <a className="flex cursor-pointer border-b border-white/20 py-4 pl-6 text-center last:border-b-0 hover:bg-[#333333]">*/}
{/* {t('common:subscribe')}*/}
{/* </a>*/}
{/*</Link>*/}

<Link href="/settings/profile">
<a className="flex cursor-pointer items-center whitespace-nowrap border-b border-white/20 py-4 px-6 text-center last:border-b-0 hover:bg-[#333333]">
<AiOutlineUser className="mr-2 text-base" />
{t('common:profile_setting')}
</a>
</Link>

<div
className="flex cursor-pointer items-center whitespace-nowrap border-b border-white/20 py-4 pl-6 text-center last:border-b-0 hover:bg-[#333333]"
onClick={() => {
mutation.mutate(
{},
{
onSuccess: () => {
resetUserInfo();
router.push('/auth/signin');
},
}
);
}}
>
<MdOutlineLogout className="mr-2 text-base" /> {t('common:signout')}
</div>
</div>
</div>
</div>
);
};

export default User;
2 changes: 2 additions & 0 deletions src/common/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import MobileHeader from './MobileHeader';
import CommunityDropdown from './CommunityDropdown';
import ChangeLanguage from './ChangeLanguage';
import SubmitYouProject from './SubmitYouProject';
import User from './User';

const Header: React.FC<{
sticky?: boolean;
Expand Down Expand Up @@ -60,6 +61,7 @@ const Header: React.FC<{
<div className="flex h-full items-center">
<ChangeLanguage />
<SubmitYouProject />
<User />
</div>
</div>
</div>
Expand Down
6 changes: 2 additions & 4 deletions src/common/components/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ const Input = forwardRef<
value?: string;
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
defaultValue?: string;
className?: string;
placeholder: string;
placeholder?: string;
error?: boolean;
disabled?: boolean;
}
>((props, ref) => {
const {
name,
className,
defaultValue,
value,
onChange,
onBlur,
Expand All @@ -42,7 +40,7 @@ const Input = forwardRef<
disabled={disabled}
className={classnames(
className,
'daisy-input-bordered daisy-input h-12 flex-1 border-2 px-4 text-base outline-none',
'daisy-input-bordered daisy-input h-12 w-full flex-1 border-2 px-4 text-base outline-none',
[error ? 'border-red-500' : 'border-black']
)}
/>
Expand Down
11 changes: 6 additions & 5 deletions src/common/components/Layout/Center.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { PropsWithChildren } from 'react';
import classnames from 'classnames';

const Center: React.FC<PropsWithChildren<{ className?: string }>> = ({
children,
className,
}) => {
const Center: React.FC<
PropsWithChildren<{ className?: string; widthClassName?: string }>
> = ({ children, className, widthClassName = 'w-[1200px]' }) => {
return (
<div className={classnames('mx-auto w-[1200px]', 'lg:w-full', className)}>
<div
className={classnames('mx-auto', 'lg:w-full', widthClassName, className)}
>
{children}
</div>
);
Expand Down
Loading

1 comment on commit a6d5353

@vercel
Copy link

@vercel vercel bot commented on a6d5353 May 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.