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

BEPRO 2.32 #510

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
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
8 changes: 7 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ NEXT_PUBLIC_PROPOSAL_REJECTED=
# Google Analytics Measurement ID
NEXT_PUBLIC_GA_MEASUREMENT_ID=

# Enable/Disable Elastic logs: true | false
NEXT_LOG_TO_ELASTIC=false

# API log level: 0 none, 1 error, 2 warn, 3 info, 4 trace, 5 log, 6 debug
LOG_LEVEL=6

Expand Down Expand Up @@ -149,4 +152,7 @@ NEXT_PUBLIC_MODAL_FEATURE_LINK=

# ImgProxy
IMGPROXY_KEY=
IMGPROXY_SALT=
IMGPROXY_SALT=

# Enable/Disable access logs: true | false
ACCESS_LOGS_ENABLED=false
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function BountySettings({

const isGovernor = currentUser?.isGovernor;
const isDraftFunding = currentBounty?.isDraft || !currentBounty?.isFunded
const cancelableTime = currentBounty?.network?.cancelableTime;
const cancelableTime = +currentBounty?.network?.cancelableTime;
const isCancelable = +new Date() >= +new Date(+currentBounty.createdAt + cancelableTime);
const objViewProps = {
onEditIssue,
Expand Down
18 changes: 15 additions & 3 deletions components/bounty/comments/input-comment/controller.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import {ChangeEvent, useState} from "react";

import { AxiosError } from "axios";
import {useTranslation} from "next-i18next";

import InputCommentView from "components/bounty/comments/input-comment/view";

import { COMMENT_MAX_LENGTH } from "helpers/constants";
import {QueryKeys} from "helpers/query-keys";

import {IdsComment, TypeComment} from "interfaces/comments";

import {CreateComment} from "x-hooks/api/comments";
import { useToastStore } from "x-hooks/stores/toasts/toasts.store";
import useReactQueryMutation from "x-hooks/use-react-query-mutation";
import { useTaskSubscription } from "x-hooks/use-task-subscription";

Expand All @@ -34,7 +37,10 @@ export default function InputComment({
deliverable: QueryKeys.deliverable(ids?.deliverableId?.toString()),
proposal: QueryKeys.proposalComments(ids?.proposalId?.toString())
}[type];
const commentLength = comment?.length || 0;
const error = commentLength > COMMENT_MAX_LENGTH ? "max-length" : null;

const { addError, addSuccess } = useToastStore();
const { refresh: refreshSubscriptions } = useTaskSubscription();
const { mutate: addComment } = useReactQueryMutation({
queryKey: queryKey,
Expand All @@ -43,9 +49,12 @@ export default function InputComment({
...ids,
type
}),
toastSuccess: t("bounty:actions.comment.success"),
toastError: t("bounty:actions.comment.error"),
onSuccess: () => {
onSettled: (data, error: AxiosError<{ message: string }>) => {
if (error) {
addError(t("actions.failed"), `${error?.response?.data?.message}`);
return;
}
addSuccess(t("actions.success"), t("bounty:actions.comment.success"));
setComment("");
refreshSubscriptions();
}
Expand All @@ -61,6 +70,9 @@ export default function InputComment({
userAddress={userAddress}
avatarHash={avatar}
comment={comment}
commentLength={commentLength}
maxLength={COMMENT_MAX_LENGTH}
error={error}
onCommentChange={onCommentChange}
onCommentSubmit={addComment}
/>
Expand Down
90 changes: 56 additions & 34 deletions components/bounty/comments/input-comment/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {useTranslation} from "next-i18next";

import AvatarOrIdenticon from "components/avatar-or-identicon";
import Button from "components/button";
import If from "components/If";

import {truncateAddress} from "helpers/truncate-address";

Expand All @@ -12,55 +13,76 @@ export default function InputCommentView({
userAddress,
avatarHash,
comment,
commentLength,
maxLength,
error = null,
onCommentSubmit,
onCommentChange ,
}: {
handle?: string;
userAddress: string;
avatarHash: string;
comment: string;
commentLength: number;
maxLength: number;
error: "max-length" | null;
onCommentSubmit: (...props) => void;
onCommentChange : (e: ChangeEvent<HTMLTextAreaElement>) => void
}) {
const { t } = useTranslation("common");

const borderColor = error ? "danger" : "gray-700";
const errorMessage = {
"max-length": t("errors.comment.max-length", { max: maxLength }),
}[error];

return (
<div className="border-radius-8 p-3 bg-gray-850 mb-3 border-gray-700 border">
<div className="d-flex align-items-center mb-2">
<div className="d-flex align-items-center text-truncate">
<AvatarOrIdenticon
user={{
avatar: avatarHash,
handle,
address: userAddress,
}}
size="xsm"
/>
<span className="xs-medium ms-2 text-truncate">
{handle ? `@${handle}` : truncateAddress(userAddress)}{" "}
</span>
<>
<div className={`border-radius-8 p-3 bg-gray-850 border border-${borderColor}`}>
<div className="d-flex align-items-center justify-content-between mb-2">
<div className="d-flex align-items-center text-truncate">
<AvatarOrIdenticon
user={{
avatar: avatarHash,
handle,
address: userAddress,
}}
size="xsm"
/>
<span className="xs-medium ms-2 text-truncate">
{handle ? `@${handle}` : truncateAddress(userAddress)}{" "}
</span>
</div>

<div className="xs-medium text-gray-300">
{commentLength}/{maxLength}
</div>
</div>
</div>
<textarea
tabIndex={0}
className="ps-0 form-control input-comment"
rows={2}
data-testid="comments-textarea"
placeholder={t("comments.input.placeholder")}
value={comment}
onChange={onCommentChange}
/>
<textarea
tabIndex={0}
className="ps-0 form-control input-comment"
rows={2}
data-testid="comments-textarea"
placeholder={t("comments.input.placeholder")}
value={comment}
onChange={onCommentChange}
/>

<div className="d-flex justify-content-end mt-2">
<Button
className="btn-comment"
data-testid="comments-btn"
onClick={onCommentSubmit}
disabled={!comment?.length}
>
{t("comments.button")}
</Button>
<div className="d-flex justify-content-end mt-2">
<Button
className="btn-comment"
data-testid="comments-btn"
onClick={onCommentSubmit}
disabled={!comment?.length || !!error}
>
{t("comments.button")}
</Button>
</div>
</div>
</div>

<If condition={!!error}>
<small className="xs-small text-danger">{errorMessage}</small>
</If>
</>
);
}
11 changes: 9 additions & 2 deletions components/profile/notification-form/controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { lowerCaseCompare } from "helpers/string";
import { isValidEmail } from "helpers/validators/email";

import { CustomSession } from "interfaces/custom-session";
import { EmailConfirmationErrors } from "interfaces/enums/Errors";
import { NotificationSettings } from "interfaces/user-notification";

import { useUpdateEmail } from "x-hooks/api/user";
Expand Down Expand Up @@ -90,8 +91,12 @@ export default function NotificationForm() {
const sessionUser = (sessionData as CustomSession)?.user;
const userEmail = sessionUser?.email || "";
const isConfirmationPending = !!userEmail && !sessionUser?.isEmailConfirmed;
const isEmailConfirmed = !!userEmail && !!sessionUser?.isEmailConfirmed;
const isSameEmail = lowerCaseCompare(userEmail, inputEmail);
const emailVerificationError = query?.emailVerificationError?.toString()?.replace("Error: ", "");
const emailVerification = query?.emailVerification?.toString();
const emailVerificationError = !isEmailConfirmed && emailVerification && emailVerification !== "success" ?
emailVerification : null;
const canResend = !!emailVerificationError && emailVerification !== EmailConfirmationErrors.ALREADY_CONFIRMED;

function handleEmailChange(e) {
setInputEmail(e.target.value);
Expand All @@ -105,7 +110,7 @@ export default function NotificationForm() {
function onResend() {
updateEmail(userEmail, {
onSuccess: () => {
goToProfilePage("dashboard", { emailVerificationError: "" });
goToProfilePage("dashboard", { emailVerification: "" });
}
});
}
Expand Down Expand Up @@ -151,7 +156,9 @@ export default function NotificationForm() {
isInvalid={isEmailInvalid}
isConfirmationPending={isConfirmationPending}
isExecuting={isExecutingEmail}
isEmailConfirmed={isEmailConfirmed}
emailVerificationError={emailVerificationError}
canResend={canResend}
notificationSettings={userNotificationSettings || {}}
toggleNotificationItem={toggleNotificationItem}
onChange={handleEmailChange}
Expand Down
44 changes: 32 additions & 12 deletions components/profile/notification-form/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";

import {useTranslation} from "next-i18next";

import DoneIcon from "assets/icons/done-icon";
import InfoIconEmpty from "assets/icons/info-icon-empty";

import Button from "components/button";
Expand All @@ -19,6 +20,8 @@ interface NotificationFormViewProps {
isInvalid: boolean;
isConfirmationPending: boolean;
isExecuting: boolean;
isEmailConfirmed: boolean;
canResend: boolean;
emailVerificationError: string;
notificationSettings: Partial<NotificationSettings>;
onChange: (e) => void;
Expand All @@ -36,6 +39,8 @@ export default function NotificationFormView({
isInvalid,
isConfirmationPending,
isExecuting,
isEmailConfirmed,
canResend,
emailVerificationError,
notificationSettings,
onChange,
Expand Down Expand Up @@ -78,7 +83,7 @@ export default function NotificationFormView({
<Button
onClick={onSave}
disabled={isSaveButtonDisabled}
isLoading={isExecuting}
isLoading={!emailVerificationError && isExecuting}
data-testid="notification-save-btn">
{t("actions.save")}
</Button>
Expand All @@ -99,22 +104,24 @@ export default function NotificationFormView({

<If condition={!!emailVerificationError}>
<div className="row align-items-center mt-2">
<div className="col-6">
<div className="col-6 col-lg-4">
<small className="xs-medium text-danger">
{t(`profile:email-errors.${emailVerificationError}`)}
</small>
</div>

<div className="col-auto">
<Button
onClick={onResend}
disabled={isExecuting || !emailVerificationError}
isLoading={emailVerificationError && isExecuting}
data-testid="notification-re-send-btn"
>
{t("profile:notifications-form.re-send")}
</Button>
</div>
<If condition={!!canResend}>
<div className="col-auto">
<Button
onClick={onResend}
disabled={isExecuting || !emailVerificationError}
isLoading={emailVerificationError && isExecuting}
data-testid="notification-re-send-btn"
>
{t("profile:notifications-form.re-send")}
</Button>
</div>
</If>
</div>
</If>

Expand All @@ -127,6 +134,19 @@ export default function NotificationFormView({
</div>
</div>
</If>

<If condition={isEmailConfirmed && !emailVerificationError}>
<div className="row align-items-center mt-2">
<div className="col">
<span className="text-green-500 xs-medium">
<DoneIcon className="mr-1" />
</span>
<span className="text-green-500 xs-medium font-weight-normal">
{t("profile:notifications-form.email-confirmed")}
</span>
</div>
</div>
</If>
</div>

<div className="row align-items-center mt-4">
Expand Down
21 changes: 17 additions & 4 deletions contexts/wagmi-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {getDefaultConfig} from "@rainbow-me/rainbowkit";
import getConfig from "next/config";
import {parseCookies} from "nookies";
import {defineChain} from "viem";
import {aurora, auroraTestnet, mainnet, moonbeam, polygon, polygonAmoy, polygonMumbai} from "viem/chains";
import {aurora, auroraTestnet, mainnet, moonbeam, polygon, polygonAmoy, polygonMumbai, localhost} from "viem/chains";
import {cookieStorage, cookieToInitialState, createStorage, WagmiProvider} from "wagmi";

interface WagmiProps {
Expand All @@ -30,18 +30,31 @@ const coinEx = defineChain({
}
});

const ganache = defineChain({
...localhost,
blockExplorers: {
default: {
name: "Local",
url: "http://127.0.0.1:8545",
}
}
});

const config = getDefaultConfig({
appName: "BEPRO",
projectId: publicRuntimeConfig?.walletConnectProjectId || "bc2288336095f20ebf8653a1ab670566",
chains: [
polygon,
polygonAmoy,
polygonMumbai,
aurora,
auroraTestnet,
moonbeam,
coinEx,
mainnet,
polygonAmoy,
polygonMumbai,
auroraTestnet,
... (publicRuntimeConfig?.isProduction ? [] : [
ganache,
])
],
ssr: true,
storage: createStorage({
Expand Down
Loading
Loading