-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
489 additions
and
340 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { Box } from '@mui/material'; | ||
import useAxios from 'axios-hooks'; | ||
import { deserialize, DocumentObject } from 'jsonapi-fractal'; | ||
import { useEffect, useState } from 'react'; | ||
import ThumbsUp from '@/assets/icons/thumbs-up.svg'; | ||
import useLangContext from '@/hooks/useLangContext'; | ||
import Loader from '@/themed/loader/Loader'; | ||
import Text from '@/themed/text/Text'; | ||
import { formatDateFromString } from '@/util'; | ||
|
||
interface CommentBoxProps { | ||
postId: number; | ||
} | ||
|
||
interface IComment { | ||
content: string; | ||
createdAt: string; | ||
id: number; | ||
likesCount: number; | ||
photos?: string; | ||
postId: number; | ||
updatedAt: string; | ||
canDeleteByUser: boolean; | ||
canEditByUser: boolean; | ||
createdBy: ICommentUser; | ||
} | ||
|
||
interface ICommentUser { | ||
accountId: number; | ||
lastName: string; | ||
userName: string; | ||
} | ||
|
||
const CommentBox = ({ postId }: CommentBoxProps) => { | ||
const [{ data, loading, error }] = useAxios({ | ||
url: `/posts/${postId}`, | ||
}); | ||
const [comments, setComments] = useState<DocumentObject[]>([]); | ||
const langContext = useLangContext(); | ||
|
||
useEffect(() => { | ||
if (!data) return; | ||
const deserializedData = deserialize<{ comments: DocumentObject[] }>(data) as { comments: DocumentObject[] }[]; | ||
const first = deserializedData.shift(); | ||
if (first) setComments(first.comments); | ||
}, [data]); | ||
|
||
return ( | ||
<> | ||
{loading && <Loader height="15vh" />} | ||
{!loading && | ||
comments.map((commentData) => { | ||
const comment = deserialize<IComment>(commentData) as IComment; | ||
const acronym = `${comment.createdBy.userName[0]}${comment.createdBy.lastName[0]}`; | ||
|
||
return ( | ||
<Box> | ||
<Box className="flex items-center gap-4 mt-6"> | ||
<Box className="min-w-20 min-h-20 -tracking-4 bg-green-100 rounded-full flex items-center justify-center"> | ||
<Text className="mb-0 text-green-800 font-bold -tracking-4 uppercase">{acronym}</Text> | ||
</Box> | ||
<Box> | ||
<Box className="flex gap-2"> | ||
<Text className="mb-0 font-semibold"> | ||
{comment.createdBy.userName} {comment.createdBy.lastName} | ||
</Text> | ||
<Text className="mb-0 opacity-60 max-w-max"> | ||
{formatDateFromString(langContext.state.selected, comment.createdAt)} | ||
</Text> | ||
</Box> | ||
<Text className="mb-0">{comment.content}</Text> | ||
<Box className="flex gap-2 rounded-md items-center"> | ||
<img className="self-center" src={ThumbsUp} alt="success" /> | ||
<Text className="mb-0 font-medium opacity-60">{comment.likesCount}</Text> | ||
</Box> | ||
</Box> | ||
</Box> | ||
{error && <p>Something wrong happened</p>} | ||
</Box> | ||
); | ||
})} | ||
</> | ||
); | ||
}; | ||
|
||
export default CommentBox; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { Box } from '@mui/material'; | ||
import { useState } from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import Comment from '@/assets/icons/comment.svg'; | ||
import ThumbsUp from '@/assets/icons/thumbs-up.svg'; | ||
import Trash from '@/assets/icons/trash.svg'; | ||
import Text from '@/themed/text/Text'; | ||
import CommentBox from './CommentBox'; | ||
|
||
interface PostProps { | ||
id: number; | ||
author: string; | ||
date: number; | ||
location: string; | ||
text: string; | ||
image?: { photo_url: string }; | ||
likes: number; | ||
comments?: number; | ||
acronym: string; | ||
} | ||
|
||
const PostBox = ({ author, date, location, text, likes, image, id, comments, acronym }: PostProps) => { | ||
const { t } = useTranslation('feed'); | ||
const [imageLoaded, setImageLoaded] = useState(false); | ||
const [openComments, setOpenComments] = useState(false); | ||
|
||
return ( | ||
<Box key={id} className="flex-col border-solid border-neutral-100 rounded-md p-8 flex justify-between mb-4"> | ||
<Box className="flex items-center gap-4 mb-6"> | ||
<Box className="w-20 h-20 -tracking-4 bg-green-100 rounded-full flex items-center justify-center"> | ||
<Text className="mb-0 text-green-800 font-bold -tracking-4 uppercase">{acronym}</Text> | ||
</Box> | ||
<Box> | ||
<Text className="mb-0 font-semibold">{author}</Text> | ||
<Text className="mb-0 opacity-60"> | ||
{date} • {location} | ||
</Text> | ||
</Box> | ||
</Box> | ||
<Text className={`mb-0 ${image?.photo_url && 'mb-4'}`}>{text}</Text> | ||
<Box className="rounded-lg mb-4 overflow-hidden"> | ||
{image?.photo_url && !imageLoaded && ( | ||
<div role="status" className="animate-pulse w-full"> | ||
<div className="h-96 w-full bg-lightGray opacity-50 rounded-lg" /> | ||
</div> | ||
)} | ||
{image?.photo_url && ( | ||
<img | ||
src={image?.photo_url} | ||
className="w-full object-cover" | ||
alt="posted" | ||
onLoad={() => setImageLoaded(true)} | ||
/> | ||
)} | ||
</Box> | ||
<Box className="flex justify-between gap-4"> | ||
<Box className="flex gap-6"> | ||
<Box className="flex gap-2 px-2 py-1 rounded-md items-center cursor-default"> | ||
<img className="self-center" src={ThumbsUp} alt="success" /> | ||
<Text className="mb-0 font-medium opacity-60">{likes}</Text> | ||
</Box> | ||
<Box | ||
onClick={() => { | ||
if (!comments) return; | ||
setOpenComments((prev) => !prev); | ||
}} | ||
className={`flex gap-2 px-2 py-1 rounded-md items-center ${comments ? 'cursor-pointer hover:bg-neutral-100' : 'cursor-default'}`} | ||
> | ||
<img className="self-center" src={Comment} alt="success" /> | ||
<Text className="mb-0 font-medium opacity-60"> | ||
{comments} {t('post.comment')} | ||
</Text> | ||
</Box> | ||
</Box> | ||
<Box className="flex gap-2 px-2 py-1 rounded-md items-center cursor-default"> | ||
<img className="self-center" src={Trash} alt="success" /> | ||
<Text className="mb-0 font-medium opacity-60">{t('post.delete')}</Text> | ||
</Box> | ||
</Box> | ||
{openComments && <CommentBox postId={id} />} | ||
</Box> | ||
); | ||
}; | ||
|
||
export default PostBox; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { Box } from '@mui/material'; | ||
import useAxios from 'axios-hooks'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { ErrorResponse } from 'react-router-dom'; | ||
import useUser from '@/hooks/useUser'; | ||
import { BaseObject } from '@/schemas'; | ||
import Loader from '@/themed/loader/Loader'; | ||
import { ProgressBar } from '@/themed/progress-bar/ProgressBar'; | ||
import Title from '@/themed/title/Title'; | ||
|
||
interface HouseReport { | ||
greenQuantity: number; | ||
houseQuantity: number; | ||
orangeQuantity: number; | ||
redQuantity: number; | ||
siteVariationPercentage: number; | ||
visitQuantity: number; | ||
visitVariationPercentage: number; | ||
} | ||
|
||
const RiskChart = () => { | ||
const { t } = useTranslation('feed'); | ||
const user = useUser(); | ||
|
||
const [{ data, loading }] = useAxios<HouseReport, null, ErrorResponse>({ | ||
url: `reports/house_status`, | ||
}); | ||
|
||
const label = `${(user?.team as BaseObject)?.name}: ${t('riskChart.title')}`; | ||
|
||
return ( | ||
<Box className="border-solid border-neutral-100 rounded-md p-6 mb-4"> | ||
<Title label={label} type="subsection" className="mb-0" /> | ||
<Box className="flex flex-col mt-6"> | ||
{loading && <Loader />} | ||
{!loading && ( | ||
<> | ||
<ProgressBar label={t('riskChart.greenSites')} progress={data?.greenQuantity || 0} color="green-600" /> | ||
<ProgressBar label={t('riskChart.yellowSites')} progress={data?.orangeQuantity || 0} color="yellow-600" /> | ||
<ProgressBar label={t('riskChart.redSites')} progress={data?.redQuantity || 0} color="red-600" /> | ||
</> | ||
)} | ||
</Box> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default RiskChart; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Box } from '@mui/material'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { ProgressBar } from '@/themed/progress-bar/ProgressBar'; | ||
import Title from '@/themed/title/Title'; | ||
|
||
const SitesReport = () => { | ||
const { t } = useTranslation('feed'); | ||
|
||
return ( | ||
<Box className="border-solid border-neutral-100 rounded-md p-6 mb-4"> | ||
<Title label={t('sitesReport.title')} type="subsection" className="mb-0" /> | ||
<Box className="flex flex-col mt-6"> | ||
<> | ||
<ProgressBar label={t('sitesReport.title')} progress={60} color="green-600" /> | ||
<ProgressBar label={t('sitesReport.quantity')} progress={80} color="green-800" /> | ||
</> | ||
</Box> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default SitesReport; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { Box, Tab, Tabs } from '@mui/material'; | ||
import useAxios from 'axios-hooks'; | ||
import { useState } from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import Text from '@/themed/text/Text'; | ||
import Loader from '@/themed/loader/Loader'; | ||
|
||
function a11yProps(index: number) { | ||
return { | ||
id: `simple-tab-${index}`, | ||
'aria-controls': `simple-tabpanel-${index}`, | ||
}; | ||
} | ||
|
||
enum RankView { | ||
VisitRank = 'visitRank', | ||
GreenHouseRank = 'greenHouseRank', | ||
} | ||
|
||
interface Rank { | ||
first_name: string; | ||
last_name: string; | ||
quantity: number; | ||
} | ||
|
||
interface BrigadistPerformance { | ||
visitRank: Rank[]; | ||
greenHouseRank: Rank[]; | ||
} | ||
|
||
const RankViewBox = () => { | ||
const { t } = useTranslation('feed'); | ||
const [rankView, setRankView] = useState(RankView.VisitRank); | ||
|
||
const handleChange = (_: React.SyntheticEvent, newValue: number) => { | ||
setRankView(Object.values(RankView)[newValue] as RankView); | ||
}; | ||
|
||
const [{ data, loading, error }] = useAxios<BrigadistPerformance>({ | ||
url: `/reports/brigadists_performance`, | ||
}); | ||
|
||
const value = Object.values(RankView).indexOf(rankView); | ||
|
||
return ( | ||
<Box className="border-solid border-neutral-100 rounded-md"> | ||
<Tabs value={value} onChange={handleChange} aria-label="basic tabs example"> | ||
<Tab label={t('rankView.users')} {...a11yProps(0)} className="w-1/2" /> | ||
<Tab label={t('rankView.greenHouses')} {...a11yProps(1)} className="w-1/2" /> | ||
</Tabs> | ||
<Box className="flex flex-col p-6"> | ||
{error && <p>Error</p>} | ||
{loading && <Loader />} | ||
{!loading && ( | ||
<> | ||
<Box className="flex justify-between mb-4"> | ||
<Text className="text-neutral-400 opacity-60">{t('rankView.ranking')}</Text> | ||
<Text className="text-neutral-400 opacity-60">{t('rankView.visits')}</Text> | ||
</Box> | ||
<Box> | ||
{data && | ||
data[rankView].map((item) => ( | ||
<Box className="flex justify-between mb-6" key={item.first_name + item.quantity}> | ||
<Box className="flex flex-row items-center gap-3"> | ||
<Box className="rounded-full h-10 w-10 bg-neutral-100" /> | ||
<Text className="font-semibold text-neutral-400 opacity-70 mb-0"> | ||
{item.first_name} {item.last_name} | ||
</Text> | ||
</Box> | ||
<Text className="font-semibold text-green-800 mb-0">{item.quantity}</Text> | ||
</Box> | ||
))} | ||
</Box> | ||
</> | ||
)} | ||
</Box> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default RankViewBox; |
7 changes: 6 additions & 1 deletion
7
src/i18n/locales/en/myCity.json → src/i18n/locales/en/feed.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 6 additions & 1 deletion
7
src/i18n/locales/es/myCity.json → src/i18n/locales/es/feed.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 6 additions & 1 deletion
7
src/i18n/locales/pt/myCity.json → src/i18n/locales/pt/feed.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.