Skip to content

Commit

Permalink
Merge pull request #121 from cuculus-dev/feature/issues-120
Browse files Browse the repository at this point in the history
プロフィール編集画面
  • Loading branch information
takecchi committed Dec 14, 2023
2 parents 0943b58 + d074365 commit ebf012a
Show file tree
Hide file tree
Showing 17 changed files with 675 additions and 175 deletions.
46 changes: 24 additions & 22 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,31 @@ const config: StorybookConfig = {
autodocs: true,
},
webpackFinal: async (config) => {
/**
* FIXME 良い方法があればそっちに変更したい。
* SVGに関するルールを削除
*/
config.module.rules = config.module.rules.map((rule) => {
if (
rule &&
rule !== '...' &&
rule.test instanceof RegExp &&
rule.test.test('.svg')
) {
return undefined;
}
return rule;
});
if (config.module && config.module.rules) {
/**
* FIXME 良い方法があればそっちに変更したい。
* SVGに関するルールを削除
*/
config.module.rules = config.module.rules.map((rule) => {
if (
rule &&
rule !== '...' &&
rule.test instanceof RegExp &&
rule.test.test('.svg')
) {
return undefined;
}
return rule;
});

config.module.rules.push({
test: /\.svg$/,
issuer: {
and: [/\.(js|ts)x?$/],
},
use: ['@svgr/webpack'],
});
config.module.rules.push({
test: /\.svg$/,
issuer: {
and: [/\.(js|ts)x?$/],
},
use: ['@svgr/webpack'],
});
}
if (config.resolve?.alias) {
config.resolve.alias = {
...config.resolve.alias,
Expand Down
2 changes: 1 addition & 1 deletion .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Preview } from '@storybook/react';
import theme from '@/theme/theme';
import theme from '../src/theme/theme';
import { withThemeFromJSXProvider } from '@storybook/addon-styling';
import { CssBaseline, ThemeProvider } from '@mui/material';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
Expand Down
32 changes: 28 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}
},
"dependencies": {
"@cuculus/cuculus-api": "^0.4.0",
"@cuculus/cuculus-api": "^0.4.1",
"@ducanh2912/next-pwa": "^9.7.1",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
Expand All @@ -32,6 +32,7 @@
"next": "^13.5.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-easy-crop": "^5.0.2",
"swr": "^2.2.1",
"virtua": "^0.17.4"
},
Expand Down
18 changes: 2 additions & 16 deletions src/app/(menu)/(public)/[username]/_components/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,15 @@ type Props = {
};
export default function ProfilePage({ fallbackData }: Props) {
const { data, isLoading } = useUser(fallbackData.username, fallbackData);
const { data: authId, isLoading: authorizing } = useAuth();
const { data: authId } = useAuth();
if (!data) {
// FIXME 読み込み中
return <></>;
}

return (
<PrimaryColumn columnName={data.name} showBack>
<ProfileCard
name={data.name}
username={data.username}
id={data.id}
protected={data._protected}
followingCount={data.followingCount}
followersCount={data.followersCount}
createdAt={data.createdAt}
bio={data.bio}
profileImageUrl={data.profileImageUrl}
url={data.url}
verified={data.verified}
authId={authId}
authorizing={authorizing}
/>
<ProfileCard authId={authId} {...data} />
{!isLoading && <UserTimeline user={data} />}
</PrimaryColumn>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ type Story = StoryObj<typeof meta>;
export const NormalFollowButton: Story = {
args: {
userId: 123,
followStatus: 'NotFollowing',
isFollowing: true,
},
};
Original file line number Diff line number Diff line change
@@ -1,83 +1,21 @@
'use client';

import CapsuleButton from '@/app/_components/button/CapsuleButton';
import { ButtonTypeMap } from '@mui/material';
import { MouseEventHandler } from 'react';
import { OverridableStringUnion } from '@mui/types';
import { ButtonPropsVariantOverrides } from '@mui/material/Button';

// static class propertyにして文字列で持たせる?(interfaceどうするか)(enum使う?)
export type FollowStatus =
| 'NotFollowing'
| 'Following'
| 'Pending'
| 'Blocked'
| 'EditProfile';

interface Props {
type Props = {
userId: number;
followStatus: FollowStatus;
}

export function FollowButton({ followStatus }: Props) {
// TODO ボタン処理実装
const follow: MouseEventHandler<HTMLButtonElement> = () => {
// doPost(followActionUrl)
};

// TODO ボタン処理実装
const unfollow: MouseEventHandler<HTMLButtonElement> = () => {
// doDelete(followActionUrl);
};

// TODO ボタン処理実装
const cancelRequest: MouseEventHandler<HTMLButtonElement> = () => {
// doCancel(???);
};

const editProfile: MouseEventHandler<HTMLButtonElement> = () => {
// editProfile(???);
};
isFollowing: boolean;
};

const [color, enabled, text, onClick, variant] = ((): [
ButtonTypeMap['props']['color'],
boolean,
string,
MouseEventHandler<HTMLButtonElement> | undefined,
OverridableStringUnion<
'text' | 'outlined' | 'contained',
ButtonPropsVariantOverrides
>,
] => {
switch (followStatus) {
case 'NotFollowing':
return ['primary', true, 'フォロー', unfollow, 'contained'];
case 'Following':
return ['primary', true, 'フォロー中', follow, 'outlined'];
case 'Pending':
return ['secondary', true, '承認待ち', cancelRequest, 'outlined'];
case 'Blocked':
return [
'warning',
false,
'ブロックされています',
undefined,
'outlined',
];
case 'EditProfile':
return ['primary', true, 'プロフィールを編集', editProfile, 'outlined'];
default:
return ['error', false, '(invalid value)', undefined, 'outlined'];
}
})();
export function FollowButton({ isFollowing }: Props) {
const text = isFollowing ? 'フォロー中' : 'フォロー';

return (
<CapsuleButton
aria-label={text}
color={color}
disabled={!enabled}
onClick={onClick}
variant={variant}
color="primary"
// onClick={onClick}
variant={isFollowing ? 'outlined' : 'contained'}
>
{text}
</CapsuleButton>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client';

import { styled } from '@mui/material';

const HeaderImage = styled('div')<{
image?: string;
}>`
display: block;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
aspect-ratio: 3 / 1;
background-color: ${({ theme }) => theme.palette.primary.light};
background-image: ${({ image }) => (image ? `url(${image})` : 'none')};
`;

export default HeaderImage;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client';

import { Avatar, styled } from '@mui/material';

const UserIcon = styled(Avatar)`
width: 120px;
height: 120px;
margin-top: -80px;
border-color: ${({ theme }) => theme.palette.background.paper};
border-style: solid;
${({ theme }) => theme.breakpoints.down('tablet')} {
width: 92px;
height: 92px;
margin-top: -61px;
}
`;

export default UserIcon;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use client';

import CapsuleButton from '@/app/_components/button/CapsuleButton';
import ProfileSettingModal from '@/app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal';
import { useState } from 'react';
import { useProfile } from '@/swr/client/auth';

export function EditProfileButton() {
const text = 'プロフィールを編集';
const [open, setOpen] = useState<boolean>(false);
const { data } = useProfile();

if (!data) {
return <></>;
}

return (
<>
<CapsuleButton
aria-label={text}
color="primary"
onClick={() => {
setOpen(true);
}}
variant="outlined"
>
{text}
</CapsuleButton>
<ProfileSettingModal
open={open}
bio={data.bio}
displayName={data.name}
src={data.profileImageUrl}
onClose={() => setOpen(false)}
/>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ export const NormalProfileCard: Story = {
username: 'takecchi',
createdAt: new Date('2023-10-04T18:57:44.373Z'),
profileImageUrl: '/mock/profileAvatarImage.png',
protected: false,
_protected: false,
verified: false,
bio: 'こんにちは。',
url: '',
followersCount: 2,
followingCount: 1,
authId: undefined,
authorizing: false,
},
};
Loading

0 comments on commit ebf012a

Please sign in to comment.