Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: user account #134

Merged
merged 14 commits into from
May 18, 2023
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