Merge branch 'dev' into feature/linking-accounts

This commit is contained in:
MTG2000
2022-08-13 18:41:40 +03:00
25 changed files with 244 additions and 153 deletions

View File

@@ -0,0 +1,23 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import Card from './Card';
export default {
title: 'Shared/Card',
component: Card,
argTypes: {
backgroundColor: { control: 'color' },
},
} as ComponentMeta<typeof Card>;
const Template: ComponentStory<typeof Card> = (args) => <Card {...args} > <p className="text-body4 text-gray-700">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Voluptas corrupti molestias, accusantium porro vitae mollitia voluptatibus omnis. Itaque assumenda minus cum reprehenderit sit, cupiditate, impedit doloribus ad modi corporis maiores. Corrupti praesentium, dolor vero veniam suscipit architecto accusamus beatae minus iste sed ea harum aperiam quibusdam fugiat molestias dolores magni!</p>
</Card>
export const Default = Template.bind({});
export const Primary = Template.bind({});
Primary.args = {
onlyMd: true
}

View File

@@ -0,0 +1,33 @@
import React, { PropsWithChildren } from 'react'
interface Props extends React.ComponentPropsWithoutRef<'div'> {
onlyMd?: boolean;
defaultPadding?: boolean
}
const Card = React.forwardRef<HTMLDivElement, PropsWithChildren<Props>>(({
onlyMd = false,
defaultPadding = true,
className,
...props
}, ref) => {
return (
<div
{...props}
ref={ref}
className={`
${onlyMd ?
`md:bg-white md:rounded-16 md:border-2 border-gray-200 ${defaultPadding && "md:p-24"}` :
`bg-white rounded-12 md:rounded-16 border-2 border-gray-200 ${defaultPadding && "p-16 md:p-24"}`
}
${className}
`}
></div>
)
})
export default Card;

View File

@@ -7,6 +7,7 @@ import DOMPurify from 'dompurify';
import { Vote_Item_Type } from "src/graphql";
import { useVote } from "src/utils/hooks";
import { useState } from "react";
import Card from "src/Components/Card/Card";
interface Props {
@@ -25,13 +26,12 @@ export default function CommentCard({ comment, canReply, onReply }: Props) {
});
return (
<div className="border-2 border-gray-200 rounded-12 md:rounded-16 p-24">
<Card>
<Header author={comment.author} date={new Date(comment.created_at).toISOString()} />
<div
className="text-body4 mt-16 whitespace-pre-line"
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(marked.parse(comment.body)) }}
>
</div>
<div className="flex gap-24 mt-16 items-center">
<VoteButton
@@ -46,6 +46,6 @@ export default function CommentCard({ comment, canReply, onReply }: Props) {
<BiComment /> <span className="align-middle text-body5">Reply</span>
</button>}
</div>
</div>
</Card>
)
}

View File

@@ -10,6 +10,7 @@ import { AiOutlineClose } from 'react-icons/ai'
import { Link, useLocation } from 'react-router-dom'
import { createRoute, PAGES_ROUTES } from 'src/utils/routing'
import Preferences from 'src/services/preferences.service'
import Card from 'src/Components/Card/Card';
// const createWorker = createWorkerFactory(() => import('./comments.worker'));
@@ -44,8 +45,7 @@ export default function CommentsSection({ type, id }: Props) {
return (
<div className="md:border-2 border-gray-200 rounded-12 md:rounded-16 md:p-32 bg-white">
<Card onlyMd>
<div className="flex flex-wrap justify-between">
<h6 className="text-body2 font-bolder">Discussion</h6>
{connectionStatus.status === 'Connected' && <div className="bg-green-50 text-green-500 text-body5 font-medium py-4 px-12 rounded-48"> &#8226; <span className="hidden md:inline">Connected to {connectionStatus.connectedRelaysCount} relays</span> 📡</div>}
@@ -88,6 +88,6 @@ export default function CommentsSection({ type, id }: Props) {
onReply={content => handleNewComment(content, comment.nostr_id.toString())}
/>)}
</div>
</div>
</Card>
)
}

View File

@@ -7,6 +7,7 @@ import { Author, Tag, Vote_Item_Type } from 'src/graphql';
import Badge from "src/Components/Badge/Badge"
import { createRoute } from "src/utils/routing"
import { BiComment } from "react-icons/bi"
import Card from "src/Components/Card/Card"
export type StoryCardType = Pick<Story,
@@ -34,7 +35,7 @@ export default function StoryCard({ story }: Props) {
});
return (
<div className="bg-white rounded-12 overflow-hidden border-2 border-gray-200">
<Card className="overflow-hidden" defaultPadding={false}>
{story.cover_image && <img src={story.cover_image} className='h-[200px] w-full object-cover' alt="" />}
<div className="p-24">
<Header author={story.author} date={story.createdAt} />
@@ -56,6 +57,7 @@ export default function StoryCard({ story }: Props) {
</div>
</div>
</div>
</div>
</Card>
)
}

View File

@@ -1,5 +1,6 @@
import Skeleton from 'react-loading-skeleton'
import { Link } from 'react-router-dom'
import Card from 'src/Components/Card/Card'
import Avatar from 'src/features/Profiles/Components/Avatar/Avatar'
import { useTrendingPostsQuery } from 'src/graphql'
import { random } from 'src/utils/helperFunctions'
@@ -12,7 +13,7 @@ export default function TrendingCard() {
return (
<div className="bg-white rounded-12 md:border-2 border-gray-200 md:p-16">
<Card onlyMd>
<h3 className="text-body2 font-bolder mb-16">Trending on BOLT.FUN</h3>
<ul className='flex flex-col'>
{
@@ -34,6 +35,6 @@ export default function TrendingCard() {
}
)}
</ul>
</div>
</Card>
)
}

View File

@@ -4,6 +4,7 @@ import Slider from 'src/Components/Slider/Slider';
import { Tag, usePopularTagsQuery } from 'src/graphql';
import { MEDIA_QUERIES } from 'src/utils/theme';
import { capitalize } from 'src/utils/helperFunctions';
import Card from 'src/Components/Card/Card';
export type FilterTag = Pick<Tag, 'id' | 'title' | "icon">
@@ -30,7 +31,8 @@ export default function PopularTagsFilter({ value, onChange }: Props) {
return (
<div className='overflow-hidden'>
{isMdScreen ?
<div className='bg-white border-2 border-gray-200 rounded-12 p-16'>
<Card>
<p className="text-body2 font-bolder text-black mb-16">Popular Tags</p>
<ul className=' flex flex-col gap-16'>
{tagsQuery.loading ?
@@ -60,7 +62,8 @@ export default function PopularTagsFilter({ value, onChange }: Props) {
</span>
</li>)}
</ul>
</div>
</Card>
:
<>
{

View File

@@ -1,6 +1,7 @@
import dayjs from "dayjs";
import { Link } from "react-router-dom";
import Button from "src/Components/Button/Button";
import Card from "src/Components/Card/Card";
import { Author } from "src/features/Posts/types";
import Avatar from "src/features/Profiles/Components/Avatar/Avatar";
import { trimText } from "src/utils/helperFunctions";
@@ -16,7 +17,7 @@ interface Props {
export default function AuthorCard({ author }: Props) {
return (
<div className="bg-white p-16 border-2 border-gray-200 rounded-12">
<Card>
<div className='flex gap-8'>
<Avatar width={48} src={author.avatar} />
<div className="overflow-hidden">
@@ -31,6 +32,6 @@ export default function AuthorCard({ author }: Props) {
className="mt-16">
Maker's Profile
</Button>
</div>
</Card>
)
}

View File

@@ -9,6 +9,7 @@ import { useAppSelector } from "src/utils/hooks";
import { useUpdateStory } from './useUpdateStory'
import { FaPen } from "react-icons/fa";
import DOMPurify from 'dompurify';
import Card from "src/Components/Card/Card";
interface Props {
@@ -26,9 +27,8 @@ export default function StoryPageContent({ story }: Props) {
return (
<>
<div id="content" className="bg-white md:p-32 md:border-2 border-gray-200 rounded-16 relative">
<div id="content" className="bg-white md:p-32 md:border-2 border-gray-200 rounded-16 relative"> </div>
<Card id="content" onlyMd className="relative">
{story.cover_image &&
<img src={story.cover_image}
className='w-full object-cover rounded-12 md:rounded-16 mb-16'
@@ -72,7 +72,8 @@ export default function StoryPageContent({ story }: Props) {
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(marked.parse(story.body)) }}
>
</div>
</div>
</Card>
{/* <div id="comments" className="mt-10 comments_col">
<CommentsSection comments={story.comments} />
</div> */}

View File

@@ -1,6 +1,7 @@
import Button from 'src/Components/Button/Button';
import { useAppDispatch } from 'src/utils/hooks';
import { openModal } from 'src/redux/features/modals.slice';
import Card from 'src/Components/Card/Card';
import { useMyWalletsKeysQuery, useUpdateUserWalletsKeysMutation } from 'src/graphql';
import Skeleton from 'react-loading-skeleton';
import { useReducer } from 'react';
@@ -116,10 +117,8 @@ export default function AccountCard({ }: Props) {
return (
<div className="rounded-16 bg-white border-2 border-gray-200 p-24">
<p className="text-body2 font-bold">Account Settings</p>
<Card>
<p className="text-body2 font-bold">🔒 Linking Accounts</p>
<div className='mt-24 flex flex-col gap-16'>
<p className="text-body3 font-bold">Linked Wallets</p>
<p className="text-body4 text-gray-600">
@@ -186,8 +185,6 @@ export default function AccountCard({ }: Props) {
</>
}
</div>
</div>
</Card>
)
}

View File

@@ -4,11 +4,12 @@ import NotFoundPage from "src/features/Shared/pages/NotFoundPage/NotFoundPage";
import Slider from "src/Components/Slider/Slider";
import { useProfileQuery } from "src/graphql";
import { useAppSelector, useMediaQuery } from "src/utils/hooks";
import CommentsSettingsCard from "../ProfilePage/CommentsSettingsCard/CommentsSettingsCard";
import UpdateMyProfileCard from "./UpdateMyProfileCard/UpdateMyProfileCard";
import UpdateMyProfileTab from "./UpdateMyProfileTab/UpdateMyProfileTab";
import { Helmet } from 'react-helmet'
import { MEDIA_QUERIES } from "src/utils/theme";
import AccountCard from "./AccountCard/AccountCard";
import PreferencesTab from "./PreferencesTab/PreferencesTab";
import Card from "src/Components/Card/Card";
const links = [
@@ -56,7 +57,7 @@ export default function EditProfilePage() {
<div className="page-container grid grid-cols-1 md:grid-cols-4 gap-24">
<aside>
{isMediumScreen ?
<div className='bg-white border-2 border-gray-200 rounded-12 p-16 sticky-side-element' >
<Card className="sticky-side-element">
<p className="text-body2 font-bolder text-black mb-16">Edit maker profile</p>
<ul className=' flex flex-col gap-8'>
{links.map((link, idx) =>
@@ -72,7 +73,7 @@ export default function EditProfilePage() {
</NavLink>
</li>)}
</ul>
</div>
</Card>
:
<div className="border-b-2 border-gray-200">
<Slider>
@@ -96,9 +97,9 @@ export default function EditProfilePage() {
<main className="md:col-span-3">
<Routes>
<Route index element={<Navigate to='my-profile' />} />
<Route path='my-profile' element={<UpdateMyProfileCard data={profileQuery.data.profile} />} />
<Route path='my-profile' element={<UpdateMyProfileTab data={profileQuery.data.profile} />} />
<Route path='account' element={<AccountCard />} />
<Route path='preferences' element={<CommentsSettingsCard nostr_prv_key={profileQuery.data.profile.nostr_prv_key} nostr_pub_key={profileQuery.data.profile.nostr_pub_key} isOwner={true} />
<Route path='preferences' element={<PreferencesTab nostr_prv_key={profileQuery.data.profile.nostr_prv_key} nostr_pub_key={profileQuery.data.profile.nostr_pub_key} isOwner={true} />
} />
</Routes>
</main>

View File

@@ -0,0 +1,102 @@
import { useToggle } from '@react-hookz/web'
import { FaChevronDown } from 'react-icons/fa';
import { Nullable } from 'remirror';
import Button from 'src/Components/Button/Button';
import CopyToClipboard from 'src/Components/CopyToClipboard/CopyToClipboard';
import IconButton from 'src/Components/IconButton/IconButton';
import { CONSTS } from 'src/utils';
import { motion } from "framer-motion";
import Card from 'src/Components/Card/Card';
interface Props {
nostr_pub_key: Nullable<string>;
nostr_prv_key: Nullable<string>;
}
export default function CommentsSettingsCard({ nostr_prv_key, nostr_pub_key }: Props) {
const [relaysDropdownOpen, toggleRelaysDropdownOpen] = useToggle(false)
return (
<Card>
<p className="text-body2 font-bold">💬 Nostr comments <span className="bg-green-50 text-green-500 text-body5 font-medium py-4 px-12 rounded-48 ml-8">Experimental</span></p>
<p className="mt-8 text-body4 text-gray-600">
Our commenting system is experimental and uses Nostr to store and relay your messages and replies to our own relay, as well as relays ran by other people in the community.
We generate Nostr keys for you since there are no popular wallets which support it.
</p>
<div className='mt-24 flex flex-col gap-16'>
<p className="text-body3 font-bold">Nostr keys</p>
{nostr_prv_key && <div>
<p className="text-body5 font-bold">
Your Nostr Private Key
</p>
<div className="input-wrapper mt-8 relative">
<input
type={'password'}
className="input-text"
defaultValue={nostr_prv_key}
readOnly
/>
<CopyToClipboard text={nostr_prv_key} />
</div>
</div>}
<div>
<p className="text-body5 font-bold">
Your Nostr Public Key
</p>
<div className="input-wrapper mt-8 relative">
<input
type='text'
className="input-text"
defaultValue={nostr_pub_key!}
readOnly
/>
<CopyToClipboard text={nostr_pub_key ?? ''} />
</div>
</div>
</div>
{/* <p className="text-body4 font-bold mt-24">
Connect your Nostr identity
</p>
<div className="mt-8 py-12 relative">
<p className="text-body4 text-gray-400 font-bold">
🚧 Coming Soon 🚧
</p>
</div> */}
<div className='mt-24'>
<div className="flex justify-between">
<p className="text-body4 font-bold">
Nostr relays
</p>
<IconButton onClick={() => toggleRelaysDropdownOpen()}>
<motion.div
animate={{ rotate: relaysDropdownOpen ? 180 : 0 }}
>
<FaChevronDown />
</motion.div>
</IconButton>
</div>
{relaysDropdownOpen &&
<motion.ul
initial={{ y: '-50%', opacity: 0 }}
animate={{ y: '0', opacity: 1 }}
className="mt-8 relative flex flex-col gap-8">
{CONSTS.DEFAULT_RELAYS.map((url, idx) => <li key={idx} className="text-body4 border-b py-12 px-16 border border-gray-200 rounded-16">{url}</li>)}
</motion.ul>}
</div>
<Button color='gray' fullWidth disabled className='mt-24'>
Connect your Nostr ID (coming soon)
</Button>
</Card>
)
}

View File

@@ -0,0 +1,21 @@
import { Nullable } from 'remirror';
import CommentsSettingsCard from './CommentsSettingsCard/CommentsSettingsCard';
interface Props {
isOwner?: boolean;
nostr_pub_key: Nullable<string>;
nostr_prv_key: Nullable<string>;
}
export default function PreferencesTab({ nostr_prv_key, nostr_pub_key, isOwner }: Props) {
return (
<div className="grid grid-cols-1 md:grid-cols-3 gap-24">
<div className="col-span-2">
<CommentsSettingsCard nostr_prv_key={nostr_prv_key} nostr_pub_key={nostr_pub_key} />
</div>
</div>
)
}

View File

@@ -1,6 +1,7 @@
import React from 'react'
import { Link } from 'react-router-dom'
import Button from 'src/Components/Button/Button'
import Card from 'src/Components/Card/Card'
import Avatar from 'src/features/Profiles/Components/Avatar/Avatar'
import { useProfileQuery } from 'src/graphql'
import { trimText } from 'src/utils/helperFunctions'
@@ -33,7 +34,7 @@ export default function SaveChangesCard(props: Props) {
}
return (
<div className="md:p-24 rounded-16 bg-white md:border-2 border-gray-200 flex flex-col gap-24">
<Card onlyMd className='flex flex-col gap-24'>
<div className='hidden md:flex gap-8'>
<Link
className='shrink-0'
@@ -49,7 +50,7 @@ export default function SaveChangesCard(props: Props) {
</p>} */}
</div>
<p className="hidden md:block text-body5">{trimText(profileQuery.data.profile.bio, 120)}</p>
<div className="flex md:flex-col gap-16 justify-end">
<div className="flex flex-col gap-16">
<Button
color="primary"
onClick={props.onSubmit}
@@ -65,6 +66,6 @@ export default function SaveChangesCard(props: Props) {
Cancel
</Button>
</div>
</div>
</Card>
)
}

View File

@@ -8,6 +8,7 @@ import Avatar from "src/features/Profiles/Components/Avatar/Avatar";
import { usePrompt } from "src/utils/hooks";
import SaveChangesCard from "../SaveChangesCard/SaveChangesCard";
import { toast } from "react-toastify";
import Card from "src/Components/Card/Card";
interface Props {
data: Pick<User,
@@ -62,7 +63,7 @@ const schema: yup.SchemaOf<IFormInputs> = yup.object({
}).required();
export default function UpdateMyProfileCard({ data, onClose }: Props) {
export default function UpdateMyProfileTab({ data, onClose }: Props) {
const { register, formState: { errors, isDirty, }, handleSubmit, reset } = useForm<IFormInputs>({
defaultValues: data,
@@ -110,7 +111,7 @@ export default function UpdateMyProfileCard({ data, onClose }: Props) {
return (
<div className="grid grid-cols-1 md:grid-cols-3 gap-24">
<div className="col-span-2 rounded-16 bg-white border-2 border-gray-200">
<Card className="md:col-span-2">
<div className="bg-gray-600 relative h-[160px] rounded-t-16">
<div className="absolute left-24 bottom-0 translate-y-1/2">
<Avatar src={data.avatar} width={120} />
@@ -274,7 +275,7 @@ export default function UpdateMyProfileCard({ data, onClose }: Props) {
</p>
</form>
</div>
</div>
</Card>
<div className="self-start sticky-side-element">
<SaveChangesCard
isLoading={mutationStatus.loading}

View File

@@ -3,7 +3,7 @@ import { User } from "src/graphql"
import { trimText, withHttp } from "src/utils/helperFunctions"
import { FiGithub, FiGlobe, FiLinkedin, FiTwitter } from 'react-icons/fi'
import Button from "src/Components/Button/Button";
import { PAGES_ROUTES } from "src/utils/routing";
import Card from "src/Components/Card/Card";
interface Props {
isOwner?: boolean;
@@ -53,7 +53,8 @@ export default function AboutCard({ user, isOwner }: Props) {
return (
<div className="rounded-16 bg-white border-2 border-gray-200">
<Card defaultPadding={false}>
<div className="bg-gray-600 relative h-[160px] rounded-t-16">
<div className="absolute left-24 bottom-0 translate-y-1/2">
<Avatar src={user.avatar} width={120} />
@@ -64,8 +65,8 @@ export default function AboutCard({ user, isOwner }: Props) {
</div>
<div className="p-24 pt-0">
<div className="flex flex-col gap-16">
<h1 className="text-h2 font-bolder">
{trimText(user.name, 20)}
<h1 className="text-h2 font-bolder break-words">
{user.name}
</h1>
{links.some(link => link.hasValue) && <div className="flex flex-wrap gap-16">
@@ -99,6 +100,7 @@ export default function AboutCard({ user, isOwner }: Props) {
</p>}
</div>
</div>
</div>
</Card>
)
}

View File

@@ -1,102 +0,0 @@
import { useToggle } from '@react-hookz/web'
import { FaChevronDown } from 'react-icons/fa';
import { Nullable } from 'remirror';
import Button from 'src/Components/Button/Button';
import CopyToClipboard from 'src/Components/CopyToClipboard/CopyToClipboard';
import IconButton from 'src/Components/IconButton/IconButton';
import { CONSTS } from 'src/utils';
import { motion } from "framer-motion";
interface Props {
isOwner?: boolean;
nostr_pub_key: Nullable<string>;
nostr_prv_key: Nullable<string>;
}
export default function CommentsSettingsCard({ nostr_prv_key, nostr_pub_key, isOwner }: Props) {
const [relaysDropdownOpen, toggleRelaysDropdownOpen] = useToggle(false)
return (
<div className="grid grid-cols-1 md:grid-cols-3 gap-24">
<div className="col-span-2 rounded-16 bg-white border-2 border-gray-200 p-24">
<p className="text-body2 font-bold">💬 Nostr comments <span className="bg-green-50 text-green-500 text-body5 font-medium py-4 px-12 rounded-48 ml-8">Experimental</span></p>
<p className="mt-8 text-body4 text-gray-600">
Our commenting system is experimental and uses Nostr to store and relay your messages and replies to our own relay, as well as relays ran by other people in the community.
We generate Nostr keys for you since there are no popular wallets which support it.
</p>
<div className='mt-24 flex flex-col gap-16'>
<p className="text-body3 font-bold">Nostr keys</p>
{nostr_prv_key && <div>
<p className="text-body5 font-bold">
Your Nostr Private Key
</p>
<div className="input-wrapper mt-8 relative">
<input
type={'password'}
className="input-text"
defaultValue={nostr_prv_key}
readOnly
/>
<CopyToClipboard text={nostr_prv_key} />
</div>
</div>}
<div>
<p className="text-body5 font-bold">
Your Nostr Public Key
</p>
<div className="input-wrapper mt-8 relative">
<input
type='text'
className="input-text"
defaultValue={nostr_pub_key!}
readOnly
/>
<CopyToClipboard text={nostr_pub_key ?? ''} />
</div>
</div>
</div>
{/* <p className="text-body4 font-bold mt-24">
Connect your Nostr identity
</p>
<div className="mt-8 py-12 relative">
<p className="text-body4 text-gray-400 font-bold">
🚧 Coming Soon 🚧
</p>
</div> */}
<div className='mt-24'>
<div className="flex justify-between">
<p className="text-body4 font-bold">
Nostr relays
</p>
<IconButton onClick={() => toggleRelaysDropdownOpen()}>
<motion.div
animate={{ rotate: relaysDropdownOpen ? 180 : 0 }}
>
<FaChevronDown />
</motion.div>
</IconButton>
</div>
{relaysDropdownOpen &&
<motion.ul
initial={{ y: '-50%', opacity: 0 }}
animate={{ y: '0', opacity: 1 }}
className="mt-8 relative flex flex-col gap-8">
{CONSTS.DEFAULT_RELAYS.map((url, idx) => <li key={idx} className="text-body4 border-b py-12 px-16 border border-gray-200 rounded-16">{url}</li>)}
</motion.ul>}
</div>
<Button color='gray' fullWidth disabled className='mt-24'>
Connect your Nostr ID (coming soon)
</Button>
</div>
</div>
)
}

View File

@@ -7,7 +7,6 @@ import { Helmet } from 'react-helmet'
import { useAppSelector } from 'src/utils/hooks';
import styles from './styles.module.scss'
import StoriesCard from "./StoriesCard/StoriesCard"
import CommentsSettingsCard from "./CommentsSettingsCard/CommentsSettingsCard"
export default function ProfilePage() {

View File

@@ -2,6 +2,7 @@ import React from 'react'
import { Link } from 'react-router-dom'
import Badge from 'src/Components/Badge/Badge'
import Button from 'src/Components/Button/Button'
import Card from 'src/Components/Card/Card'
import { Story } from 'src/features/Posts/types'
import { getDateDifference } from 'src/utils/helperFunctions'
import { Tag } from 'src/utils/interfaces'
@@ -24,7 +25,7 @@ interface Props {
export default function StoriesCard({ stories, isOwner }: Props) {
return (
<div className="rounded-16 bg-white border-2 border-gray-200 p-24">
<Card>
<p className="text-body2 font-bold">Stories ({stories.length})</p>
{stories.length > 0 &&
<ul className="">
@@ -64,6 +65,6 @@ export default function StoriesCard({ stories, isOwner }: Props) {
</Button>}
</div>
}
</div>
</Card>
)
}

View File

@@ -24,7 +24,7 @@ export default function HottestPage() {
<title>{`Hottest Lightning Products`}</title>
<meta property="og:title" content={`Hottest Lightning Products`} />
</Helmet>
<div className='px-32'>
<div className='page-container'>
<HeaderImage
isLoading={loading}
title={"Hottest Projects"}

View File

@@ -6,10 +6,12 @@ import App from './App';
if (process.env.REACT_APP_ENABLE_MOCKS) {
const { worker } = require('./mocks/browser')
worker.start({
onUnhandledRequest: 'bypass'
})
import('./mocks/browser')
.then(({ worker }) => {
worker.start({
onUnhandledRequest: 'bypass'
})
})
}

View File

@@ -6,7 +6,7 @@ export const user: User = {
email: "mtg0987654321@gmail.com",
avatar: "https://avatars.dicebear.com/api/bottts/Mtgmtg.svg",
bio: "Lorem asiop asklh kluiw wekjhl shkj kljhsva klu khsc klhlkbs mjklwqr kmlk sadlfui mewr qiumnk, asdjomi cskhsdf.",
name: "Mtg",
name: "123123124asdfsadfsa8d7fsadfasdf",
github: "MTG2000",
jobTitle: "Front-end Web Developer",
join_date: new Date(2021).toISOString(),

View File

@@ -62,6 +62,8 @@ export function lazyModal<T extends ComponentType<any>>
}
export function trimText(text: string | undefined | null, length: number) {
console.log(text);
if (!text) return '';
return text.slice(0, length) + (text.length > length ? "..." : "")
}