Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 62 additions & 41 deletions client/src/modules/edit-profile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,53 @@ const EditProfile = () => {
const [charactersLeft, setCharactersLeft] = useState(bioLimit);
const [updatedProfileImg, setUpdatedProfileImg] = useState<File | null>(null);
const [previewImg, setPreviewImg] = useState<string | null>(null);

// Form state
const [formData, setFormData] = useState({
username: '',
bio: '',
youtube: '',
facebook: '',
twitter: '',
github: '',
instagram: '',
website: '',
});

useEffect(() => {
if (isAuthenticated()) {
fetchProfile().finally(() => setLoading(false));
}
}, [isAuthenticated, fetchProfile]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (profile?.personal_info?.bio) {
setCharactersLeft(bioLimit - profile.personal_info.bio.length);
if (profile) {
setFormData({
username: profile.personal_info.username || '',
bio: profile.personal_info.bio || '',
youtube: profile.social_links.youtube || '',
facebook: profile.social_links.facebook || '',
twitter: profile.social_links.x || '',
github: profile.social_links.github || '',
instagram: profile.social_links.instagram || '',
website: profile.social_links.website || '',
});
if (profile.personal_info?.bio) {
setCharactersLeft(bioLimit - profile.personal_info.bio.length);
}
}
}, [profile]);

const handleCharacterChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setCharactersLeft(bioLimit - e.currentTarget.value.length);
const value = e.currentTarget.value;
setFormData(prev => ({ ...prev, bio: value }));
setCharactersLeft(bioLimit - value.length);
};

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.currentTarget;
setFormData(prev => ({ ...prev, [name]: value }));
};

const handleImagePreview = (e: React.ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -93,33 +125,16 @@ const EditProfile = () => {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (!editProfileForm.current) return;
const form = new FormData(editProfileForm.current);
const formData: { [key: string]: FormDataEntryValue } = {};
const { username, bio, youtube, facebook, twitter, github, instagram, website } = formData;

for (const [key, value] of form.entries()) {
formData[key] = value;
}

const {
username,
bio,
youtube,
facebook,
twitter,
github,
instagram,
website,
} = formData;

if (typeof username !== 'string' || username.length < 3) {
if (username.length < 3) {
return addNotification({
message: 'Username should be atleast 3 characters long',
type: 'error',
});
}

if (typeof bio === 'string' && bio.length > bioLimit) {
if (bio.length > bioLimit) {
return addNotification({
message: `Bio should be less than ${bioLimit} characters`,
type: 'error',
Expand All @@ -131,15 +146,15 @@ const EditProfile = () => {
try {
await updateUserProfile({
username,
bio: (bio as string) || '',
bio: bio || '',
social_links: {
youtube: (youtube as string) || '',
facebook: (facebook as string) || '',
x: (twitter as string) || '',
github: (github as string) || '',
instagram: (instagram as string) || '',
linkedin: '',
website: (website as string) || '',
youtube: youtube || '',
facebook: facebook || '',
x: twitter || '',
github: github || '',
instagram: instagram || '',
linkedin: profile?.social_links.linkedin || '',
website: website || '',
},
});
addNotification({
Expand Down Expand Up @@ -278,9 +293,14 @@ const EditProfile = () => {
id="edit-profile-username"
type="text"
name="username"
defaultValue={username}
value={formData.username}
placeholder="Username"
icon={<AlternateEmailIcon />}
slotProps={{
htmlInput: {
onChange: handleInputChange,
},
}}
/>
<Typography
variant="caption"
Expand All @@ -297,7 +317,7 @@ const EditProfile = () => {
name="bio"
multiline
rows={4}
defaultValue={bio}
value={formData.bio}
placeholder="Bio"
fullWidth
inputProps={{ maxLength: bioLimit }}
Expand Down Expand Up @@ -328,24 +348,25 @@ const EditProfile = () => {
gap: 2,
}}
>
{(
Object.keys(social_links) as Array<
keyof typeof social_links
>
).map(key => {
const link = social_links[key] || '';
{['youtube', 'facebook', 'twitter', 'github', 'instagram', 'website'].map(key => {
const fieldName = key as keyof typeof formData;
return (
<InputBox
key={key}
id={`edit-profile-${key}`}
name={key}
type="text"
defaultValue={link}
value={formData[fieldName]}
placeholder="https://"
icon={socialIcons[key] || <LanguageIcon />}
sx={{
flex: { xs: '1 1 100%', sm: '1 1 calc(50% - 8px)' },
}}
slotProps={{
htmlInput: {
onChange: handleInputChange,
},
}}
/>
);
})}
Expand Down
55 changes: 34 additions & 21 deletions client/src/modules/manage-projects/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,36 +36,49 @@ const useManageProjects = () => {
]);

if (projectsResponse.data && countResponse.data) {
const currentState = is_draft ? draftProjects : publishedProjects;
const existingResults = currentState?.results || [];

const formattedData: ManageProjectsPaginationState = {
results:
page === 1
? projectsResponse.data
: [...existingResults, ...projectsResponse.data],
page,
totalDocs: countResponse.data.totalDocs || 0,
deletedDocCount,
};
const totalDocs = countResponse.data.totalDocs || 0;

if (is_draft) {
setDraftProjects(formattedData);
setDraftProjects((prevState: ManageProjectsPaginationState | undefined) => {
const previousResults = prevState?.results || [];

const results =
page === 1 || !prevState
? projectsResponse.data
: [...previousResults, ...projectsResponse.data];

return {
results,
page,
totalDocs,
deletedDocCount,
};
});
} else {
setPublishedProjects(formattedData);
setPublishedProjects(
(prevState: ManageProjectsPaginationState | undefined) => {
const previousResults = prevState?.results || [];

const results =
page === 1 || !prevState
? projectsResponse.data
: [...previousResults, ...projectsResponse.data];

return {
results,
page,
totalDocs,
deletedDocCount,
};
}
);
}
}
} catch (error) {
console.error('Error fetching projects:', error);
}
},
[
isAuthenticated,
setPublishedProjects,
setDraftProjects,
publishedProjects,
draftProjects,
]
[isAuthenticated, setPublishedProjects, setDraftProjects]
);

return {
Expand Down
6 changes: 4 additions & 2 deletions client/src/modules/manage-projects/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ const ManageProjects = () => {
if (draftProjects === null) {
fetchProjects({ page: 1, is_draft: true, query });
}
}, [publishedProjects, draftProjects, fetchProjects, query]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [publishedProjects, draftProjects, query]);

const handleSearch = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter' && query.length) {
const value = e.currentTarget.value;
if (e.key === 'Enter' && value.length) {
setPublishedProjects(null);
setDraftProjects(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const NotificationCard = ({
borderLeftColor: `${getNotificationColor()}.main`,
position: 'relative',
'&:hover': {
elevation: 4,
boxShadow: theme => theme.shadows[4],
transform: 'scale(1.01)',
transition: 'all 0.2s ease-in-out',
},
Expand Down Expand Up @@ -318,8 +318,7 @@ const NotificationCard = ({
<Collapse in={isReplying} timeout="auto" unmountOnExit>
<Box sx={{ p: 2, bgcolor: 'grey.50' }}>
<NotificationCommentField
_id={project_id}
project_author={{ _id: userAuth?.personal_info?.username || '' }}
project_id={project_id}
replyingTo={comment_id?._id}
setReplying={setIsReplying}
notification_id={notification_id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@ import { TextField, Button, Box, Typography } from '@mui/material';
import { Reply } from '@mui/icons-material';

interface NotificationCommentFieldProps {
_id: string;
project_author: {
_id: string;
};
project_id: string;
replyingTo?: string;
setReplying: (value: boolean) => void;
notification_id: string;
}

const NotificationCommentField = ({
_id,
project_author,
project_id,
replyingTo,
setReplying,
notification_id,
Expand All @@ -27,8 +23,6 @@ const NotificationCommentField = ({
const user = useAtomValue(UserAtom);
const { isAuthenticated } = useAuth();

const { _id: user_id } = project_author;

const handleComment = () => {
if (!comment.length) {
console.error('Write something to leave a comment...');
Expand All @@ -42,11 +36,10 @@ const NotificationCommentField = ({

axios
.post(
import.meta.env.VITE_SERVER_DOMAIN + '/api/notification/comment',
import.meta.env.VITE_SERVER_DOMAIN + '/api/comment',
{
_id,
project_id,
comment,
project_author: user_id,
replying_to: replyingTo,
notification_id,
},
Expand Down
31 changes: 16 additions & 15 deletions client/src/modules/notification/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,27 @@ const useNotifications = () => {
]);

if (notificationsResponse.data && countResponse.data) {
const currentState = notifications;
const existingResults = currentState?.results || [];

const formattedData: NotificationPaginationState = {
results:
page === 1
? notificationsResponse.data
: [...existingResults, ...notificationsResponse.data],
page,
totalDocs: countResponse.data.totalDocs || 0,
deleteDocCount: deletedDocCount,
};

setNotifications(formattedData);
setNotifications((currentState) => {
const existingResults = currentState?.results || [];

const formattedData: NotificationPaginationState = {
results:
page === 1
? notificationsResponse.data
: [...existingResults, ...notificationsResponse.data],
page,
totalDocs: countResponse.data.totalDocs || 0,
deleteDocCount: deletedDocCount,
};

return formattedData;
});
}
} catch (error) {
console.error('Error fetching notifications:', error);
}
},
[isAuthenticated, setNotifications, notifications]
[isAuthenticated, setNotifications]
);

return {
Expand Down
3 changes: 2 additions & 1 deletion client/src/modules/notification/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ const Notifications = () => {
setNotifications(null);
fetchNotifications({ page: 1, filter, deletedDocCount: 0 });
}
}, [isAuthenticated, filter, fetchNotifications, setNotifications]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filter]);

const handleFilter = (filterName: string) => {
setFilter(filterName as NOTIFICATION_FILTER_TYPE);
Expand Down