-
Notifications
You must be signed in to change notification settings - Fork 41
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
1 parent
00b0f9e
commit 49d7c9f
Showing
8 changed files
with
175 additions
and
48 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
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 |
---|---|---|
@@ -1,10 +1,108 @@ | ||
import { Text } from "src/components/text"; | ||
import { useEffect } from "react"; | ||
import { Link } from "src/components/link"; | ||
import { Loading } from "src/components/loading"; | ||
import { Locale, useLocale } from "src/components/locale"; | ||
import { Markdown } from "src/components/markdown"; | ||
import { TryAgain } from "src/components/try-again"; | ||
import { fetchContributionsListAction } from "src/redux/actions/contributions"; | ||
import { useAppDispatch, useAppSelector } from "src/redux/store"; | ||
import { getElapsedTime } from "src/utils/elapsed-time"; | ||
|
||
// ts-prune-ignore-next | ||
export default function Page(): JSX.Element { | ||
const { localize } = useLocale(); | ||
const { contributionsList } = useAppSelector((state) => state.contributionsPage); | ||
const dispatch = useAppDispatch(); | ||
|
||
useEffect(() => { | ||
dispatch(fetchContributionsListAction()); | ||
}, [dispatch]); | ||
|
||
// @TODO-ZM: add filters and search | ||
return ( | ||
<main> | ||
<Text>Contribution Page</Text> | ||
<main className="flex flex-col self-center"> | ||
<h1 className="text-xl font-bold m-2 mt-8 self-center"> | ||
<Locale contribute-title /> | ||
</h1> | ||
|
||
<div className="flex flex-col self-center"> | ||
{contributionsList === "ERROR" ? ( | ||
<TryAgain | ||
error={localize("global-generic-error")} | ||
action={localize("global-try-again")} | ||
onClick={() => { | ||
dispatch(fetchContributionsListAction()); | ||
}} | ||
/> | ||
) : contributionsList === null ? ( | ||
<Loading /> | ||
) : ( | ||
<div className="flex flex-row flex-wrap gap-4 justify-between p-4"> | ||
{contributionsList.map((contribution, contributionIndex) => ( | ||
<div | ||
dir="ltr" | ||
className="card card-compact bg-base-300 w-96 flex-auto" | ||
key={contributionIndex} | ||
> | ||
<div className="card-body markdown"> | ||
<div className="card-body"> | ||
<h2 className="card-title"> | ||
<Markdown content={contribution.title} /> | ||
</h2> | ||
<span className="card-normal flex-1 ">{contribution.project.name}</span> | ||
<div className="flex flex-row flex-wrap gap-1"> | ||
{contribution.labels.map((label, labelIndex) => ( | ||
<span key={`label-${labelIndex}`} className="badge"> | ||
{label} | ||
</span> | ||
))} | ||
{contribution.languages.map((language, languageIndex) => ( | ||
<span key={`language-${languageIndex}`} className="badge"> | ||
{language} | ||
</span> | ||
))} | ||
</div> | ||
<div className="card-actions justify-end mt-4 gap-4"> | ||
<img | ||
className="w-6 h-6 rounded-full" | ||
src={contribution.createdBy.avatarUrl} | ||
/> | ||
<div className="flex-1" /> | ||
<div className="flex flex-row"> | ||
{getElapsedTime(contribution.updatedAt, localize("elapsed-time-suffixes"))} | ||
</div> | ||
{contribution.commentsCount > 0 && ( | ||
<div className="flex flex-row"> | ||
<svg | ||
xmlns="http://www.w3.org/2000/svg" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
strokeWidth={1.5} | ||
stroke="currentColor" | ||
className="size-6" | ||
> | ||
<path | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
d="M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155" | ||
/> | ||
</svg> | ||
<span className="">{contribution.commentsCount}</span> | ||
</div> | ||
)} | ||
<Link href={contribution.url} className="link"> | ||
{contribution.type === "issue" | ||
? localize("contribute-read-issue") | ||
: localize("contribute-review-changes")} | ||
</Link> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
))} | ||
</div> | ||
)} | ||
</div> | ||
</main> | ||
); | ||
} |
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
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,18 @@ | ||
import { Action, ThunkAction } from "@reduxjs/toolkit"; | ||
import { contributionsPageSlice } from "src/redux/slices/contributions-page"; | ||
import { AppState } from "src/redux/store"; | ||
import { fetchV2 } from "src/utils/fetch"; | ||
|
||
export const fetchContributionsListAction = | ||
(): ThunkAction<void, AppState, unknown, Action> => async (dispatch) => { | ||
try { | ||
dispatch(contributionsPageSlice.actions.set({ contributionsList: null })); | ||
const { contributions } = await fetchV2("api:Contributions", { query: [] }); | ||
|
||
dispatch(contributionsPageSlice.actions.set({ contributionsList: contributions })); | ||
} catch (error) { | ||
dispatch(contributionsPageSlice.actions.set({ contributionsList: "ERROR" })); | ||
// @TODO-ZM: Uncomment this line when sentry is added | ||
// Sentry.captureException(error, { tags: { type: "WEB_FETCH" } }); | ||
} | ||
}; |
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,20 @@ | ||
import { GetContributionsResponseDto } from "@dzcode.io/api/dist/contribution/types"; | ||
import { createSlice } from "@reduxjs/toolkit"; | ||
import { setReducerFactory } from "src/redux/utils"; | ||
import { LOADABLE } from "src/utils/loadable"; | ||
|
||
export interface ContributionsPageState { | ||
contributionsList: LOADABLE<GetContributionsResponseDto["contributions"]>; | ||
} | ||
|
||
const initialState: ContributionsPageState = { | ||
contributionsList: null, | ||
}; | ||
|
||
export const contributionsPageSlice = createSlice({ | ||
name: "contributions-page", | ||
initialState, | ||
reducers: { | ||
set: setReducerFactory(), | ||
}, | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// @TODO-ZM: move localization logic into the Dictionary files | ||
export const getElapsedTime = (time: string | number | Date, localizedSuffixes: string) => { | ||
const timePassed = new Date().getTime() - new Date(time).getTime(); | ||
const years = Math.floor(timePassed / 31536000000); | ||
const months = Math.floor((timePassed - years * 31536000000) / 2628000000); | ||
const days = Math.floor((timePassed - months * 2628000000) / 86400000); | ||
const hours = Math.floor((timePassed - days * 86400000) / 3600000); | ||
const minutes = Math.floor((timePassed - hours * 3600000) / 60000); | ||
const [year, month, day, hour, minute, now] = localizedSuffixes.split("|"); | ||
|
||
return `${ | ||
years > 0 | ||
? `${years}${year}` | ||
: `${ | ||
months > 0 | ||
? `${months}${month}` | ||
: `${ | ||
days > 0 | ||
? `${days}${day}` | ||
: `${ | ||
hours > 0 ? `${hours}${hour}` : `${minutes > 0 ? `${minutes}${minute}` : now}` | ||
}` | ||
}` | ||
}` | ||
}`; | ||
}; |