Skip to content

Commit

Permalink
profile redux
Browse files Browse the repository at this point in the history
  • Loading branch information
Shuaige1234567 committed Dec 13, 2023
1 parent a140b96 commit d2338ff
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 83 deletions.
10 changes: 8 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,26 @@ import Settings from './routes/settings';
import {Home} from "./routes/home";
import {useAuth} from "./utils/useAuth";
import Feed from "./actors/feed";
import {userApi} from "./actors/user";
import {updateProfile} from "./redux";

function App() {
const {userFeedCai} = useAuth()
const {userFeedCai, principal} = useAuth()

const fetch = async () => {
if (!userFeedCai) return
const feedApi = new Feed(userFeedCai)
await feedApi.getAllPost()
await feedApi.getLatestFeed(20)
if (!principal) return
const res = await userApi.getProfile(principal)
if (!res[0]) return
updateProfile(res[0])
}

useEffect(() => {
fetch()
}, [userFeedCai])
}, [userFeedCai, principal])

return (
<div className="App">
Expand Down
82 changes: 45 additions & 37 deletions frontend/src/components/Modal/form.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React, { useState } from 'react';
import React, {useState} from 'react';
import {
Button,
Form,
Input,
notification,
} from 'antd';
import {Profile} from "../../declarations/user/user";
import { userApi } from '../../actors/user';
import { LoadingOutlined, CheckOutlined } from '@ant-design/icons';
import {userApi} from '../../actors/user';
import {LoadingOutlined, CheckOutlined} from '@ant-design/icons';
import {updateProfile} from "../../redux";
import {useAuth} from "../../utils/useAuth";

interface DataNodeType {
value: string;
Expand All @@ -17,59 +19,65 @@ interface DataNodeType {

const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
xs: {span: 24},
sm: {span: 8},
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
xs: {span: 24},
sm: {span: 16},
},
};

const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
};

interface ProfileFormProps {
userProfile: Profile | undefined;
drawCallBack: () => void;
userProfile: Profile | undefined;
drawCallBack: () => void;
}

export default function ProfileForm(props: ProfileFormProps) {
const [form] = Form.useForm();
const [api, contextHolder] = notification.useNotification();
const {principal} = useAuth()

const onFinish = async (values: any) => {
api.info({
message: 'Update Profile ing ...',
key: 'updateProfile',
duration: null,
description: '',
icon: <LoadingOutlined />
icon: <LoadingOutlined/>
})
await userApi.createProfile({
'backImgUrl' : values.backImgUrl === undefined? '' : values.backImgUrl,
'name' : values.name === undefined? '' : values.name,
'education' : values.education === undefined? '' : values.education,
'biography' : values.biography === undefined? '' : values.biography,
'company' : values.company === undefined? '' : values.company,
'avatarUrl' : values.avatarUrl === undefined? '' : values.avatarUrl,
'feedCanister' : [],
'backImgUrl': values.backImgUrl === undefined ? '' : values.backImgUrl,
'name': values.name === undefined ? '' : values.name,
'education': values.education === undefined ? '' : values.education,
'biography': values.biography === undefined ? '' : values.biography,
'company': values.company === undefined ? '' : values.company,
'avatarUrl': values.avatarUrl === undefined ? '' : values.avatarUrl,
'feedCanister': [],
});
if (principal) {
const res = await userApi.getProfile(principal)
if (!res[0]) return
updateProfile(res[0])
}
api.success({
message: 'Update Profile Successful !',
key: 'updateProfile',
description: '',
icon: <CheckOutlined />
icon: <CheckOutlined/>
});
props.drawCallBack();
console.log('Received values of form: ', values);
Expand All @@ -89,8 +97,8 @@ export default function ProfileForm(props: ProfileFormProps) {
avatarUrl: props.userProfile?.avatarUrl,
feedCanister: props.userProfile?.feedCanister[0]?.toString(),
biography: props.userProfile?.biography
}}
style={{ maxWidth: 600 }}
}}
style={{maxWidth: 600}}
scrollToFirstError
>
{contextHolder}
Expand All @@ -104,50 +112,50 @@ export default function ProfileForm(props: ProfileFormProps) {
},
]}
>
<Input />
<Input/>
</Form.Item>

<Form.Item
name="company"
label="Company"
>
<Input />
<Input/>
</Form.Item>

<Form.Item
name="education"
label="Education"
>
<Input />
<Input/>
</Form.Item>

<Form.Item
name="avatarUrl"
label="AvatarUrl"
>
<Input />
<Input/>
</Form.Item>

<Form.Item
name="backImgUrl"
label="BackImgUrl"
>
<Input />
<Input/>
</Form.Item>

<Form.Item
name="feedCanister"
label="Feed Canister Id"
>
<Input />
<Input/>
</Form.Item>

<Form.Item
name="biography"
label="Biography"
rules={[{ required: true, message: 'Please input Intro' }]}
rules={[{required: true, message: 'Please input Intro'}]}
>
<Input.TextArea showCount maxLength={160} />
<Input.TextArea showCount maxLength={160}/>
</Form.Item>
<Form.Item {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">
Expand Down
29 changes: 18 additions & 11 deletions frontend/src/components/post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ import {
import {PostImmutable} from "../declarations/feed/feed";
import {useAuth} from "../utils/useAuth";
import Feed from "../actors/feed";
import React, {useState} from "react";
import React, {useEffect, useState} from "react";
import {CommentForm} from "./Modal/commentForm";

export default function Post(props: { content: PostImmutable, setPostItem?: Function, avatar?: string, name?: string}) {
export default function Post(props: { content: PostImmutable, setPostItem?: Function, avatar?: string, name?: string }) {
const {content, setPostItem} = props
const {userFeedCai} = useAuth()
const [open, setOpen] = useState(false)
const [data, setData] = useState<any>()

useEffect(() => {
setData(content)
}, [content])

const feedApi = React.useMemo(() => {
if (!userFeedCai) return undefined
Expand All @@ -24,18 +29,20 @@ export default function Post(props: { content: PostImmutable, setPostItem?: Func

const update = async () => {
if (!feedApi) return tip()
await feedApi.getAllPost()
const newPost = await feedApi.getPost(data.postId)
if (!newPost[0]) return
setData(newPost[0])
}

const repost = async () => {
if (!feedApi) return tip()
await feedApi.createRepost(content.postId)
await feedApi.createRepost(data.postId)
update().then()
}

const like = async () => {
if (!feedApi) return tip()
await feedApi.createLike(content.postId)
await feedApi.createLike(data.postId)
update().then()
}

Expand All @@ -48,7 +55,7 @@ export default function Post(props: { content: PostImmutable, setPostItem?: Func
}}>
<div style={{
cursor: "pointer"
}} onClick={() => setPostItem?.(content)}>
}} onClick={() => setPostItem?.(data)}>
<Space>
<Avatar
size={32}
Expand All @@ -62,7 +69,7 @@ export default function Post(props: { content: PostImmutable, setPostItem?: Func
<Typography.Paragraph style={{
paddingLeft: '12px'
}}>
{content.content}
{data?.content}
</Typography.Paragraph>
</div>
<Space
Expand All @@ -77,23 +84,23 @@ export default function Post(props: { content: PostImmutable, setPostItem?: Func
footer={null}
onCancel={() => setOpen(false)}
>
<CommentForm postId={content.postId} setOpen={setOpen}/>
<CommentForm postId={data?.postId} setOpen={setOpen}/>
</Modal>
<div style={{cursor: "pointer"}} onClick={() => {
if (!feedApi) return tip()
setOpen(true)
}}>
<CommentOutlined/> &nbsp;
{content.comment.length}
{data?.comment.length}
</div>
<div style={{cursor: "pointer"}} onClick={repost}>
<RedoOutlined/>
&nbsp;
{content.repost.length}
{data?.repost.length}
</div>
<div style={{cursor: "pointer"}} onClick={like}>
<HeartOutlined/>&nbsp;
{content.like.length}
{data?.like.length}
</div>
</Space>
</div>
Expand Down
25 changes: 5 additions & 20 deletions frontend/src/components/sider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {useAuth} from "../utils/useAuth";
import React, {useEffect, useState} from "react";
import {PostForm} from "./Modal/postForm";
import {Profile} from "../declarations/user/user";
import { userApi } from "../actors/user";
import {userApi} from "../actors/user";
import {useProfileStore} from "../redux";

function getItem(
label: React.ReactNode,
Expand Down Expand Up @@ -52,22 +53,7 @@ export default function Sider() {
const navigate = useNavigate();
const {isAuth, logIn, principal} = useAuth();
const [open, setOpen] = useState(false)
const [profile, setProfile] = useState<Profile>();

useEffect(() => {
const initUserProfile = async () => {
if(principal?._isPrincipal === true) {
const _profile = await userApi.getProfile(principal);
console.log('side bar init profile : ', _profile);
if(_profile.length > 0) {
setProfile(_profile[0]);
};
};
};

initUserProfile();

}, [principal]);
const profile = useProfileStore()

const onClick = (info: MenuInfo) => {
if (info.key === '1') {
Expand Down Expand Up @@ -132,7 +118,7 @@ export default function Sider() {
<Card.Meta
avatar={<Avatar
size={{xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100}}
src={ profile?.avatarUrl ? profile.avatarUrl : "https://avatars.githubusercontent.com/u/120618331?s=200&v=4" }
src={profile?.avatarUrl ? profile.avatarUrl : "https://avatars.githubusercontent.com/u/120618331?s=200&v=4"}
style={{
border: '1px solid #D3D540',
}}
Expand All @@ -143,10 +129,9 @@ export default function Sider() {
description={
<Typography.Text
copyable={true}
// style={{width: '100px'}}
ellipsis
>
{principal?.toString()}
{principal?.toString()}
</Typography.Text>
}
/>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/redux/features/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./AllData"
export * from "./profile"
25 changes: 25 additions & 0 deletions frontend/src/redux/features/profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {createSlice} from "@reduxjs/toolkit"
import {RootState} from "../store"
import {useAppSelector} from "../hook"
import {Profile} from "../../declarations/user/user"


const initialState = {}
export const profileSlice = createSlice({
name: "profile",
initialState,
reducers: {
update: (state, action: { type: string, payload: Profile }) => {
return action.payload
},
},
})

const {update} = profileSlice.actions
const profile = (state: RootState) => state.profile
export const updateProfile = async (result: Profile) => {
const store = await (await import("../store")).default
store.dispatch(update(result))
}
export const useProfileStore = (): Profile => useAppSelector(profile)
export default profileSlice.reducer
3 changes: 2 additions & 1 deletion frontend/src/redux/store.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {configureStore} from "@reduxjs/toolkit";
import allData from "./features/AllData"
import profile from "./features/profile"


const store = configureStore({
reducer: {
allData
allData,profile
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
Expand Down
Loading

0 comments on commit d2338ff

Please sign in to comment.