feat: added "Project Listed" modal

This commit is contained in:
MTG2000
2022-08-16 13:22:48 +03:00
parent 86acaa5ee5
commit 2e88178cc4
9 changed files with 168 additions and 3 deletions

View File

@@ -0,0 +1,26 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import ProjectListedModal from './ProjectListedModal';
export default {
title: 'Projects/List Project Page/Modals/Project Listed Modal',
component: ProjectListedModal,
argTypes: {
backgroundColor: { control: 'color' },
},
} as ComponentMeta<typeof ProjectListedModal>;
const Template: ComponentStory<typeof ProjectListedModal> = (args) => <ProjectListedModal {...args as any} ></ProjectListedModal>
export const Default = Template.bind({});
Default.args = {
project: {
id: 12,
name: "BOLT FUN",
img: "https://picsum.photos/id/870/150/150.jpg",
tagline: "An awesome directory for lightning projects and makers"
}
}

View File

@@ -0,0 +1,96 @@
import { motion } from 'framer-motion'
import { useAppSelector, useMediaQuery, useWindowSize } from 'src/utils/hooks';
import { ModalCard, modalCardVariants } from 'src/Components/Modals/ModalsContainer/ModalsContainer'
import Button from 'src/Components/Button/Button'
import { IoClose } from 'react-icons/io5';
import NutImg from './nut.png'
import AlbyImg from './alby.png'
import Avatar from 'src/features/Profiles/Components/Avatar/Avatar';
import { createRoute } from 'src/utils/routing';
import Confetti from 'react-confetti'
import { Portal } from 'src/Components/Portal/Portal';
interface Props extends ModalCard {
project: {
id: number,
img: string,
name: string,
tagline: string,
}
}
export default function ProjectListedModal({ onClose, direction, project, ...props }: Props) {
const size = useWindowSize();
const isSmallScreen = useMediaQuery('screen and (max-width: 680px)')
return (
<motion.div
custom={direction}
variants={modalCardVariants}
initial='initial'
animate="animate"
exit='exit'
className="modal-card max-w-[442px] p-24 rounded-xl relative"
>
<Portal id='confetti'>
<Confetti recycle={false} width={size.width} height={size.height} numberOfPieces={isSmallScreen ? 200 : 400} />
</Portal>
<IoClose className='absolute text-body2 top-24 right-24 hover:cursor-pointer' onClick={onClose} />
<h2 className='text-h5 font-bold text-center'>Product listed!</h2>
<div className="flex flex-col gap-16 justify-center items-center my-24">
<Avatar src={project.img} width={80} />
<p className="text-body3 font-medium">{project.name}</p>
</div>
<p className="text-body4 font-light text-gray-600 mt-24 text-center">
Nice work, you successfully listed your product! Here are a few ideas to get your started.
</p>
<div className="flex flex-col gap-16 my-32">
<div className='!flex items-center gap-16'>
<div className={`rounded-8 w-48 h-48 text-center py-12 shrink-0 bg-gray-100`}>
</div>
<div>
<p className="font-medium self-center">
Stories
</p>
<p className="text-body5 text-gray-500">
Tell the maker community about your product.
</p>
</div>
</div>
<div className='!flex items-center gap-16'>
<div className={`rounded-8 w-48 h-48 text-center py-12 shrink-0 bg-gray-100`}>
</div>
<div>
<p className="font-medium self-center">
Start hacking
</p>
<p className="text-body5 text-gray-500">
Kickstart your hacking journey with a tournament.
</p>
</div>
</div>
</div>
<div className="flex flex-col gap-16" >
<Button
color='primary'
fullWidth
newTab
href={createRoute({ type: "edit-story" })}
> Write a story</Button>
<Button
color='white'
fullWidth
newTab
href='/tournaments'
> Explore tournaments</Button>
</div>
</motion.div>
)
}

View File

@@ -0,0 +1,4 @@
import { lazyModal } from 'src/utils/helperFunctions';
export const { LazyComponent: ProjectListedModal } = lazyModal(() => import('./ProjectListedModal'))

View File

@@ -7,6 +7,8 @@ import { IListProjectForm } from "../FormContainer/FormContainer";
import { useMemo, useState } from 'react'
import { tabs } from '../../ListProjectPage'
import { NotificationsService } from 'src/services'
import { useAppDispatch } from 'src/utils/hooks';
import { openModal } from 'src/redux/features/modals.slice';
interface Props {
currentTab: keyof typeof tabs
@@ -16,6 +18,7 @@ export default function SaveChangesCard(props: Props) {
const { handleSubmit, formState: { errors, isDirty, }, reset, getValues, watch } = useFormContext<IListProjectForm>();
const navigate = useNavigate();
const dispatch = useAppDispatch();
const [isLoading, setIsLoading] = useState(false);
const isUpdating = useMemo(() => !!getValues('id'), [getValues]);
@@ -29,7 +32,21 @@ export default function SaveChangesCard(props: Props) {
}
const clickSubmit = handleSubmit<IListProjectForm>(data => {
NotificationsService.success("Product listed successfully")
if (isUpdating)
NotificationsService.success("Saved changes successfully")
else {
dispatch(openModal({
Modal: "ProjectListedModal", props: {
project: {
id: data.id!,
name: data.name,
img: data.thumbnail_image || "https://picsum.photos/id/870/150/150.jpg",
tagline: data.tagline,
}
}
}))
}
console.log(data);
}, () => {
NotificationsService.error("Please fill all the required fields");

View File

@@ -1,6 +1,7 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { Login_ScanningWalletCard, Login_ExternalWalletCard, Login_NativeWalletCard, Login_SuccessCard } from "src/Components/Modals/Login";
import { ProjectDetailsCard } from "src/features/Projects/pages/ProjectPage/ProjectDetailsCard";
import { ProjectListedModal } from "src/features/Projects/pages/ListProjectPage/Components/ProjectListedModal";
import VoteCard from "src/features/Projects/pages/ProjectPage/VoteCard/VoteCard";
import { InsertImageModal } from 'src/Components/Inputs/TextEditor/InsertImageModal'
import { InsertVideoModal } from 'src/Components/Inputs/TextEditor/InsertVideoModal'
@@ -37,7 +38,7 @@ export const ALL_MODALS = {
ConfirmModal,
NoWeblnModal,
LinkingAccountModal,
ProjectListedModal,
// Text Editor Modals
InsertImageModal,
InsertVideoModal,

View File

@@ -3,7 +3,7 @@
$screen-xs-min: 320px;
@import "./tw.scss", "./shared.scss", "./vendors.scss", "./scrollbar.scss",
"./ui_state.scss";
"./ui_state.scss", "./portals.scss";
@import "/src/styles/mixins/index.scss";
html {

6
src/styles/portals.scss Normal file
View File

@@ -0,0 +1,6 @@
#confetti {
z-index: 3000;
position: fixed;
inset: 0;
pointer-events: none;
}

View File

@@ -1,3 +1,10 @@
:root {
--navHeight: 0;
// Z Indexes
--baseZ: 10;
--navZ: var(--baseZ) + 1;
--popupZ: var(--navZ) + 1;
--modalZ: var(--popupZ) + 1;
--particlesZ: var(--modalZ) + 1;
}

View File

@@ -14,6 +14,10 @@ type RouteOptions =
title?: string,
username?: string,
}
| {
type: "edit-story",
id?: number,
}
| {
type: "bounty",
id: string | number,
@@ -47,6 +51,10 @@ export function createRoute(options: RouteOptions) {
return `/blog/post/story/${options.id}`
+ (options.title ? `/${toSlug(options.title)}` : "");
if (options.type === "edit-story")
return `/blog/create-post` + (options.id ? `?id=${options.id}` : '')
if (options.type === "bounty")
return `/blog/post/bounty/${options.id}`
+ (options.title ? `/${toSlug(options.title)}` : "");