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

#625 add icon on the banner logo if profile is in'pending moderation'status #773

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c1d6580
added moderation-icon.png
ohorodnykostap Aug 7, 2024
e9bc7fb
Merge branch 'develop' of github.com:ita-social-projects/Forum into #…
ohorodnykostap Aug 7, 2024
97fdbd7
added the status field to the ProfileOwnerDetailViewSerializer
ohorodnykostap Aug 13, 2024
d7fdd75
added the status_updated_at field to the ProfileOwnerDetailViewSerial…
ohorodnykostap Aug 14, 2024
fc69a3e
created the PendingStatus function and styles it to display the toolt…
ohorodnykostap Aug 29, 2024
9cddec5
used the PendingStatus function to display the tooltip in the banner …
ohorodnykostap Aug 30, 2024
2688693
added styles for positioning the tooltip on the banner and logo accor…
ohorodnykostap Aug 30, 2024
f64fe73
used the PendingStatus function to display a tooltip while editing a …
ohorodnykostap Aug 30, 2024
f2a5d39
Merge branch 'develop' of github.com:ita-social-projects/Forum into #…
ohorodnykostap Aug 30, 2024
d27c021
added an empty line at the end of the code
ohorodnykostap Sep 4, 2024
86c2238
pulled the changes from the develop branch
ohorodnykostap Sep 4, 2024
436b7be
added elementType for the banner and logo and checking whether there …
ohorodnykostap Sep 6, 2024
a1a47f6
added elementType for PendingStatus function
ohorodnykostap Sep 6, 2024
4f14c53
added banner_approved_id and logo_approved_id fields
ohorodnykostap Sep 6, 2024
183555f
changed the logic for shouldShowTooltip
ohorodnykostap Sep 6, 2024
50bba46
created the ProfileImageFieldApprovedStatus class
ohorodnykostap Sep 9, 2024
d24ab70
used ProfileImageFieldApprovedStatus to track the banner and logo mod…
ohorodnykostap Sep 9, 2024
c247e9c
Merge branch 'develop' of github.com:ita-social-projects/Forum into #…
ohorodnykostap Sep 9, 2024
731d0b6
removed unused fields
ohorodnykostap Sep 10, 2024
1e22608
Merge branch 'develop' of github.com:ita-social-projects/Forum into #…
ohorodnykostap Sep 10, 2024
b1c16f5
removed unnecessary line
ohorodnykostap Sep 10, 2024
f8493e6
renamed PendingStatus.css
ohorodnykostap Sep 10, 2024
045ef74
optimized the code in PendingStatus.jsx
ohorodnykostap Sep 10, 2024
ac7ac0e
added profile={mainProfile} to the banner and logo field
ohorodnykostap Sep 10, 2024
1e465d7
optimized the code to call tooltip
ohorodnykostap Sep 10, 2024
1a6c3a6
code formatting in the ImageField.jsx file
ohorodnykostap Sep 11, 2024
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
20 changes: 18 additions & 2 deletions BackEnd/profiles/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ def to_internal_value(self, data):
return ProfileImage.objects.filter(uuid=data, is_deleted=False).first()


class ProfileImageFieldApprovedStatus(ProfileImageField):
def to_representation(self, value):
if not value.is_deleted:
return {
"uuid": value.uuid,
"path": self.context["request"].build_absolute_uri(
value.image_path.url
),
"is_approved": value.is_approved,
}


class ProfileListSerializer(serializers.ModelSerializer):
activities = ActivitySerializer(many=True, read_only=True)
categories = CategorySerializer(many=True, read_only=True)
Expand Down Expand Up @@ -200,8 +212,8 @@ class ProfileOwnerDetailViewSerializer(serializers.ModelSerializer):
email = serializers.ReadOnlyField(source="person.email")
regions = RegionSerializer(many=True, read_only=True)
regions_ukr_display = serializers.SerializerMethodField()
banner = ProfileImageField()
logo = ProfileImageField()
banner = ProfileImageFieldApprovedStatus()
logo = ProfileImageFieldApprovedStatus()

class Meta:
model = Profile
Expand Down Expand Up @@ -231,6 +243,8 @@ class Meta:
"banner",
"logo",
"is_deleted",
"status",
"status_updated_at",
)
read_only_fields = (
"id",
Expand Down Expand Up @@ -258,6 +272,8 @@ class Meta:
"banner",
"logo",
"is_deleted",
"status",
"status_updated_at",
)

def get_regions_ukr_display(self, obj) -> str:
Expand Down
Binary file added FrontEnd/public/img/moderation-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Tooltip } from 'antd';
import styles from './PendingStatus.module.css';

const PendingStatus = ({ profile, elementType }) => {

const bannerApproved = profile?.banner.is_approved;
const logoApproved = profile?.logo.is_approved;

const shouldShowTooltip = (elementType === 'banner' && bannerApproved === false)
|| (elementType === 'logo' && logoApproved === false);

const formattedDate = new Date(profile?.status_updated_at).toLocaleString('uk-UA', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
});

const tooltipText = `Статус модерації: Очікується. Час відправки запиту: ${formattedDate}`;

return (
(profile?.status === 'pending' && shouldShowTooltip) ? (
<div className={styles['tooltip-container']}>
<Tooltip
title={tooltipText}
placement="bottomLeft"
overlayStyle={{ marginLeft: '10px' }}
>
<img
src={`${process.env.REACT_APP_PUBLIC_URL}/img/moderation-icon.png`}
alt="Pending status icon"
/>
</Tooltip>
</div>
) : null
);
};

export default PendingStatus;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.tooltip-container{
display: flex;
position:absolute;
padding-top: 5px;
padding-left: 3px;
}

9 changes: 8 additions & 1 deletion FrontEnd/src/components/ProfileDetail/ProfileDetailPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import DetailedInfoSection from './DetailedInfo/DetailedInfoSection';
import BannerImage from './BannerImage';
import { ActiveLinksContext } from '../../context/ActiveLinksContext';
import classes from './ProfileDetailPage.module.css';
import PendingStatus from '../MiniComponents/PendingModerationIcon/PendingStatus';

function ProfileDetailPage({ isAuthorized }) {
const [activeLinks, setActiveLinks] = useState([]);
Expand All @@ -31,21 +32,27 @@ function ProfileDetailPage({ isAuthorized }) {
const notRequiredData = ['address', 'banner', 'logo', 'common_info', 'edrpou', 'rnokpp', 'founded', 'official_name', 'product_info', 'service_info', 'startup_idea', 'logistics', 'cooperation'];
const containsNotRequiredData = fetchedProfile ? Object.keys(fetchedProfile).some(key => notRequiredData.includes(key) && fetchedProfile[key] !== '' && fetchedProfile[key] !== null) : false;

return (error && error.response.status !== 401) ? (
return (error && error.status !== 401) ? (
<ErrorPage404 />
) : (
<div className={isLoading ? classes['loader-content'] : null}>
{isLoading ? (
<Loader />
) : (
<ActiveLinksContext.Provider value={{ activeLinks, setActiveLinks }}>
<div className={classes['banner-tooltip']}>
<PendingStatus profile={fetchedProfile} elementType="banner" />
</div>
<BannerImage data={fetchedProfile} />
<div className={classes['profile-page']}>
<MainInfoSection
containsNotRequiredData={containsNotRequiredData}
isAuthorized={isAuthorized}
data={fetchedProfile}
/>
<div className={classes['logo-tooltip']}>
<PendingStatus profile={fetchedProfile} elementType="logo" />
</div>
<DetailedInfoSection
containsNotRequiredData={containsNotRequiredData}
isAuthorized={isAuthorized}
Expand Down
14 changes: 14 additions & 0 deletions FrontEnd/src/components/ProfileDetail/ProfileDetailPage.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,17 @@
margin-left: 104px;
margin-right: 104px;
}

.logo-tooltip{
display: flex;
position:absolute;
padding-top: 5px;
padding-left: 3px;
}

.banner-tooltip{
display: flex;
position:absolute;
padding-top: 12px;
padding-left: 112px;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import classNames from 'classnames';
import preventEnterSubmit from '../../../../utils/preventEnterSubmit';
import css from './ImageField.module.css';
import PendingStatus from '../../../MiniComponents/PendingModerationIcon/PendingStatus';

const ImageField = ({
name,
Expand All @@ -10,8 +11,10 @@ const ImageField = ({
value,
updateHandler,
onDeleteImage,
profile,
error,
}) => {

const backgroundImage = {
background: `url(${value}) lightgray 50% / cover no-repeat`,
};
Expand Down Expand Up @@ -56,11 +59,18 @@ const ImageField = ({
);

return (
<div className={classNames(css['fields__column'], {
[css['fields__column--logo']]: name === 'logo',
})}>
<div
className={classNames(css['fields__column'], {
[css['fields__column--logo']]: name === 'logo',
})}
>
<div className={css['fields__label']}>
<label className={classNames(css['fields__label--text'], css['fields__field--notrequired'])}>
<label
className={classNames(
css['fields__label--text'],
css['fields__field--notrequired']
)}
>
{label}
</label>
{name === 'banner' && value && (
Expand All @@ -84,28 +94,37 @@ const ImageField = ({
<span className={css['upload-file__banner-image--title']}>
Зображення для банера на сторінці профайлу
</span>
<div
className={css['upload-file__banner-image--page']}
style={backgroundImage}
/>
<div className={css['tooltip-container']}>
<PendingStatus profile={profile} elementType="banner" />
<div
className={css['upload-file__banner-image--page']}
style={backgroundImage}
/>
</div>
</div>
<div className={css['upload-file__wrapper--banner-card']}>
<span className={css['upload-file__banner-image--title']}>
Зображення для карток
</span>
<div
className={css['upload-file__banner-image--card']}
style={backgroundImage}
/>
<div>
<PendingStatus profile={profile} elementType="banner" />
<div
className={css['upload-file__banner-image--card']}
style={backgroundImage}
/>
</div>
</div>
</>
)}
{name === 'logo' && value && (
<div className={css['upload-file__wrapper--logo']}>
<div className={css['upload-file__logo']} style={backgroundImage} />
{renderInput()}
{renderUpdateImageLabel('змінити')}
{renderDeleteButton('видалити')}
<div>
<PendingStatus profile={profile} elementType="logo" />
<div className={css['upload-file__wrapper--logo']}>
<div className={css['upload-file__logo']} style={backgroundImage} />
{renderInput()}
{renderUpdateImageLabel('змінити')}
{renderDeleteButton('видалити')}
</div>
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,4 @@ button {

.fields__field--notrequired {
padding-top: 2px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ const GeneralInfo = (props) => {
value={bannerImage}
error={bannerImageError}
onDeleteImage={deleteImageHandler}
profile={mainProfile}
/>
<ImageField
accept="image/png, image/jpeg"
Expand All @@ -535,6 +536,7 @@ const GeneralInfo = (props) => {
value={logoImage}
error={logoImageError}
onDeleteImage={deleteImageHandler}
profile={mainProfile}
/>
<BanerModeration />
<TextField
Expand Down
Loading