upgrade react-bootstrap
This commit is contained in:
		
							parent
							
								
									54d69489b9
								
							
						
					
					
						commit
						6407455def
					
				| @ -1,30 +1,30 @@ | |||||||
| import { Accordion } from 'react-bootstrap' | import Accordion from 'react-bootstrap/Accordion' | ||||||
|  | import AccordionContext from 'react-bootstrap/AccordionContext' | ||||||
|  | import { useAccordionButton } from 'react-bootstrap/AccordionButton' | ||||||
| import ArrowRight from '../svgs/arrow-right-s-fill.svg' | import ArrowRight from '../svgs/arrow-right-s-fill.svg' | ||||||
| import ArrowDown from '../svgs/arrow-down-s-fill.svg' | import ArrowDown from '../svgs/arrow-down-s-fill.svg' | ||||||
| import { useEffect, useState } from 'react' | import { useContext } from 'react' | ||||||
| 
 | 
 | ||||||
| export default function AccordianItem ({ header, body, headerColor = 'var(--theme-grey)', show }) { | function ContextAwareToggle ({ children, headerColor = 'var(--theme-grey)', eventKey }) { | ||||||
|   const [open, setOpen] = useState(show) |   const { activeEventKey } = useContext(AccordionContext) | ||||||
|  |   const decoratedOnClick = useAccordionButton(eventKey) | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   const isCurrentEventKey = activeEventKey === eventKey | ||||||
|     setOpen(show) |  | ||||||
|   }, []) |  | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Accordion |     <div style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }} onClick={decoratedOnClick}> | ||||||
|       defaultActiveKey={show ? '0' : undefined} |       {isCurrentEventKey | ||||||
|     > |  | ||||||
|       <Accordion.Toggle |  | ||||||
|         as={props => <div {...props} />} |  | ||||||
|         eventKey='0' |  | ||||||
|         style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }} |  | ||||||
|         onClick={() => setOpen(!open)} |  | ||||||
|       > |  | ||||||
|         {open |  | ||||||
|         ? <ArrowDown style={{ fill: headerColor }} height={20} width={20} /> |         ? <ArrowDown style={{ fill: headerColor }} height={20} width={20} /> | ||||||
|         : <ArrowRight style={{ fill: headerColor }} height={20} width={20} />} |         : <ArrowRight style={{ fill: headerColor }} height={20} width={20} />} | ||||||
|         <div style={{ color: headerColor }}>{header}</div> |       {children} | ||||||
|       </Accordion.Toggle> |     </div> | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default function AccordianItem ({ header, body, headerColor = 'var(--theme-grey)', show }) { | ||||||
|  |   return ( | ||||||
|  |     <Accordion defaultActiveKey={show ? '0' : undefined}> | ||||||
|  |       <ContextAwareToggle eventKey='0'><div style={{ color: headerColor }}>{header}</div></ContextAwareToggle> | ||||||
|       <Accordion.Collapse eventKey='0' className='mt-2'> |       <Accordion.Collapse eventKey='0' className='mt-2'> | ||||||
|         <div>{body}</div> |         <div>{body}</div> | ||||||
|       </Accordion.Collapse> |       </Accordion.Collapse> | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| import { useFormikContext } from 'formik' | import { useFormikContext } from 'formik' | ||||||
| import { OverlayTrigger, Tooltip } from 'react-bootstrap' | import OverlayTrigger from 'react-bootstrap/OverlayTrigger' | ||||||
|  | import Tooltip from 'react-bootstrap/Tooltip' | ||||||
| 
 | 
 | ||||||
| export default function ActionTooltip ({ children, notForm, disable, overlayText, placement }) { | export default function ActionTooltip ({ children, notForm, disable, overlayText, placement }) { | ||||||
|   // if we're in a form, we want to hide tooltip on submit
 |   // if we're in a form, we want to hide tooltip on submit
 | ||||||
| @ -21,7 +22,9 @@ export default function ActionTooltip ({ children, notForm, disable, overlayText | |||||||
|       trigger={['hover', 'focus']} |       trigger={['hover', 'focus']} | ||||||
|       show={formik?.isSubmitting ? false : undefined} |       show={formik?.isSubmitting ? false : undefined} | ||||||
|     > |     > | ||||||
|  |       <span> | ||||||
|         {children} |         {children} | ||||||
|  |       </span> | ||||||
|     </OverlayTrigger> |     </OverlayTrigger> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import AccordianItem from './accordian-item' | import AccordianItem from './accordian-item' | ||||||
| import { Input, InputUserSuggest } from './form' | import { Input, InputUserSuggest } from './form' | ||||||
| import { InputGroup } from 'react-bootstrap' | import InputGroup from 'react-bootstrap/InputGroup' | ||||||
| import { BOOST_MIN } from '../lib/constants' | import { BOOST_MIN } from '../lib/constants' | ||||||
| import Info from './info' | import Info from './info' | ||||||
| 
 | 
 | ||||||
| @ -21,7 +21,7 @@ export default function AdvPostForm ({ edit }) { | |||||||
|             label={ |             label={ | ||||||
|               <div className='d-flex align-items-center'>{edit ? 'add boost' : 'boost'} |               <div className='d-flex align-items-center'>{edit ? 'add boost' : 'boost'} | ||||||
|                 <Info> |                 <Info> | ||||||
|                   <ol className='font-weight-bold'> |                   <ol className='fw-bold'> | ||||||
|                     <li>Boost ranks posts higher temporarily based on the amount</li> |                     <li>Boost ranks posts higher temporarily based on the amount</li> | ||||||
|                     <li>The minimum boost is {BOOST_MIN} sats</li> |                     <li>The minimum boost is {BOOST_MIN} sats</li> | ||||||
|                     <li>Each {BOOST_MIN} sats of boost is equivalent to one trusted upvote |                     <li>Each {BOOST_MIN} sats of boost is equivalent to one trusted upvote | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { useRef, useState } from 'react' | import { useRef, useState } from 'react' | ||||||
| import AvatarEditor from 'react-avatar-editor' | import AvatarEditor from 'react-avatar-editor' | ||||||
| import { Button, Form as BootstrapForm } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
|  | import BootstrapForm from 'react-bootstrap/Form' | ||||||
| import Upload from './upload' | import Upload from './upload' | ||||||
| import EditImage from '../svgs/image-edit-fill.svg' | import EditImage from '../svgs/image-edit-fill.svg' | ||||||
| import Moon from '../svgs/moon-fill.svg' | import Moon from '../svgs/moon-fill.svg' | ||||||
| @ -28,7 +29,7 @@ export default function Avatar ({ onSuccess }) { | |||||||
|           <BootstrapForm.Control |           <BootstrapForm.Control | ||||||
|             type='range' onChange={e => setScale(parseFloat(e.target.value))} |             type='range' onChange={e => setScale(parseFloat(e.target.value))} | ||||||
|             min={1} max={2} step='0.05' |             min={1} max={2} step='0.05' | ||||||
|             defaultValue={scale} custom |             defaultValue={scale} | ||||||
|           /> |           /> | ||||||
|         </BootstrapForm.Group> |         </BootstrapForm.Group> | ||||||
|         <Button onClick={() => { |         <Button onClick={() => { | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import { useMutation } from '@apollo/client' | import { useMutation } from '@apollo/client' | ||||||
| import { gql } from 'graphql-tag' | import { gql } from 'graphql-tag' | ||||||
| import { Dropdown } from 'react-bootstrap' | import Dropdown from 'react-bootstrap/Dropdown' | ||||||
| 
 | 
 | ||||||
| export default function BookmarkDropdownItem ({ item: { id, meBookmark } }) { | export default function BookmarkDropdownItem ({ item: { id, meBookmark } }) { | ||||||
|   const [bookmarkItem] = useMutation( |   const [bookmarkItem] = useMutation( | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ import { gql, useApolloClient, useMutation } from '@apollo/client' | |||||||
| import Countdown from './countdown' | import Countdown from './countdown' | ||||||
| import AdvPostForm, { AdvPostInitial } from './adv-post-form' | import AdvPostForm, { AdvPostInitial } from './adv-post-form' | ||||||
| import FeeButton, { EditFeeButton } from './fee-button' | import FeeButton, { EditFeeButton } from './fee-button' | ||||||
| import { InputGroup } from 'react-bootstrap' | import InputGroup from 'react-bootstrap/InputGroup' | ||||||
| import { bountySchema } from '../lib/validate' | import { bountySchema } from '../lib/validate' | ||||||
| import { SubSelectInitial } from './sub-select-form' | import { SubSelectInitial } from './sub-select-form' | ||||||
| import CancelButton from './cancel-button' | import CancelButton from './cancel-button' | ||||||
| @ -95,7 +95,7 @@ export function BountyForm ({ | |||||||
|         topLevel |         topLevel | ||||||
|         label={ |         label={ | ||||||
|           <> |           <> | ||||||
|             {textLabel} <small className='text-muted ml-2'>optional</small> |             {textLabel} <small className='text-muted ms-2'>optional</small> | ||||||
|           </> |           </> | ||||||
|         } |         } | ||||||
|         name='text' |         name='text' | ||||||
| @ -103,7 +103,7 @@ export function BountyForm ({ | |||||||
|         hint={ |         hint={ | ||||||
|           editThreshold |           editThreshold | ||||||
|             ? ( |             ? ( | ||||||
|               <div className='text-muted font-weight-bold'> |               <div className='text-muted fw-bold'> | ||||||
|                 <Countdown date={editThreshold} /> |                 <Countdown date={editThreshold} /> | ||||||
|               </div> |               </div> | ||||||
|               ) |               ) | ||||||
|  | |||||||
| @ -1,9 +1,9 @@ | |||||||
| import { useRouter } from 'next/router' | import { useRouter } from 'next/router' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| 
 | 
 | ||||||
| export default function CancelButton ({ onClick }) { | export default function CancelButton ({ onClick }) { | ||||||
|   const router = useRouter() |   const router = useRouter() | ||||||
|   return ( |   return ( | ||||||
|     <Button className='mr-3 text-muted nav-link font-weight-bold' variant='link' onClick={onClick || (() => router.back())}>cancel</Button> |     <Button className='me-3 text-muted nav-link fw-bold' variant='link' onClick={onClick || (() => router.back())}>cancel</Button> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ import { Form, MarkdownInput, SubmitButton } from '../components/form' | |||||||
| import { gql, useMutation } from '@apollo/client' | import { gql, useMutation } from '@apollo/client' | ||||||
| import styles from './reply.module.css' | import styles from './reply.module.css' | ||||||
| import { EditFeeButton } from './fee-button' | import { EditFeeButton } from './fee-button' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import Delete from './delete' | import Delete from './delete' | ||||||
| import { commentSchema } from '../lib/validate' | import { commentSchema } from '../lib/validate' | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ import Flag from '../svgs/flag-fill.svg' | |||||||
| import { abbrNum } from '../lib/format' | import { abbrNum } from '../lib/format' | ||||||
| import Share from './share' | import Share from './share' | ||||||
| import ItemInfo from './item-info' | import ItemInfo from './item-info' | ||||||
| import { Badge } from 'react-bootstrap' | import Badge from 'react-bootstrap/Badge' | ||||||
| import { RootProvider, useRoot } from './root' | import { RootProvider, useRoot } from './root' | ||||||
| import { useMe } from './me' | import { useMe } from './me' | ||||||
| 
 | 
 | ||||||
| @ -43,7 +43,7 @@ function Parent ({ item, rootText }) { | |||||||
|       </Link> |       </Link> | ||||||
|       {root.subName && |       {root.subName && | ||||||
|         <Link href={`/~${root.subName}`}> |         <Link href={`/~${root.subName}`}> | ||||||
|           {' '}<Badge className={itemStyles.newComment} variant={null}>{root.subName}</Badge> |           {' '}<Badge className={itemStyles.newComment} bg={null}>{root.subName}</Badge> | ||||||
|         </Link>} |         </Link>} | ||||||
|     </> |     </> | ||||||
|   ) |   ) | ||||||
| @ -143,7 +143,7 @@ export default function Comment ({ | |||||||
|               pendingSats={pendingSats} |               pendingSats={pendingSats} | ||||||
|               commentsText='replies' |               commentsText='replies' | ||||||
|               className={`${itemStyles.other} ${styles.other}`} |               className={`${itemStyles.other} ${styles.other}`} | ||||||
|               embellishUser={op && <span className='text-boost font-weight-bold ml-1'>OP</span>} |               embellishUser={op && <Badge bg='boost' className={`ms-1 ${styles.op} bg-opacity-75`}>OP</Badge>} | ||||||
|               extraInfo={ |               extraInfo={ | ||||||
|                 <> |                 <> | ||||||
|                   {includeParent && <Parent item={item} rootText={rootText} />} |                   {includeParent && <Parent item={item} rootText={rootText} />} | ||||||
| @ -170,7 +170,7 @@ export default function Comment ({ | |||||||
|                   }} |                   }} | ||||||
|                 />)} |                 />)} | ||||||
|             {topLevel && ( |             {topLevel && ( | ||||||
|               <span className='d-flex ml-auto align-items-center'> |               <span className='d-flex ms-auto align-items-center'> | ||||||
|                 <Share item={item} /> |                 <Share item={item} /> | ||||||
|               </span> |               </span> | ||||||
|             )} |             )} | ||||||
| @ -203,7 +203,7 @@ export default function Comment ({ | |||||||
|                   {root.bounty && !bountyPaid && <PayBounty item={item} />} |                   {root.bounty && !bountyPaid && <PayBounty item={item} />} | ||||||
|                 </Reply>} |                 </Reply>} | ||||||
|               {children} |               {children} | ||||||
|               <div className={`${styles.comments} ml-sm-1 ml-md-3`}> |               <div className={`${styles.comments} ms-sm-1 ms-md-3`}> | ||||||
|                 {item.comments && !noComments |                 {item.comments && !noComments | ||||||
|                   ? item.comments.map((item) => ( |                   ? item.comments.map((item) => ( | ||||||
|                     <Comment depth={depth + 1} key={item.id} item={item} /> |                     <Comment depth={depth + 1} key={item.id} item={item} /> | ||||||
| @ -220,7 +220,7 @@ export default function Comment ({ | |||||||
| function DepthLimit ({ item }) { | function DepthLimit ({ item }) { | ||||||
|   if (item.ncomments > 0) { |   if (item.ncomments > 0) { | ||||||
|     return ( |     return ( | ||||||
|       <Link href={`/items/${item.id}`} className='d-block p-3 font-weight-bold text-muted w-100 text-center'> |       <Link href={`/items/${item.id}`} className='d-block p-3 fw-bold text-muted w-100 text-center'> | ||||||
|         view replies |         view replies | ||||||
|       </Link> |       </Link> | ||||||
|     ) |     ) | ||||||
| @ -252,7 +252,7 @@ export function CommentSkeleton ({ skeletonChildren }) { | |||||||
|         <div className={styles.replyPadder}> |         <div className={styles.replyPadder}> | ||||||
|           <div className={`${itemStyles.other} ${styles.reply} clouds`} /> |           <div className={`${itemStyles.other} ${styles.reply} clouds`} /> | ||||||
|         </div> |         </div> | ||||||
|         <div className={`${styles.comments} ml-sm-1 ml-md-3`}> |         <div className={`${styles.comments} ms-sm-1 ms-md-3`}> | ||||||
|           {skeletonChildren |           {skeletonChildren | ||||||
|             ? <CommentSkeleton skeletonChildren={skeletonChildren - 1} /> |             ? <CommentSkeleton skeletonChildren={skeletonChildren - 1} /> | ||||||
|             : null} |             : null} | ||||||
|  | |||||||
| @ -26,6 +26,11 @@ | |||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .op { | ||||||
|  |     margin-top: -1px; | ||||||
|  |     vertical-align: text-top; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .collapsed .hunk { | .collapsed .hunk { | ||||||
|     margin-bottom: .5rem; |     margin-bottom: .5rem; | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,7 +2,8 @@ import { gql, useApolloClient, useLazyQuery } from '@apollo/client' | |||||||
| import { useState } from 'react' | import { useState } from 'react' | ||||||
| import Comment, { CommentSkeleton } from './comment' | import Comment, { CommentSkeleton } from './comment' | ||||||
| import styles from './header.module.css' | import styles from './header.module.css' | ||||||
| import { Nav, Navbar } from 'react-bootstrap' | import Nav from 'react-bootstrap/Nav' | ||||||
|  | import Navbar from 'react-bootstrap/Navbar' | ||||||
| import { COMMENTS_QUERY } from '../fragments/items' | import { COMMENTS_QUERY } from '../fragments/items' | ||||||
| import { COMMENTS } from '../fragments/comments' | import { COMMENTS } from '../fragments/comments' | ||||||
| import { abbrNum } from '../lib/format' | import { abbrNum } from '../lib/format' | ||||||
| @ -19,7 +20,7 @@ export function CommentsHeader ({ handleSort, pinned, bio, parentCreatedAt, comm | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Navbar className='pt-1 pb-0'> |     <Navbar className='pt-1 pb-0 px-3'> | ||||||
|       <Nav |       <Nav | ||||||
|         className={styles.navbarNav} |         className={styles.navbarNav} | ||||||
|         activeKey={sort} |         activeKey={sort} | ||||||
| @ -27,7 +28,7 @@ export function CommentsHeader ({ handleSort, pinned, bio, parentCreatedAt, comm | |||||||
|         <Nav.Item className='text-muted'> |         <Nav.Item className='text-muted'> | ||||||
|           {abbrNum(commentSats)} sats |           {abbrNum(commentSats)} sats | ||||||
|         </Nav.Item> |         </Nav.Item> | ||||||
|         <div className='ml-auto d-flex'> |         <div className='ms-auto d-flex'> | ||||||
|           <Nav.Item> |           <Nav.Item> | ||||||
|             <Nav.Link |             <Nav.Link | ||||||
|               eventKey='hot' |               eventKey='hot' | ||||||
|  | |||||||
| @ -1,7 +1,9 @@ | |||||||
| import { Badge, OverlayTrigger, Tooltip } from 'react-bootstrap' | import Badge from 'react-bootstrap/Badge' | ||||||
|  | import OverlayTrigger from 'react-bootstrap/OverlayTrigger' | ||||||
|  | import Tooltip from 'react-bootstrap/Tooltip' | ||||||
| import CowboyHatIcon from '../svgs/cowboy.svg' | import CowboyHatIcon from '../svgs/cowboy.svg' | ||||||
| 
 | 
 | ||||||
| export default function CowboyHat ({ user, badge, className = 'ml-1', height = 16, width = 16 }) { | export default function CowboyHat ({ user, badge, className = 'ms-1', height = 16, width = 16 }) { | ||||||
|   if (user?.streak === null || user.hideCowboyHat) { |   if (user?.streak === null || user.hideCowboyHat) { | ||||||
|     return null |     return null | ||||||
|   } |   } | ||||||
| @ -11,11 +13,11 @@ export default function CowboyHat ({ user, badge, className = 'ml-1', height = 1 | |||||||
|     <HatTooltip overlayText={streak ? `${streak} days` : 'new'}> |     <HatTooltip overlayText={streak ? `${streak} days` : 'new'}> | ||||||
|       {badge |       {badge | ||||||
|         ? ( |         ? ( | ||||||
|           <Badge variant='grey-medium' className='ml-2 d-inline-flex align-items-center'> |           <Badge bg='grey-medium' className='ms-2 d-inline-flex align-items-center'> | ||||||
|             <CowboyHatIcon className={className} height={height} width={width} /> |             <CowboyHatIcon className={className} height={height} width={width} /> | ||||||
|             <span className='ml-1'>{streak || 'new'}</span> |             <span className='ms-1 text-dark'>{streak || 'new'}</span> | ||||||
|           </Badge>) |           </Badge>) | ||||||
|         : <CowboyHatIcon className={className} height={height} width={width} />} |         : <span><CowboyHatIcon className={className} height={height} width={width} /></span>} | ||||||
|     </HatTooltip> |     </HatTooltip> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,7 +1,9 @@ | |||||||
| import { useMutation } from '@apollo/client' | import { useMutation } from '@apollo/client' | ||||||
| import { gql } from 'graphql-tag' | import { gql } from 'graphql-tag' | ||||||
| import { useState } from 'react' | import { useState } from 'react' | ||||||
| import { Alert, Button, Dropdown } from 'react-bootstrap' | import Alert from 'react-bootstrap/Alert' | ||||||
|  | import Button from 'react-bootstrap/Button' | ||||||
|  | import Dropdown from 'react-bootstrap/Dropdown' | ||||||
| import { useShowModal } from './modal' | import { useShowModal } from './modal' | ||||||
| 
 | 
 | ||||||
| export default function Delete ({ itemId, children, onDelete }) { | export default function Delete ({ itemId, children, onDelete }) { | ||||||
| @ -63,7 +65,7 @@ function DeleteConfirm ({ onConfirm }) { | |||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       {error && <Alert variant='danger' onClose={() => setError(undefined)} dismissible>{error}</Alert>} |       {error && <Alert variant='danger' onClose={() => setError(undefined)} dismissible>{error}</Alert>} | ||||||
|       <p className='font-weight-bolder'>Are you sure? This is a gone forever kind of delete.</p> |       <p className='fw-bolder'>Are you sure? This is a gone forever kind of delete.</p> | ||||||
|       <div className='d-flex justify-content-end'> |       <div className='d-flex justify-content-end'> | ||||||
|         <Button |         <Button | ||||||
|           variant='danger' onClick={async () => { |           variant='danger' onClick={async () => { | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ import { ITEM_FIELDS } from '../fragments/items' | |||||||
| import AccordianItem from './accordian-item' | import AccordianItem from './accordian-item' | ||||||
| import Item from './item' | import Item from './item' | ||||||
| import Delete from './delete' | import Delete from './delete' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import { discussionSchema } from '../lib/validate' | import { discussionSchema } from '../lib/validate' | ||||||
| import { SubSelectInitial } from './sub-select-form' | import { SubSelectInitial } from './sub-select-form' | ||||||
| import CancelButton from './cancel-button' | import CancelButton from './cancel-button' | ||||||
| @ -91,11 +91,11 @@ export function DiscussionForm ({ | |||||||
|       /> |       /> | ||||||
|       <MarkdownInput |       <MarkdownInput | ||||||
|         topLevel |         topLevel | ||||||
|         label={<>{textLabel} <small className='text-muted ml-2'>optional</small></>} |         label={<>{textLabel} <small className='text-muted ms-2'>optional</small></>} | ||||||
|         name='text' |         name='text' | ||||||
|         minRows={6} |         minRows={6} | ||||||
|         hint={editThreshold |         hint={editThreshold | ||||||
|           ? <div className='text-muted font-weight-bold'><Countdown date={editThreshold} /></div> |           ? <div className='text-muted fw-bold'><Countdown date={editThreshold} /></div> | ||||||
|           : null} |           : null} | ||||||
|       /> |       /> | ||||||
|       <AdvPostForm edit={!!item} /> |       <AdvPostForm edit={!!item} /> | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { gql, useMutation } from '@apollo/client' | import { gql, useMutation } from '@apollo/client' | ||||||
| import { Dropdown } from 'react-bootstrap' | import Dropdown from 'react-bootstrap/Dropdown' | ||||||
| import FundError from './fund-error' | import FundError from './fund-error' | ||||||
| import { useShowModal } from './modal' | import { useShowModal } from './modal' | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Table } from 'react-bootstrap' | import Table from 'react-bootstrap/Table' | ||||||
| import ActionTooltip from './action-tooltip' | import ActionTooltip from './action-tooltip' | ||||||
| import Info from './info' | import Info from './info' | ||||||
| import styles from './fee-button.module.css' | import styles from './fee-button.module.css' | ||||||
| @ -31,7 +31,7 @@ function Receipt ({ cost, repetition, hasImgLink, baseFee, parentId, boost }) { | |||||||
|       </tbody> |       </tbody> | ||||||
|       <tfoot> |       <tfoot> | ||||||
|         <tr> |         <tr> | ||||||
|           <td className='font-weight-bold'>{cost} sats</td> |           <td className='fw-bold'>{cost} sats</td> | ||||||
|           <td align='right' className='font-weight-light'>total fee</td> |           <td align='right' className='font-weight-light'>total fee</td> | ||||||
|         </tr> |         </tr> | ||||||
|       </tfoot> |       </tfoot> | ||||||
| @ -90,7 +90,7 @@ function EditReceipt ({ cost, paidSats, addImgLink, boost, parentId }) { | |||||||
|       </tbody> |       </tbody> | ||||||
|       <tfoot> |       <tfoot> | ||||||
|         <tr> |         <tr> | ||||||
|           <td className='font-weight-bold'>{cost} sats</td> |           <td className='fw-bold'>{cost} sats</td> | ||||||
|           <td align='right' className='font-weight-light'>total fee</td> |           <td align='right' className='font-weight-light'>total fee</td> | ||||||
|         </tr> |         </tr> | ||||||
|       </tfoot> |       </tfoot> | ||||||
|  | |||||||
| @ -1,4 +1,6 @@ | |||||||
| import { Container, OverlayTrigger, Popover } from 'react-bootstrap' | import Container from 'react-bootstrap/Container' | ||||||
|  | import OverlayTrigger from 'react-bootstrap/OverlayTrigger' | ||||||
|  | import Popover from 'react-bootstrap/Popover' | ||||||
| import { CopyInput } from './form' | import { CopyInput } from './form' | ||||||
| import styles from './footer.module.css' | import styles from './footer.module.css' | ||||||
| import Texas from '../svgs/texas.svg' | import Texas from '../svgs/texas.svg' | ||||||
| @ -15,7 +17,7 @@ import useDarkMode from './dark-mode' | |||||||
| 
 | 
 | ||||||
| const RssPopover = ( | const RssPopover = ( | ||||||
|   <Popover> |   <Popover> | ||||||
|     <Popover.Content style={{ fontWeight: 500, fontSize: '.9rem' }}> |     <Popover.Body style={{ fontWeight: 500, fontSize: '.9rem' }}> | ||||||
|       <div className='d-flex justify-content-center'> |       <div className='d-flex justify-content-center'> | ||||||
|         <a href='/rss' className='nav-link p-0 d-inline-flex'> |         <a href='/rss' className='nav-link p-0 d-inline-flex'> | ||||||
|           home |           home | ||||||
| @ -38,13 +40,13 @@ const RssPopover = ( | |||||||
|           jobs |           jobs | ||||||
|         </a> |         </a> | ||||||
|       </div> |       </div> | ||||||
|     </Popover.Content> |     </Popover.Body> | ||||||
|   </Popover> |   </Popover> | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const SocialsPopover = ( | const SocialsPopover = ( | ||||||
|   <Popover> |   <Popover> | ||||||
|     <Popover.Content style={{ fontWeight: 500, fontSize: '.9rem' }}> |     <Popover.Body style={{ fontWeight: 500, fontSize: '.9rem' }}> | ||||||
|       <a |       <a | ||||||
|         href='https://snort.social/p/npub1jfujw6llhq7wuvu5detycdsq5v5yqf56sgrdq8wlgrryx2a2p09svwm0gx' className='nav-link p-0 d-inline-flex' |         href='https://snort.social/p/npub1jfujw6llhq7wuvu5detycdsq5v5yqf56sgrdq8wlgrryx2a2p09svwm0gx' className='nav-link p-0 d-inline-flex' | ||||||
|         target='_blank' rel='noreferrer' |         target='_blank' rel='noreferrer' | ||||||
| @ -72,13 +74,13 @@ const SocialsPopover = ( | |||||||
|       > |       > | ||||||
|         pod |         pod | ||||||
|       </a> |       </a> | ||||||
|     </Popover.Content> |     </Popover.Body> | ||||||
|   </Popover> |   </Popover> | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ChatPopover = ( | const ChatPopover = ( | ||||||
|   <Popover> |   <Popover> | ||||||
|     <Popover.Content style={{ fontWeight: 500, fontSize: '.9rem' }}> |     <Popover.Body style={{ fontWeight: 500, fontSize: '.9rem' }}> | ||||||
|       <a |       <a | ||||||
|         href='https://tribes.sphinx.chat/t/stackerzchat' className='nav-link p-0 d-inline-flex' |         href='https://tribes.sphinx.chat/t/stackerzchat' className='nav-link p-0 d-inline-flex' | ||||||
|         target='_blank' rel='noreferrer' |         target='_blank' rel='noreferrer' | ||||||
| @ -99,13 +101,13 @@ const ChatPopover = ( | |||||||
|       > |       > | ||||||
|         simplex |         simplex | ||||||
|       </a> |       </a> | ||||||
|     </Popover.Content> |     </Popover.Body> | ||||||
|   </Popover> |   </Popover> | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const AnalyticsPopover = ( | const AnalyticsPopover = ( | ||||||
|   <Popover> |   <Popover> | ||||||
|     <Popover.Content style={{ fontWeight: 500, fontSize: '.9rem' }}> |     <Popover.Body style={{ fontWeight: 500, fontSize: '.9rem' }}> | ||||||
|       <a |       <a | ||||||
|         href='https://plausible.io/stacker.news' className='nav-link p-0 d-inline-flex' |         href='https://plausible.io/stacker.news' className='nav-link p-0 d-inline-flex' | ||||||
|         target='_blank' rel='noreferrer' |         target='_blank' rel='noreferrer' | ||||||
| @ -116,7 +118,7 @@ const AnalyticsPopover = ( | |||||||
|       <Link href='/stackers/day' className='nav-link p-0 d-inline-flex'> |       <Link href='/stackers/day' className='nav-link p-0 d-inline-flex'> | ||||||
|         stackers |         stackers | ||||||
|       </Link> |       </Link> | ||||||
|     </Popover.Content> |     </Popover.Body> | ||||||
|   </Popover> |   </Popover> | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -151,7 +153,7 @@ export default function Footer ({ links = true }) { | |||||||
|           <> |           <> | ||||||
|             <div className='mb-1'> |             <div className='mb-1'> | ||||||
|               <DarkModeIcon onClick={darkModeToggle} width={20} height={20} className='fill-grey theme' suppressHydrationWarning /> |               <DarkModeIcon onClick={darkModeToggle} width={20} height={20} className='fill-grey theme' suppressHydrationWarning /> | ||||||
|               <LnIcon onClick={toggleLightning} width={20} height={20} className='ml-2 fill-grey theme' suppressHydrationWarning /> |               <LnIcon onClick={toggleLightning} width={20} height={20} className='ms-2 fill-grey theme' suppressHydrationWarning /> | ||||||
|             </div> |             </div> | ||||||
|             <div className='mb-0' style={{ fontWeight: 500 }}> |             <div className='mb-0' style={{ fontWeight: 500 }}> | ||||||
|               <Rewards /> |               <Rewards /> | ||||||
| @ -207,7 +209,7 @@ export default function Footer ({ links = true }) { | |||||||
|           <div |           <div | ||||||
|             className={`text-small mx-auto mb-2 ${styles.connect}`} |             className={`text-small mx-auto mb-2 ${styles.connect}`} | ||||||
|           > |           > | ||||||
|             <span className='nav-item text-muted mr-2'>connect:</span> |             <span className='nav-item text-muted me-2'>connect:</span> | ||||||
|             <CopyInput |             <CopyInput | ||||||
|               size='sm' |               size='sm' | ||||||
|               groupClassName='mb-0 w-100' |               groupClassName='mb-0 w-100' | ||||||
| @ -219,23 +221,23 @@ export default function Footer ({ links = true }) { | |||||||
|               href='https://amboss.space/node/03cc1d0932bb99b0697f5b5e5961b83ab7fd66f1efc4c9f5c7bad66c1bcbe78f02' |               href='https://amboss.space/node/03cc1d0932bb99b0697f5b5e5961b83ab7fd66f1efc4c9f5c7bad66c1bcbe78f02' | ||||||
|               target='_blank' rel='noreferrer' |               target='_blank' rel='noreferrer' | ||||||
|             > |             > | ||||||
|               <Amboss className='ml-2 theme' width={20} height={20} /> |               <Amboss className='ms-2 theme' width={20} height={20} /> | ||||||
|             </a> |             </a> | ||||||
|           </div>} |           </div>} | ||||||
|         <small className='d-flex justify-content-center align-items-center text-muted flex-wrap'> |         <small className='d-flex justify-content-center align-items-center text-muted flex-wrap'> | ||||||
|           <a className={`${styles.contrastLink} d-flex align-items-center`} href='https://github.com/stackernews/stacker.news' target='_blank' rel='noreferrer'> |           <a className={`${styles.contrastLink} d-flex align-items-center`} href='https://github.com/stackernews/stacker.news' target='_blank' rel='noreferrer'> | ||||||
|             FOSS <Github width={20} height={20} className='mx-1' /> |             FOSS <Github width={20} height={20} className='mx-1' /> | ||||||
|           </a> |           </a> | ||||||
|           made in Austin<Texas className='ml-1' width={20} height={20} /> |           made in Austin<Texas className='ms-1' width={20} height={20} /> | ||||||
|           <span className='ml-1'>by</span> |           <span className='ms-1'>by</span> | ||||||
|           <span> |           <span> | ||||||
|             <Link href='/k00b' className='ml-1'> |             <Link href='/k00b' className='ms-1'> | ||||||
|               @k00b |               @k00b | ||||||
|             </Link> |             </Link> | ||||||
|             <Link href='/kr' className='ml-1'> |             <Link href='/kr' className='ms-1'> | ||||||
|               @kr |               @kr | ||||||
|             </Link> |             </Link> | ||||||
|             <Link href='/ekzyis' className='ml-1'> |             <Link href='/ekzyis' className='ms-1'> | ||||||
|               @ekzyis |               @ekzyis | ||||||
|             </Link> |             </Link> | ||||||
|           </span> |           </span> | ||||||
|  | |||||||
| @ -6,7 +6,10 @@ import { Formik, Form as FormikForm, useFormikContext, useField, FieldArray } fr | |||||||
| import React, { createContext, useContext, useEffect, useRef, useState } from 'react' | import React, { createContext, useContext, useEffect, useRef, useState } from 'react' | ||||||
| import copy from 'clipboard-copy' | import copy from 'clipboard-copy' | ||||||
| import Thumb from '../svgs/thumb-up-fill.svg' | import Thumb from '../svgs/thumb-up-fill.svg' | ||||||
| import { Col, Dropdown as BootstrapDropdown, Nav } from 'react-bootstrap' | import Col from 'react-bootstrap/Col' | ||||||
|  | import Dropdown from 'react-bootstrap/Dropdown' | ||||||
|  | import Nav from 'react-bootstrap/Nav' | ||||||
|  | import Row from 'react-bootstrap/Row' | ||||||
| import Markdown from '../svgs/markdown-line.svg' | import Markdown from '../svgs/markdown-line.svg' | ||||||
| import styles from './form.module.css' | import styles from './form.module.css' | ||||||
| import Text from '../components/text' | import Text from '../components/text' | ||||||
| @ -53,6 +56,7 @@ export function CopyInput (props) { | |||||||
|       onClick={handleClick} |       onClick={handleClick} | ||||||
|       append={ |       append={ | ||||||
|         <Button |         <Button | ||||||
|  |           className={styles.appendButton} | ||||||
|           size={props.size} |           size={props.size} | ||||||
|           onClick={handleClick} |           onClick={handleClick} | ||||||
|         > |         > | ||||||
| @ -109,7 +113,7 @@ export function MarkdownInput ({ label, topLevel, groupClassName, onChange, setH | |||||||
|             <Nav.Link eventKey='preview' disabled={!meta.value}>preview</Nav.Link> |             <Nav.Link eventKey='preview' disabled={!meta.value}>preview</Nav.Link> | ||||||
|           </Nav.Item> |           </Nav.Item> | ||||||
|           <a |           <a | ||||||
|             className='ml-auto text-muted d-flex align-items-center' |             className='ms-auto text-muted d-flex align-items-center' | ||||||
|             href='https://guides.github.com/features/mastering-markdown/' target='_blank' rel='noreferrer' |             href='https://guides.github.com/features/mastering-markdown/' target='_blank' rel='noreferrer' | ||||||
|           > |           > | ||||||
|             <Markdown width={18} height={18} /> |             <Markdown width={18} height={18} /> | ||||||
| @ -206,7 +210,7 @@ const insertMarkdownItalicFormatting = insertMarkdownFormatting( | |||||||
| 
 | 
 | ||||||
| function FormGroup ({ className, label, children }) { | function FormGroup ({ className, label, children }) { | ||||||
|   return ( |   return ( | ||||||
|     <BootstrapForm.Group className={className}> |     <BootstrapForm.Group className={`form-group ${className}`}> | ||||||
|       {label && <BootstrapForm.Label>{label}</BootstrapForm.Label>} |       {label && <BootstrapForm.Label>{label}</BootstrapForm.Label>} | ||||||
|       {children} |       {children} | ||||||
|     </BootstrapForm.Group> |     </BootstrapForm.Group> | ||||||
| @ -244,11 +248,7 @@ function InputInner ({ | |||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       <InputGroup hasValidation> |       <InputGroup hasValidation> | ||||||
|         {prepend && ( |  | ||||||
|           <InputGroup.Prepend> |  | ||||||
|         {prepend} |         {prepend} | ||||||
|           </InputGroup.Prepend> |  | ||||||
|         )} |  | ||||||
|         <BootstrapForm.Control |         <BootstrapForm.Control | ||||||
|           onKeyDown={(e) => { |           onKeyDown={(e) => { | ||||||
|             const metaOrCtrl = e.metaKey || e.ctrlKey |             const metaOrCtrl = e.metaKey || e.ctrlKey | ||||||
| @ -274,8 +274,6 @@ function InputInner ({ | |||||||
|           isInvalid={invalid} |           isInvalid={invalid} | ||||||
|           isValid={showValid && meta.initialValue !== meta.value && meta.touched && !meta.error} |           isValid={showValid && meta.initialValue !== meta.value && meta.touched && !meta.error} | ||||||
|         /> |         /> | ||||||
|         {(append || (clear && field.value)) && ( |  | ||||||
|           <InputGroup.Append> |  | ||||||
|         {(clear && field.value) && |         {(clear && field.value) && | ||||||
|           <Button |           <Button | ||||||
|             variant={null} |             variant={null} | ||||||
| @ -288,12 +286,10 @@ function InputInner ({ | |||||||
|                 onChange(formik, { target: { value: '' } }) |                 onChange(formik, { target: { value: '' } }) | ||||||
|               } |               } | ||||||
|             }} |             }} | ||||||
|                 className={`${styles.clearButton} ${invalid ? styles.isInvalid : ''}`} |             className={`${styles.clearButton} ${styles.appendButton} ${invalid ? styles.isInvalid : ''}`} | ||||||
|           ><CloseIcon className='fill-grey' height={20} width={20} /> |           ><CloseIcon className='fill-grey' height={20} width={20} /> | ||||||
|           </Button>} |           </Button>} | ||||||
|         {append} |         {append} | ||||||
|           </InputGroup.Append> |  | ||||||
|         )} |  | ||||||
|         <BootstrapForm.Control.Feedback type='invalid'> |         <BootstrapForm.Control.Feedback type='invalid'> | ||||||
|           {meta.touched && meta.error} |           {meta.touched && meta.error} | ||||||
|         </BootstrapForm.Control.Feedback> |         </BootstrapForm.Control.Feedback> | ||||||
| @ -357,10 +353,10 @@ export function InputUserSuggest ({ label, groupClassName, ...props }) { | |||||||
|           } |           } | ||||||
|         }} |         }} | ||||||
|       /> |       /> | ||||||
|       <BootstrapDropdown show={suggestions.array.length > 0}> |       <Dropdown show={suggestions.array.length > 0}> | ||||||
|         <BootstrapDropdown.Menu className={styles.suggestionsMenu}> |         <Dropdown.Menu className={styles.suggestionsMenu}> | ||||||
|           {suggestions.array.map((v, i) => |           {suggestions.array.map((v, i) => | ||||||
|             <BootstrapDropdown.Item |             <Dropdown.Item | ||||||
|               key={v.name} |               key={v.name} | ||||||
|               active={suggestions.index === i} |               active={suggestions.index === i} | ||||||
|               onClick={() => { |               onClick={() => { | ||||||
| @ -369,9 +365,9 @@ export function InputUserSuggest ({ label, groupClassName, ...props }) { | |||||||
|               }} |               }} | ||||||
|             > |             > | ||||||
|               {v.name} |               {v.name} | ||||||
|             </BootstrapDropdown.Item>)} |             </Dropdown.Item>)} | ||||||
|         </BootstrapDropdown.Menu> |         </Dropdown.Menu> | ||||||
|       </BootstrapDropdown> |       </Dropdown> | ||||||
|     </FormGroup> |     </FormGroup> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| @ -394,14 +390,14 @@ export function VariableInput ({ label, groupClassName, name, hint, max, min, re | |||||||
|             <> |             <> | ||||||
|               {options?.map((_, i) => ( |               {options?.map((_, i) => ( | ||||||
|                 <div key={i}> |                 <div key={i}> | ||||||
|                   <BootstrapForm.Row className='mb-2'> |                   <Row className='mb-2'> | ||||||
|                     <Col> |                     <Col> | ||||||
|                       <InputInner name={`${name}[${i}]`} {...props} readOnly={i < readOnlyLen} placeholder={i >= min ? 'optional' : undefined} /> |                       <InputInner name={`${name}[${i}]`} {...props} readOnly={i < readOnlyLen} placeholder={i >= min ? 'optional' : undefined} /> | ||||||
|                     </Col> |                     </Col> | ||||||
|                     {options.length - 1 === i && options.length !== max |                     {options.length - 1 === i && options.length !== max | ||||||
|                       ? <AddIcon className='fill-grey align-self-center pointer mx-2' onClick={() => fieldArrayHelpers.push('')} /> |                       ? <Col className='d-flex ps-0' xs='auto'><AddIcon className='fill-grey align-self-center justify-self-center pointer' onClick={() => fieldArrayHelpers.push('')} /></Col> | ||||||
|                       : null} |                       : null} | ||||||
|                   </BootstrapForm.Row> |                   </Row> | ||||||
|                 </div> |                 </div> | ||||||
|               ))} |               ))} | ||||||
|             </> |             </> | ||||||
| @ -423,10 +419,9 @@ export function Checkbox ({ children, label, groupClassName, hiddenLabel, extra, | |||||||
|   // return the correct bag of props for you
 |   // return the correct bag of props for you
 | ||||||
|   const [field,, helpers] = useField({ ...props, type: 'checkbox' }) |   const [field,, helpers] = useField({ ...props, type: 'checkbox' }) | ||||||
|   return ( |   return ( | ||||||
|     <BootstrapForm.Group className={groupClassName}> |     <FormGroup className={groupClassName}> | ||||||
|       {hiddenLabel && <BootstrapForm.Label className='invisible'>{label}</BootstrapForm.Label>} |       {hiddenLabel && <BootstrapForm.Label className='invisible'>{label}</BootstrapForm.Label>} | ||||||
|       <BootstrapForm.Check |       <BootstrapForm.Check | ||||||
|         custom |  | ||||||
|         id={props.id || props.name} |         id={props.id || props.name} | ||||||
|         inline={inline} |         inline={inline} | ||||||
|       > |       > | ||||||
| @ -444,7 +439,7 @@ export function Checkbox ({ children, label, groupClassName, hiddenLabel, extra, | |||||||
|             </div>} |             </div>} | ||||||
|         </BootstrapForm.Check.Label> |         </BootstrapForm.Check.Label> | ||||||
|       </BootstrapForm.Check> |       </BootstrapForm.Check> | ||||||
|     </BootstrapForm.Group> |     </FormGroup> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -497,8 +492,7 @@ export function Select ({ label, items, groupClassName, onChange, noForm, overri | |||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <FormGroup label={label} className={groupClassName}> |     <FormGroup label={label} className={groupClassName}> | ||||||
|       <BootstrapForm.Control |       <BootstrapForm.Select | ||||||
|         as='select' |  | ||||||
|         {...field} {...props} |         {...field} {...props} | ||||||
|         onChange={(e) => { |         onChange={(e) => { | ||||||
|           if (field?.onChange) { |           if (field?.onChange) { | ||||||
| @ -509,11 +503,10 @@ export function Select ({ label, items, groupClassName, onChange, noForm, overri | |||||||
|             onChange(formik, e) |             onChange(formik, e) | ||||||
|           } |           } | ||||||
|         }} |         }} | ||||||
|         custom |  | ||||||
|         isInvalid={invalid} |         isInvalid={invalid} | ||||||
|       > |       > | ||||||
|         {items.map(item => <option key={item}>{item}</option>)} |         {items.map(item => <option key={item}>{item}</option>)} | ||||||
|       </BootstrapForm.Control> |       </BootstrapForm.Select> | ||||||
|       <BootstrapForm.Control.Feedback type='invalid'> |       <BootstrapForm.Control.Feedback type='invalid'> | ||||||
|         {meta.touched && meta.error} |         {meta.touched && meta.error} | ||||||
|       </BootstrapForm.Control.Feedback> |       </BootstrapForm.Control.Feedback> | ||||||
|  | |||||||
| @ -19,15 +19,23 @@ | |||||||
|     height: auto; |     height: auto; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .appendButton { | ||||||
|  |     border-left: 0 !important; | ||||||
|  |     border-top-left-radius: 0; | ||||||
|  |     border-bottom-left-radius: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .clearButton { | .clearButton { | ||||||
|     background-color: var(--theme-inputBg); |     background-color: var(--theme-inputBg); | ||||||
|     border: 1px solid var(--theme-borderColor); |     border: 1px solid var(--theme-borderColor); | ||||||
|     padding: 0rem 0.5rem; |     padding: 0rem 0.5rem; | ||||||
|     border-left: 0; |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .clearButton:hover, .clearButton:active { | ||||||
|  |     background-color: var(--theme-inputBg) !important; | ||||||
|  |     border: 1px solid var(--theme-borderColor) !important; | ||||||
|  |     border-left: 0 !important; | ||||||
|  | } | ||||||
| .clearButton.isInvalid { | .clearButton.isInvalid { | ||||||
|     border-color: #c03221; |     border-color: #c03221; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,10 +1,10 @@ | |||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| 
 | 
 | ||||||
| export default function FundError ({ onClose }) { | export default function FundError ({ onClose }) { | ||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       <p className='font-weight-bolder'>you need more sats</p> |       <p className='fw-bolder'>you need more sats</p> | ||||||
|       <div className='d-flex justify-content-end'> |       <div className='d-flex justify-content-end'> | ||||||
|         <Link href='/wallet?type=fund'> |         <Link href='/wallet?type=fund'> | ||||||
|           <Button variant='success' onClick={onClose}>fund</Button> |           <Button variant='success' onClick={onClose}>fund</Button> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ import Nav from 'react-bootstrap/Nav' | |||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| import styles from './header.module.css' | import styles from './header.module.css' | ||||||
| import { useRouter } from 'next/router' | import { useRouter } from 'next/router' | ||||||
| import { Button, Container, NavDropdown } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
|  | import Container from 'react-bootstrap/Container' | ||||||
|  | import NavDropdown from 'react-bootstrap/NavDropdown' | ||||||
| import Price from './price' | import Price from './price' | ||||||
| import { useMe } from './me' | import { useMe } from './me' | ||||||
| import Head from 'next/head' | import Head from 'next/head' | ||||||
| @ -37,7 +39,7 @@ function Back () { | |||||||
|   }, [router.asPath]) |   }, [router.asPath]) | ||||||
| 
 | 
 | ||||||
|   if (show) { |   if (show) { | ||||||
|     return <a role='button' tabIndex='0' className='nav-link standalone p-0' onClick={() => router.back()}><BackArrow className='theme mr-1 mr-md-2' width={22} height={22} /></a> |     return <a role='button' tabIndex='0' className='nav-link standalone p-0' onClick={() => router.back()}><BackArrow className='theme me-1 me-md-2' width={22} height={22} /></a> | ||||||
|   } |   } | ||||||
|   return null |   return null | ||||||
| } | } | ||||||
| @ -54,8 +56,8 @@ function NotificationBell () { | |||||||
|         <link rel='shortcut icon' href={data?.hasNewNotes ? '/favicon-notify.png' : '/favicon.png'} /> |         <link rel='shortcut icon' href={data?.hasNewNotes ? '/favicon-notify.png' : '/favicon.png'} /> | ||||||
|       </Head> |       </Head> | ||||||
|       <Link href='/notifications' passHref legacyBehavior> |       <Link href='/notifications' passHref legacyBehavior> | ||||||
|         <Nav.Link eventKey='notifications' className='pl-0 position-relative'> |         <Nav.Link eventKey='notifications' className='ps-0 position-relative'> | ||||||
|           <NoteIcon height={22} width={22} className='theme' /> |           <NoteIcon height={22} width={22} className='theme' style={{ marginTop: '-4px' }} /> | ||||||
|           {data?.hasNewNotes && |           {data?.hasNewNotes && | ||||||
|             <span className={styles.notification}> |             <span className={styles.notification}> | ||||||
|               <span className='invisible'>{' '}</span> |               <span className='invisible'>{' '}</span> | ||||||
| @ -70,23 +72,23 @@ function StackerCorner ({ dropNavKey }) { | |||||||
|   const me = useMe() |   const me = useMe() | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex align-items-center ml-auto'> |     <div className='d-flex ms-auto'> | ||||||
|       <NotificationBell /> |       <NotificationBell /> | ||||||
|       <div className='position-relative'> |       <div className='position-relative'> | ||||||
|         <NavDropdown |         <NavDropdown | ||||||
|           className={styles.dropdown} |           className={styles.dropdown} | ||||||
|           title={ |           title={ | ||||||
|             <Nav.Link eventKey={me.name} as='span' className='p-0 d-flex align-items-center' onClick={e => e.preventDefault()}> |             <Nav.Link eventKey={me.name} as='span' className='p-0' onClick={e => e.preventDefault()}> | ||||||
|               {`@${me.name}`}<CowboyHat user={me} /> |               {`@${me.name}`}<CowboyHat user={me} /> | ||||||
|             </Nav.Link> |             </Nav.Link> | ||||||
|           } |           } | ||||||
|           alignRight |           align='end' | ||||||
|         > |         > | ||||||
|           <Link href={'/' + me.name} passHref legacyBehavior> |           <Link href={'/' + me.name} passHref legacyBehavior> | ||||||
|             <NavDropdown.Item active={me.name === dropNavKey}> |             <NavDropdown.Item active={me.name === dropNavKey}> | ||||||
|               profile |               profile | ||||||
|               {me && !me.bioId && |               {me && !me.bioId && | ||||||
|                 <div className='p-1 d-inline-block bg-secondary ml-1'> |                 <div className='p-1 d-inline-block bg-secondary ms-1'> | ||||||
|                   <span className='invisible'>{' '}</span> |                   <span className='invisible'>{' '}</span> | ||||||
|                 </div>} |                 </div>} | ||||||
|             </NavDropdown.Item> |             </NavDropdown.Item> | ||||||
| @ -147,9 +149,9 @@ function LurkerCorner ({ path }) { | |||||||
|   }), [router]) |   }), [router]) | ||||||
| 
 | 
 | ||||||
|   return path !== '/login' && path !== '/signup' && !path.startsWith('/invites') && |   return path !== '/login' && path !== '/signup' && !path.startsWith('/invites') && | ||||||
|     <div className='ml-auto'> |     <div className='ms-auto'> | ||||||
|       <Button |       <Button | ||||||
|         className='align-items-center px-3 py-1 mr-2' |         className='align-items-center px-3 py-1 me-2' | ||||||
|         id='signup' |         id='signup' | ||||||
|         style={{ borderWidth: '2px' }} |         style={{ borderWidth: '2px' }} | ||||||
|         variant='outline-grey-darkmode' |         variant='outline-grey-darkmode' | ||||||
| @ -158,7 +160,7 @@ function LurkerCorner ({ path }) { | |||||||
|         login |         login | ||||||
|       </Button> |       </Button> | ||||||
|       <Button |       <Button | ||||||
|         className='align-items-center pl-2 py-1 pr-3' |         className='align-items-center ps-2 py-1 pe-3' | ||||||
|         style={{ borderWidth: '2px' }} |         style={{ borderWidth: '2px' }} | ||||||
|         id='login' |         id='login' | ||||||
|         onClick={() => handleLogin('/signup')} |         onClick={() => handleLogin('/signup')} | ||||||
| @ -166,7 +168,7 @@ function LurkerCorner ({ path }) { | |||||||
|         <LightningIcon |         <LightningIcon | ||||||
|           width={17} |           width={17} | ||||||
|           height={17} |           height={17} | ||||||
|           className='mr-1' |           className='me-1' | ||||||
|         />sign up |         />sign up | ||||||
|       </Button> |       </Button> | ||||||
|     </div> |     </div> | ||||||
| @ -232,7 +234,7 @@ export default function Header ({ sub }) { | |||||||
|   const me = useMe() |   const me = useMe() | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Container as='header' className='px-0'> |     <Container as='header'> | ||||||
|       <Navbar className='pb-0 pb-lg-2'> |       <Navbar className='pb-0 pb-lg-2'> | ||||||
|         <Nav |         <Nav | ||||||
|           className={styles.navbarNav} |           className={styles.navbarNav} | ||||||
| @ -249,11 +251,11 @@ export default function Header ({ sub }) { | |||||||
|           <NavItems className='d-none d-lg-flex mx-2' prefix={prefix} sub={sub} /> |           <NavItems className='d-none d-lg-flex mx-2' prefix={prefix} sub={sub} /> | ||||||
|           <PostItem className='d-none d-lg-flex mx-2' prefix={prefix} /> |           <PostItem className='d-none d-lg-flex mx-2' prefix={prefix} /> | ||||||
|           <Link href={prefix + '/search'} passHref legacyBehavior> |           <Link href={prefix + '/search'} passHref legacyBehavior> | ||||||
|             <Nav.Link eventKey='search' className='position-relative d-none d-lg-flex align-items-center pr-0 ml-2'> |             <Nav.Link eventKey='search' className='position-relative d-none d-lg-flex align-items-center pe-0 ms-2'> | ||||||
|               <SearchIcon className='theme' width={22} height={22} /> |               <SearchIcon className='theme' width={22} height={22} /> | ||||||
|             </Nav.Link> |             </Nav.Link> | ||||||
|           </Link> |           </Link> | ||||||
|           <Nav.Item className={`${styles.price} ml-auto align-items-center ${me?.name.length > 10 ? 'd-none d-lg-flex' : ''}`}> |           <Nav.Item className={`${styles.price} ms-auto align-items-center ${me?.name.length > 10 ? 'd-none d-lg-flex' : ''}`}> | ||||||
|             <Price className='nav-link text-monospace' /> |             <Price className='nav-link text-monospace' /> | ||||||
|           </Nav.Item> |           </Nav.Item> | ||||||
|           {me ? <StackerCorner dropNavKey={dropNavKey} /> : <LurkerCorner path={path} />} |           {me ? <StackerCorner dropNavKey={dropNavKey} /> : <LurkerCorner path={path} />} | ||||||
| @ -264,13 +266,13 @@ export default function Header ({ sub }) { | |||||||
|           className={`${styles.navbarNav}`} |           className={`${styles.navbarNav}`} | ||||||
|           activeKey={topNavKey} |           activeKey={topNavKey} | ||||||
|         > |         > | ||||||
|           <NavItems className='mr-1' prefix={prefix} sub={sub} /> |           <NavItems className='me-1' prefix={prefix} sub={sub} /> | ||||||
|           <Link href={prefix + '/search'} passHref legacyBehavior> |           <Link href={prefix + '/search'} passHref legacyBehavior> | ||||||
|             <Nav.Link eventKey='search' className='position-relative ml-auto d-flex mr-1'> |             <Nav.Link eventKey='search' className='position-relative ms-auto d-flex me-1'> | ||||||
|               <SearchIcon className='theme' width={22} height={22} /> |               <SearchIcon className='theme' width={22} height={22} /> | ||||||
|             </Nav.Link> |             </Nav.Link> | ||||||
|           </Link> |           </Link> | ||||||
|           <PostItem className='mr-0 pr-0' prefix={prefix} /> |           <PostItem className='me-0' prefix={prefix} /> | ||||||
|         </Nav> |         </Nav> | ||||||
|       </Navbar> |       </Navbar> | ||||||
|     </Container> |     </Container> | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|     line-height: 100%; |     line-height: 100%; | ||||||
|     margin-bottom: -.3rem; |     margin-bottom: -.3rem; | ||||||
|     margin-right: 0; |     margin-right: 0; | ||||||
|     text-shadow: 0 0 10px var(--primary); |     text-shadow: 0 0 10px var(--bs-primary); | ||||||
|     color: var(--theme-brandColor) !important; |     color: var(--theme-brandColor) !important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -28,10 +28,14 @@ | |||||||
|     fill: var(--theme-navLinkActive); |     fill: var(--theme-navLinkActive); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .dropdown svg { | ||||||
|  |     vertical-align: text-top; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .jobIndicator { | .jobIndicator { | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     padding: .25rem; |     padding: .25rem; | ||||||
|     background-color: var(--primary); |     background-color: var(--bs-primary); | ||||||
|     top: 3px; |     top: 3px; | ||||||
|     right: 0px; |     right: 0px; | ||||||
|     border: 1px solid var(--theme-body); |     border: 1px solid var(--theme-body); | ||||||
| @ -40,8 +44,8 @@ | |||||||
| .notification { | .notification { | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     padding: .25rem; |     padding: .25rem; | ||||||
|     background-color: var(--danger); |     background-color: var(--bs-danger); | ||||||
|     top: 3px; |     top: 1px; | ||||||
|     right: 8px; |     right: 8px; | ||||||
|     border: 1px solid var(--theme-body); |     border: 1px solid var(--theme-body); | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ export default function Info ({ children, iconClassName = 'fill-theme-color' }) | |||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <InfoIcon |     <InfoIcon | ||||||
|       width={18} height={18} className={`${iconClassName} pointer ml-1`} |       width={18} height={18} className={`${iconClassName} pointer ms-1`} | ||||||
|       onClick={(e) => { |       onClick={(e) => { | ||||||
|         e.preventDefault() |         e.preventDefault() | ||||||
|         showModal(onClose => children) |         showModal(onClose => children) | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ function InvoiceDefaultStatus ({ status }) { | |||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex mt-2 justify-content-center'> |     <div className='d-flex mt-2 justify-content-center'> | ||||||
|       <Moon className='spin fill-grey' /> |       <Moon className='spin fill-grey' /> | ||||||
|       <div className='ml-3 text-muted' style={{ fontWeight: '600' }}>{status}</div> |       <div className='ms-3 text-muted' style={{ fontWeight: '600' }}>{status}</div> | ||||||
|     </div> |     </div> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| @ -15,7 +15,7 @@ function InvoiceConfirmedStatus ({ status }) { | |||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex mt-2 justify-content-center'> |     <div className='d-flex mt-2 justify-content-center'> | ||||||
|       <Check className='fill-success' /> |       <Check className='fill-success' /> | ||||||
|       <div className='ml-3 text-success' style={{ fontWeight: '600' }}>{status}</div> |       <div className='ms-3 text-success' style={{ fontWeight: '600' }}>{status}</div> | ||||||
|     </div> |     </div> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| @ -24,7 +24,7 @@ function InvoiceFailedStatus ({ status }) { | |||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex mt-2 justify-content-center'> |     <div className='d-flex mt-2 justify-content-center'> | ||||||
|       <ThumbDown className='fill-danger' /> |       <ThumbDown className='fill-danger' /> | ||||||
|       <div className='ml-3 text-danger' style={{ fontWeight: '600' }}>{status}</div> |       <div className='ms-3 text-danger' style={{ fontWeight: '600' }}>{status}</div> | ||||||
|     </div> |     </div> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| import { Button, InputGroup } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
|  | import InputGroup from 'react-bootstrap/InputGroup' | ||||||
| import React, { useState, useRef, useEffect } from 'react' | import React, { useState, useRef, useEffect } from 'react' | ||||||
| import { Form, Input, SubmitButton } from './form' | import { Form, Input, SubmitButton } from './form' | ||||||
| import { useMe } from './me' | import { useMe } from './me' | ||||||
| @ -12,12 +13,12 @@ const Tips = ({ setOValue }) => { | |||||||
|   return tips.map(num => |   return tips.map(num => | ||||||
|     <Button |     <Button | ||||||
|       size='sm' |       size='sm' | ||||||
|       className={`${num > 1 ? 'ml-2' : ''} mb-2`} |       className={`${num > 1 ? 'ms-2' : ''} mb-2`} | ||||||
|       key={num} |       key={num} | ||||||
|       onClick={() => { setOValue(num) }} |       onClick={() => { setOValue(num) }} | ||||||
|     > |     > | ||||||
|       <UpBolt |       <UpBolt | ||||||
|         className='mr-1' |         className='me-1' | ||||||
|         width={14} |         width={14} | ||||||
|         height={14} |         height={14} | ||||||
|       />{num} |       />{num} | ||||||
| @ -77,7 +78,7 @@ export default function ItemAct ({ onClose, itemId, act, strike }) { | |||||||
|         <Tips setOValue={setOValue} /> |         <Tips setOValue={setOValue} /> | ||||||
|       </div> |       </div> | ||||||
|       <div className='d-flex'> |       <div className='d-flex'> | ||||||
|         <SubmitButton variant='success' className='ml-auto mt-1 px-4' value='TIP'>zap</SubmitButton> |         <SubmitButton variant='success' className='ms-auto mt-1 px-4' value='TIP'>zap</SubmitButton> | ||||||
|       </div> |       </div> | ||||||
|     </Form> |     </Form> | ||||||
|   ) |   ) | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ import styles from '../styles/item.module.css' | |||||||
| import itemStyles from './item.module.css' | import itemStyles from './item.module.css' | ||||||
| import { NOFOLLOW_LIMIT } from '../lib/constants' | import { NOFOLLOW_LIMIT } from '../lib/constants' | ||||||
| import { useMe } from './me' | import { useMe } from './me' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import { TwitterTweetEmbed } from 'react-twitter-embed' | import { TwitterTweetEmbed } from 'react-twitter-embed' | ||||||
| import YouTube from 'react-youtube' | import YouTube from 'react-youtube' | ||||||
| import useDarkMode from './dark-mode' | import useDarkMode from './dark-mode' | ||||||
| @ -134,7 +134,7 @@ function TopLevelItem ({ item, noReply, ...props }) { | |||||||
|         {item.url && <ItemEmbed item={item} />} |         {item.url && <ItemEmbed item={item} />} | ||||||
|         {item.poll && <Poll item={item} />} |         {item.poll && <Poll item={item} />} | ||||||
|         {item.bounty && |         {item.bounty && | ||||||
|           <div className='font-weight-bold mt-2'> |           <div className='fw-bold mt-2'> | ||||||
|             {item.bountyPaidTo?.length |             {item.bountyPaidTo?.length | ||||||
|               ? ( |               ? ( | ||||||
|                 <div className='px-3 py-1 d-inline-block bg-grey-medium rounded text-success'> |                 <div className='px-3 py-1 d-inline-block bg-grey-medium rounded text-success'> | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| import { useRouter } from 'next/router' | import { useRouter } from 'next/router' | ||||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||||
| import { Badge, Dropdown } from 'react-bootstrap' | import Badge from 'react-bootstrap/Badge' | ||||||
|  | import Dropdown from 'react-bootstrap/Dropdown' | ||||||
| import Countdown from './countdown' | import Countdown from './countdown' | ||||||
| import { abbrNum } from '../lib/format' | import { abbrNum } from '../lib/format' | ||||||
| import { newComments } from '../lib/new-comments' | import { newComments } from '../lib/new-comments' | ||||||
| @ -43,12 +44,12 @@ export default function ItemInfo ({ item, pendingSats, full, commentsText, class | |||||||
|         </>} |         </>} | ||||||
|       <Link href={`/items/${item.id}`} title={`${item.commentSats} sats`} className='text-reset'> |       <Link href={`/items/${item.id}`} title={`${item.commentSats} sats`} className='text-reset'> | ||||||
|         {item.ncomments} {commentsText || 'comments'} |         {item.ncomments} {commentsText || 'comments'} | ||||||
|         {hasNewComments && <>{' '}<Badge className={styles.newComment} variant={null}>new</Badge></>} |         {hasNewComments && <>{' '}<Badge className={styles.newComment} bg={null}>new</Badge></>} | ||||||
|       </Link> |       </Link> | ||||||
|       <span> \ </span> |       <span> \ </span> | ||||||
|       <span> |       <span> | ||||||
|         <Link href={`/${item.user.name}`} className='d-inline-flex align-items-center'> |         <Link href={`/${item.user.name}`}> | ||||||
|           @{item.user.name}<CowboyHat className='ml-1 fill-grey' user={item.user} height={12} width={12} /> |           @{item.user.name}<CowboyHat className='ms-1 fill-grey' user={item.user} height={12} width={12} /> | ||||||
|           {embellishUser} |           {embellishUser} | ||||||
|         </Link> |         </Link> | ||||||
|         <span> </span> |         <span> </span> | ||||||
| @ -65,15 +66,15 @@ export default function ItemInfo ({ item, pendingSats, full, commentsText, class | |||||||
|       </span> |       </span> | ||||||
|       {item.subName && |       {item.subName && | ||||||
|         <Link href={`/~${item.subName}`}> |         <Link href={`/~${item.subName}`}> | ||||||
|           {' '}<Badge className={styles.newComment} variant={null}>{item.subName}</Badge> |           {' '}<Badge className={styles.newComment} bg={null}>{item.subName}</Badge> | ||||||
|         </Link>} |         </Link>} | ||||||
|       {(item.outlawed && !item.mine && |       {(item.outlawed && !item.mine && | ||||||
|         <Link href='/recent/outlawed'> |         <Link href='/recent/outlawed'> | ||||||
|           {' '}<Badge className={styles.newComment} variant={null}>outlawed</Badge> |           {' '}<Badge className={styles.newComment} bg={null}>outlawed</Badge> | ||||||
|         </Link>) || |         </Link>) || | ||||||
|         (item.freebie && |         (item.freebie && | ||||||
|           <Link href='/recent/freebies'> |           <Link href='/recent/freebies'> | ||||||
|             {' '}<Badge className={styles.newComment} variant={null}>freebie</Badge> |             {' '}<Badge className={styles.newComment} bg={null}>freebie</Badge> | ||||||
|           </Link> |           </Link> | ||||||
|         )} |         )} | ||||||
|       {canEdit && !item.deletedAt && |       {canEdit && !item.deletedAt && | ||||||
| @ -112,9 +113,9 @@ export default function ItemInfo ({ item, pendingSats, full, commentsText, class | |||||||
| 
 | 
 | ||||||
| export function ItemDropdown ({ children }) { | export function ItemDropdown ({ children }) { | ||||||
|   return ( |   return ( | ||||||
|     <Dropdown className='pointer' as='span'> |     <Dropdown className={`pointer ${styles.dropdown}`} as='span'> | ||||||
|       <Dropdown.Toggle variant='success' id='dropdown-basic' as='a'> |       <Dropdown.Toggle variant='success' as='a'> | ||||||
|         <MoreIcon className='fill-grey ml-1' height={16} width={16} /> |         <MoreIcon className='fill-grey ms-1' height={16} width={16} /> | ||||||
|       </Dropdown.Toggle> |       </Dropdown.Toggle> | ||||||
|       <Dropdown.Menu> |       <Dropdown.Menu> | ||||||
|         {children} |         {children} | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| import * as Yup from 'yup' | import * as Yup from 'yup' | ||||||
| import Toc from './table-of-contents' | import Toc from './table-of-contents' | ||||||
| import { Badge, Button, Image } from 'react-bootstrap' | import Badge from 'react-bootstrap/Badge' | ||||||
|  | import Button from 'react-bootstrap/Button' | ||||||
|  | import Image from 'react-bootstrap/Image' | ||||||
| import { SearchTitle } from './item' | import { SearchTitle } from './item' | ||||||
| import styles from './item.module.css' | import styles from './item.module.css' | ||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| @ -28,7 +30,7 @@ export default function ItemJob ({ item, toc, rank, children }) { | |||||||
|         </Link> |         </Link> | ||||||
|         <div className={`${styles.hunk} align-self-center mb-0`}> |         <div className={`${styles.hunk} align-self-center mb-0`}> | ||||||
|           <div className={`${styles.main} flex-wrap d-inline`}> |           <div className={`${styles.main} flex-wrap d-inline`}> | ||||||
|             <Link href={`/items/${item.id}`} className={`${styles.title} text-reset mr-2`}> |             <Link href={`/items/${item.id}`} className={`${styles.title} text-reset me-2`}> | ||||||
|               {item.searchTitle |               {item.searchTitle | ||||||
|                 ? <SearchTitle title={item.searchTitle} /> |                 ? <SearchTitle title={item.searchTitle} /> | ||||||
|                 : ( |                 : ( | ||||||
| @ -49,7 +51,7 @@ export default function ItemJob ({ item, toc, rank, children }) { | |||||||
|             <span> \ </span> |             <span> \ </span> | ||||||
|             <span> |             <span> | ||||||
|               <Link href={`/${item.user.name}`} className='d-inline-flex align-items-center'> |               <Link href={`/${item.user.name}`} className='d-inline-flex align-items-center'> | ||||||
|                 @{item.user.name}<CowboyHat className='ml-1 fill-grey' user={item.user} height={12} width={12} /> |                 @{item.user.name}<CowboyHat className='ms-1 fill-grey' user={item.user} height={12} width={12} /> | ||||||
|               </Link> |               </Link> | ||||||
|               <span> </span> |               <span> </span> | ||||||
|               <Link href={`/items/${item.id}`} title={item.createdAt} className='text-reset'> |               <Link href={`/items/${item.id}`} title={item.createdAt} className='text-reset'> | ||||||
| @ -64,9 +66,9 @@ export default function ItemJob ({ item, toc, rank, children }) { | |||||||
|                   <Link href={`/items/${item.id}/edit`} className='text-reset'> |                   <Link href={`/items/${item.id}/edit`} className='text-reset'> | ||||||
|                     edit |                     edit | ||||||
|                   </Link> |                   </Link> | ||||||
|                   {item.status !== 'ACTIVE' && <span className='ml-1 font-weight-bold text-boost'> {item.status}</span>} |                   {item.status !== 'ACTIVE' && <span className='ms-1 fw-bold text-boost'> {item.status}</span>} | ||||||
|                 </>)} |                 </>)} | ||||||
|             {item.maxBid > 0 && item.status === 'ACTIVE' && <Badge className={`${styles.newComment} ml-1`}>PROMOTED</Badge>} |             {item.maxBid > 0 && item.status === 'ACTIVE' && <Badge className={`${styles.newComment} ms-1`}>PROMOTED</Badge>} | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|         {toc && |         {toc && | ||||||
| @ -81,9 +83,9 @@ export default function ItemJob ({ item, toc, rank, children }) { | |||||||
|             <Button |             <Button | ||||||
|               target='_blank' href={isEmail ? `mailto:${item.url}?subject=${encodeURIComponent(item.title)} via Stacker News` : item.url} |               target='_blank' href={isEmail ? `mailto:${item.url}?subject=${encodeURIComponent(item.title)} via Stacker News` : item.url} | ||||||
|             > |             > | ||||||
|               apply {isEmail && <EmailIcon className='ml-1' />} |               apply {isEmail && <EmailIcon className='ms-1' />} | ||||||
|             </Button> |             </Button> | ||||||
|             {isEmail && <div className='ml-3 align-self-center text-muted font-weight-bold'>{item.url}</div>} |             {isEmail && <div className='ms-3 align-self-center text-muted fw-bold'>{item.url}</div>} | ||||||
|           </div> |           </div> | ||||||
|           {children} |           {children} | ||||||
|         </div> |         </div> | ||||||
|  | |||||||
| @ -39,22 +39,22 @@ export default function Item ({ item, rank, belowTitle, right, full, children, s | |||||||
|           : item.meDontLike ? <Flag width={24} height={24} className={`${styles.dontLike}`} /> : <UpVote item={item} className={styles.upvote} pendingSats={pendingSats} setPendingSats={setPendingSats} />} |           : item.meDontLike ? <Flag width={24} height={24} className={`${styles.dontLike}`} /> : <UpVote item={item} className={styles.upvote} pendingSats={pendingSats} setPendingSats={setPendingSats} />} | ||||||
|         <div className={styles.hunk}> |         <div className={styles.hunk}> | ||||||
|           <div className={`${styles.main} flex-wrap`}> |           <div className={`${styles.main} flex-wrap`}> | ||||||
|             <Link href={`/items/${item.id}`} ref={titleRef} className={`${styles.title} text-reset mr-2`}> |             <Link href={`/items/${item.id}`} ref={titleRef} className={`${styles.title} text-reset me-2`}> | ||||||
|               {item.searchTitle ? <SearchTitle title={item.searchTitle} /> : item.title} |               {item.searchTitle ? <SearchTitle title={item.searchTitle} /> : item.title} | ||||||
|               {item.pollCost && <span className={styles.icon}> <PollIcon className='fill-grey ml-1' height={14} width={14} /></span>} |               {item.pollCost && <span className={styles.icon}> <PollIcon className='fill-grey ms-1' height={14} width={14} /></span>} | ||||||
|               {item.bounty > 0 && |               {item.bounty > 0 && | ||||||
|                 <span className={styles.icon}> |                 <span className={styles.icon}> | ||||||
|                   <ActionTooltip notForm overlayText={`${abbrNum(item.bounty)} ${item.bountyPaidTo?.length ? 'sats paid' : 'sats bounty'}`}> |                   <ActionTooltip notForm overlayText={`${abbrNum(item.bounty)} ${item.bountyPaidTo?.length ? 'sats paid' : 'sats bounty'}`}> | ||||||
|                     <BountyIcon className={`${styles.bountyIcon} ${item.bountyPaidTo?.length ? 'fill-success' : 'fill-grey'}`} height={16} width={16} /> |                     <BountyIcon className={`${styles.bountyIcon} ${item.bountyPaidTo?.length ? 'fill-success' : 'fill-grey'}`} height={16} width={16} /> | ||||||
|                   </ActionTooltip> |                   </ActionTooltip> | ||||||
|                 </span>} |                 </span>} | ||||||
|               {image && <span className={styles.icon}><ImageIcon className='fill-grey ml-2' height={16} width={16} /></span>} |               {image && <span className={styles.icon}><ImageIcon className='fill-grey ms-2' height={16} width={16} /></span>} | ||||||
|             </Link> |             </Link> | ||||||
|             {item.url && !image && |             {item.url && !image && | ||||||
|               <> |               <> | ||||||
|                 {/*  eslint-disable-next-line */} |                 {/*  eslint-disable-next-line */} | ||||||
|                 <a |                 <a | ||||||
|                   className={`${styles.link} py-half py-md-0`} target='_blank' href={item.url} |                   className={`${styles.link}`} target='_blank' href={item.url} | ||||||
|                   rel={item.sats + item.boost >= NOFOLLOW_LIMIT ? null : 'nofollow'} |                   rel={item.sats + item.boost >= NOFOLLOW_LIMIT ? null : 'nofollow'} | ||||||
|                 > |                 > | ||||||
|                   {item.url.replace(/(^https?:|^)\/\//, '')} |                   {item.url.replace(/(^https?:|^)\/\//, '')} | ||||||
| @ -88,7 +88,7 @@ export function ItemSkeleton ({ rank, children }) { | |||||||
|         <UpVote className={styles.upvote} /> |         <UpVote className={styles.upvote} /> | ||||||
|         <div className={styles.hunk}> |         <div className={styles.hunk}> | ||||||
|           <div className={`${styles.main} flex-wrap flex-md-nowrap`}> |           <div className={`${styles.main} flex-wrap flex-md-nowrap`}> | ||||||
|             <span className={`${styles.title} clouds text-reset flex-md-fill flex-md-shrink-0 mr-2`} /> |             <span className={`${styles.title} clouds text-reset flex-md-fill flex-md-shrink-0 me-2`} /> | ||||||
|             <span className={`${styles.link} clouds`} /> |             <span className={`${styles.link} clouds`} /> | ||||||
|           </div> |           </div> | ||||||
|           <div className={styles.other}> |           <div className={styles.other}> | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
|     max-width: 100%; |     max-width: 100%; | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     vertical-align: middle; |     vertical-align: middle; | ||||||
|  |     padding-bottom: .15rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .icon { | .icon { | ||||||
| @ -24,12 +25,15 @@ a.title:visited { | |||||||
|     overflow: hidden; |     overflow: hidden; | ||||||
|     text-overflow: ellipsis; |     text-overflow: ellipsis; | ||||||
|     flex: 1 0 128px; |     flex: 1 0 128px; | ||||||
|  |     padding-bottom: .15rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .newComment { | .newComment { | ||||||
|     color: var(--theme-grey) !important; |     color: var(--theme-grey) !important; | ||||||
|     background: var(--theme-clickToContextColor) !important; |     background: var(--theme-clickToContextColor) !important; | ||||||
|     vertical-align: middle; |     vertical-align: middle; | ||||||
|  |     margin-top: -1px; | ||||||
|  |     margin-left: 0.1rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .pin { | .pin { | ||||||
| @ -64,6 +68,16 @@ a.link:visited { | |||||||
| .other { | .other { | ||||||
|     font-size: 80%; |     font-size: 80%; | ||||||
|     color: var(--theme-grey); |     color: var(--theme-grey); | ||||||
|  |     vertical-align: text-top; | ||||||
|  |     margin-bottom: .125rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .other svg { | ||||||
|  |     vertical-align: text-top; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .other .dropdown svg { | ||||||
|  |     margin-top: -1px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .item { | .item { | ||||||
|  | |||||||
| @ -1,5 +1,10 @@ | |||||||
| import { Checkbox, Form, Input, MarkdownInput, SubmitButton } from './form' | import { Checkbox, Form, Input, MarkdownInput, SubmitButton } from './form' | ||||||
| import { InputGroup, Form as BForm, Col, Image } from 'react-bootstrap' | import Row from 'react-bootstrap/Row' | ||||||
|  | import Col from 'react-bootstrap/Col' | ||||||
|  | import InputGroup from 'react-bootstrap/InputGroup' | ||||||
|  | import Image from 'react-bootstrap/Image' | ||||||
|  | import BootstrapForm from 'react-bootstrap/Form' | ||||||
|  | import Alert from 'react-bootstrap/Alert' | ||||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||||
| import Info from './info' | import Info from './info' | ||||||
| import AccordianItem from './accordian-item' | import AccordianItem from './accordian-item' | ||||||
| @ -9,8 +14,6 @@ import { useRouter } from 'next/router' | |||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| import { usePrice } from './price' | import { usePrice } from './price' | ||||||
| import Avatar from './avatar' | import Avatar from './avatar' | ||||||
| import BootstrapForm from 'react-bootstrap/Form' |  | ||||||
| import Alert from 'react-bootstrap/Alert' |  | ||||||
| import ActionTooltip from './action-tooltip' | import ActionTooltip from './action-tooltip' | ||||||
| import { jobSchema } from '../lib/validate' | import { jobSchema } from '../lib/validate' | ||||||
| import CancelButton from './cancel-button' | import CancelButton from './cancel-button' | ||||||
| @ -115,7 +118,7 @@ export default function JobForm ({ item, sub }) { | |||||||
|           required |           required | ||||||
|           clear |           clear | ||||||
|         /> |         /> | ||||||
|         <BForm.Row className='mr-0'> |         <Row className='me-0'> | ||||||
|           <Col> |           <Col> | ||||||
|             <Input |             <Input | ||||||
|               label='location' |               label='location' | ||||||
| @ -124,10 +127,10 @@ export default function JobForm ({ item, sub }) { | |||||||
|             /> |             /> | ||||||
|           </Col> |           </Col> | ||||||
|           <Checkbox |           <Checkbox | ||||||
|             label={<div className='font-weight-bold'>remote</div>} name='remote' hiddenLabel |             label={<div className='fw-bold'>remote</div>} name='remote' hiddenLabel | ||||||
|             groupClassName={styles.inlineCheckGroup} |             groupClassName={styles.inlineCheckGroup} | ||||||
|           /> |           /> | ||||||
|         </BForm.Row> |         </Row> | ||||||
|         <MarkdownInput |         <MarkdownInput | ||||||
|           topLevel |           topLevel | ||||||
|           label='description' |           label='description' | ||||||
| @ -136,7 +139,7 @@ export default function JobForm ({ item, sub }) { | |||||||
|           required |           required | ||||||
|         /> |         /> | ||||||
|         <Input |         <Input | ||||||
|           label={<>how to apply <small className='text-muted ml-2'>url or email address</small></>} |           label={<>how to apply <small className='text-muted ms-2'>url or email address</small></>} | ||||||
|           name='url' |           name='url' | ||||||
|           required |           required | ||||||
|           clear |           clear | ||||||
| @ -187,14 +190,14 @@ function PromoteJob ({ item, sub, storageKeyPrefix }) { | |||||||
|             label={ |             label={ | ||||||
|               <div className='d-flex align-items-center'>bid |               <div className='d-flex align-items-center'>bid | ||||||
|                 <Info> |                 <Info> | ||||||
|                   <ol className='font-weight-bold'> |                   <ol className='fw-bold'> | ||||||
|                     <li>The higher your bid the higher your job will rank</li> |                     <li>The higher your bid the higher your job will rank</li> | ||||||
|                     <li>You can increase, decrease, or remove your bid at anytime</li> |                     <li>You can increase, decrease, or remove your bid at anytime</li> | ||||||
|                     <li>You can edit or stop your job at anytime</li> |                     <li>You can edit or stop your job at anytime</li> | ||||||
|                     <li>If you run out of sats, your job will stop being promoted until you fill your wallet again</li> |                     <li>If you run out of sats, your job will stop being promoted until you fill your wallet again</li> | ||||||
|                   </ol> |                   </ol> | ||||||
|                 </Info> |                 </Info> | ||||||
|                 <small className='text-muted ml-2'>optional</small> |                 <small className='text-muted ms-2'>optional</small> | ||||||
|               </div> |               </div> | ||||||
|           } |           } | ||||||
|             name='maxBid' |             name='maxBid' | ||||||
| @ -210,7 +213,7 @@ function PromoteJob ({ item, sub, storageKeyPrefix }) { | |||||||
|             hint={<PriceHint monthly={monthly} />} |             hint={<PriceHint monthly={monthly} />} | ||||||
|             storageKeyPrefix={storageKeyPrefix} |             storageKeyPrefix={storageKeyPrefix} | ||||||
|           /> |           /> | ||||||
|           <><div className='font-weight-bold text-muted'>This bid puts your job in position: {position}</div></> |           <><div className='fw-bold text-muted'>This bid puts your job in position: {position}</div></> | ||||||
|         </> |         </> | ||||||
|   } |   } | ||||||
|     /> |     /> | ||||||
| @ -227,10 +230,10 @@ function StatusControl ({ item }) { | |||||||
| 
 | 
 | ||||||
|           <AccordianItem |           <AccordianItem | ||||||
|             header={<div style={{ fontWeight: 'bold', fontSize: '92%' }}>I want to stop my job</div>} |             header={<div style={{ fontWeight: 'bold', fontSize: '92%' }}>I want to stop my job</div>} | ||||||
|             headerColor='var(--danger)' |             headerColor='var(--bs-danger)' | ||||||
|             body={ |             body={ | ||||||
|               <Checkbox |               <Checkbox | ||||||
|                 label={<div className='font-weight-bold text-danger'>stop my job</div>} name='stop' inline |                 label={<div className='fw-bold text-danger'>stop my job</div>} name='stop' inline | ||||||
|               /> |               /> | ||||||
|           } |           } | ||||||
|           /> |           /> | ||||||
| @ -242,10 +245,10 @@ function StatusControl ({ item }) { | |||||||
|       return ( |       return ( | ||||||
|         <AccordianItem |         <AccordianItem | ||||||
|           header={<div style={{ fontWeight: 'bold', fontSize: '92%' }}>I want to resume my job</div>} |           header={<div style={{ fontWeight: 'bold', fontSize: '92%' }}>I want to resume my job</div>} | ||||||
|           headerColor='var(--success)' |           headerColor='var(--bs-success)' | ||||||
|           body={ |           body={ | ||||||
|             <Checkbox |             <Checkbox | ||||||
|               label={<div className='font-weight-bold text-success'>resume my job</div>} name='start' inline |               label={<div className='fw-bold text-success'>resume my job</div>} name='start' inline | ||||||
|             /> |             /> | ||||||
|           } |           } | ||||||
|         /> |         /> | ||||||
|  | |||||||
| @ -1,7 +1,9 @@ | |||||||
| import { gql, useMutation, useQuery } from '@apollo/client' | import { gql, useMutation, useQuery } from '@apollo/client' | ||||||
| import { signIn } from 'next-auth/client' | import { signIn } from 'next-auth/client' | ||||||
| import { useEffect } from 'react' | import { useEffect } from 'react' | ||||||
| import { Col, Container, Row } from 'react-bootstrap' | import Col from 'react-bootstrap/Col' | ||||||
|  | import Container from 'react-bootstrap/Container' | ||||||
|  | import Row from 'react-bootstrap/Row' | ||||||
| import AccordianItem from './accordian-item' | import AccordianItem from './accordian-item' | ||||||
| import Qr, { QrSkeleton } from './qr' | import Qr, { QrSkeleton } from './qr' | ||||||
| import styles from './lightning-auth.module.css' | import styles from './lightning-auth.module.css' | ||||||
| @ -37,9 +39,9 @@ function LightningExplainer ({ text, children }) { | |||||||
|         <h3 className='w-100 pb-2'> |         <h3 className='w-100 pb-2'> | ||||||
|           {text || 'Login'} with Lightning |           {text || 'Login'} with Lightning | ||||||
|         </h3> |         </h3> | ||||||
|         <div className='font-weight-bold text-muted pb-4'>This is the most private way to use Stacker News. Just open your Lightning wallet and scan the QR code.</div> |         <div className='fw-bold text-muted pb-4'>This is the most private way to use Stacker News. Just open your Lightning wallet and scan the QR code.</div> | ||||||
|         <Row className='w-100 text-muted'> |         <Row className='w-100 text-muted'> | ||||||
|           <Col className='pl-0 mb-4' md> |           <Col className='ps-0 mb-4' md> | ||||||
|             <AccordianItem |             <AccordianItem | ||||||
|               header={`Which wallets can I use to ${(text || 'Login').toLowerCase()}?`} |               header={`Which wallets can I use to ${(text || 'Login').toLowerCase()}?`} | ||||||
|               body={ |               body={ | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ import Item from './item' | |||||||
| import AccordianItem from './accordian-item' | import AccordianItem from './accordian-item' | ||||||
| import FeeButton, { EditFeeButton } from './fee-button' | import FeeButton, { EditFeeButton } from './fee-button' | ||||||
| import Delete from './delete' | import Delete from './delete' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import { linkSchema } from '../lib/validate' | import { linkSchema } from '../lib/validate' | ||||||
| import Moon from '../svgs/moon-fill.svg' | import Moon from '../svgs/moon-fill.svg' | ||||||
| import { SubSelectInitial } from './sub-select-form' | import { SubSelectInitial } from './sub-select-form' | ||||||
| @ -143,7 +143,7 @@ export function LinkForm ({ item, sub, editThreshold, children }) { | |||||||
|         autoComplete='off' |         autoComplete='off' | ||||||
|         overrideValue={data?.pageTitleAndUnshorted?.unshorted} |         overrideValue={data?.pageTitleAndUnshorted?.unshorted} | ||||||
|         hint={editThreshold |         hint={editThreshold | ||||||
|           ? <div className='text-muted font-weight-bold'><Countdown date={editThreshold} /></div> |           ? <div className='text-muted fw-bold'><Countdown date={editThreshold} /></div> | ||||||
|           : null} |           : null} | ||||||
|         onChange={async (formik, e) => { |         onChange={async (formik, e) => { | ||||||
|           if ((/^ *$/).test(formik?.values.title)) { |           if ((/^ *$/).test(formik?.values.title)) { | ||||||
| @ -191,9 +191,9 @@ export function LinkForm ({ item, sub, editThreshold, children }) { | |||||||
|                 ChildButton={SubmitButton} variant='secondary' |                 ChildButton={SubmitButton} variant='secondary' | ||||||
|               /> |               /> | ||||||
|               {dupesLoading && |               {dupesLoading && | ||||||
|                 <div className='d-flex ml-3 justify-content-center'> |                 <div className='d-flex ms-3 justify-content-center'> | ||||||
|                   <Moon className='spin fill-grey' /> |                   <Moon className='spin fill-grey' /> | ||||||
|                   <div className='ml-2 text-muted' style={{ fontWeight: '600' }}>searching for dupes</div> |                   <div className='ms-2 text-muted' style={{ fontWeight: '600' }}>searching for dupes</div> | ||||||
|                 </div>} |                 </div>} | ||||||
|             </div> |             </div> | ||||||
|             )} |             )} | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ import GithubIcon from '../svgs/github-fill.svg' | |||||||
| import TwitterIcon from '../svgs/twitter-fill.svg' | import TwitterIcon from '../svgs/twitter-fill.svg' | ||||||
| import LightningIcon from '../svgs/bolt.svg' | import LightningIcon from '../svgs/bolt.svg' | ||||||
| import SlashtagsIcon from '../svgs/slashtags.svg' | import SlashtagsIcon from '../svgs/slashtags.svg' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| 
 | 
 | ||||||
| export default function LoginButton ({ text, type, className, onClick }) { | export default function LoginButton ({ text, type, className, onClick }) { | ||||||
|   let Icon, variant |   let Icon, variant | ||||||
| @ -32,7 +32,7 @@ export default function LoginButton ({ text, type, className, onClick }) { | |||||||
|     <Button className={className} variant={variant} onClick={onClick}> |     <Button className={className} variant={variant} onClick={onClick}> | ||||||
|       <Icon |       <Icon | ||||||
|         width={20} |         width={20} | ||||||
|         height={20} className='mr-3' |         height={20} className='me-3' | ||||||
|       /> |       /> | ||||||
|       {text} {name} |       {text} {name} | ||||||
|     </Button> |     </Button> | ||||||
|  | |||||||
| @ -71,7 +71,7 @@ export default function Login ({ providers, callbackUrl, error, text, Header, Fo | |||||||
|           case 'Email': |           case 'Email': | ||||||
|             return ( |             return ( | ||||||
|               <div className='w-100' key={provider.name}> |               <div className='w-100' key={provider.name}> | ||||||
|                 <div className='mt-2 text-center text-muted font-weight-bold'>or</div> |                 <div className='mt-2 text-center text-muted fw-bold'>or</div> | ||||||
|                 <EmailLoginForm text={text} callbackUrl={callbackUrl} /> |                 <EmailLoginForm text={text} callbackUrl={callbackUrl} /> | ||||||
|               </div> |               </div> | ||||||
|             ) |             ) | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { createContext, useCallback, useContext, useMemo, useState } from 'react' | import { createContext, useCallback, useContext, useMemo, useState } from 'react' | ||||||
| import { Modal } from 'react-bootstrap' | import Modal from 'react-bootstrap/Modal' | ||||||
| 
 | 
 | ||||||
| export const ShowModalContext = createContext(() => null) | export const ShowModalContext = createContext(() => null) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import { useState } from 'react' | import { useState } from 'react' | ||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| 
 | 
 | ||||||
| @ -40,7 +40,7 @@ export function NavigateFooter ({ cursor, count, fetchMore, href, text, noMoreTe | |||||||
|   let Footer |   let Footer | ||||||
|   if (cursor) { |   if (cursor) { | ||||||
|     Footer = () => ( |     Footer = () => ( | ||||||
|       <Link href={href} className='text-reset text-muted font-weight-bold'>{text}</Link> |       <Link href={href} className='text-reset text-muted fw-bold'>{text}</Link> | ||||||
|     ) |     ) | ||||||
|   } else { |   } else { | ||||||
|     Footer = () => ( |     Footer = () => ( | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ import { COMMENT_DEPTH_LIMIT } from '../lib/constants' | |||||||
| import CowboyHatIcon from '../svgs/cowboy.svg' | import CowboyHatIcon from '../svgs/cowboy.svg' | ||||||
| import BaldIcon from '../svgs/bald.svg' | import BaldIcon from '../svgs/bald.svg' | ||||||
| import { RootProvider } from './root' | import { RootProvider } from './root' | ||||||
| import { Alert } from 'react-bootstrap' | import Alert from 'react-bootstrap/Alert' | ||||||
| import styles from './notifications.module.css' | import styles from './notifications.module.css' | ||||||
| import { useServiceWorker } from './serviceworker' | import { useServiceWorker } from './serviceworker' | ||||||
| import { Checkbox, Form } from './form' | import { Checkbox, Form } from './form' | ||||||
| @ -110,9 +110,9 @@ function Streak ({ n }) { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex font-weight-bold ml-2 py-1'> |     <div className='d-flex fw-bold ms-2 py-1'> | ||||||
|       <div style={{ fontSize: '2rem' }}>{n.days ? <BaldIcon className='fill-grey' height={40} width={40} /> : <CowboyHatIcon className='fill-grey' height={40} width={40} />}</div> |       <div style={{ fontSize: '2rem' }}>{n.days ? <BaldIcon className='fill-grey' height={40} width={40} /> : <CowboyHatIcon className='fill-grey' height={40} width={40} />}</div> | ||||||
|       <div className='ml-1 p-1'> |       <div className='ms-1 p-1'> | ||||||
|         you {n.days ? 'lost your' : 'found a'} cowboy hat |         you {n.days ? 'lost your' : 'found a'} cowboy hat | ||||||
|         <div><small style={{ lineHeight: '140%', display: 'inline-block' }}>{blurb(n)}</small></div> |         <div><small style={{ lineHeight: '140%', display: 'inline-block' }}>{blurb(n)}</small></div> | ||||||
|       </div> |       </div> | ||||||
| @ -122,11 +122,11 @@ function Streak ({ n }) { | |||||||
| 
 | 
 | ||||||
| function EarnNotification ({ n }) { | function EarnNotification ({ n }) { | ||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex ml-2 py-1'> |     <div className='d-flex ms-2 py-1'> | ||||||
|       <HandCoin className='align-self-center fill-boost mx-1' width={24} height={24} style={{ flex: '0 0 24px', transform: 'rotateY(180deg)' }} /> |       <HandCoin className='align-self-center fill-boost mx-1' width={24} height={24} style={{ flex: '0 0 24px', transform: 'rotateY(180deg)' }} /> | ||||||
|       <div className='ml-2'> |       <div className='ms-2'> | ||||||
|         <div className='font-weight-bold text-boost'> |         <div className='fw-bold text-boost'> | ||||||
|           you stacked {n.earnedSats} sats in rewards<small className='text-muted ml-1'>{timeSince(new Date(n.sortTime))}</small> |           you stacked {n.earnedSats} sats in rewards<small className='text-muted ms-1'>{timeSince(new Date(n.sortTime))}</small> | ||||||
|         </div> |         </div> | ||||||
|         {n.sources && |         {n.sources && | ||||||
|           <div style={{ fontSize: '80%', color: 'var(--theme-grey)' }}> |           <div style={{ fontSize: '80%', color: 'var(--theme-grey)' }}> | ||||||
| @ -146,10 +146,10 @@ function EarnNotification ({ n }) { | |||||||
| function Invitification ({ n }) { | function Invitification ({ n }) { | ||||||
|   return ( |   return ( | ||||||
|     <NotificationLayout href='/invites'> |     <NotificationLayout href='/invites'> | ||||||
|       <small className='font-weight-bold text-secondary ml-2'> |       <small className='fw-bold text-secondary ms-2'> | ||||||
|         your invite has been redeemed by {n.invite.invitees.length} stackers |         your invite has been redeemed by {n.invite.invitees.length} stackers | ||||||
|       </small> |       </small> | ||||||
|       <div className='ml-4 mr-2 mt-1'> |       <div className='ms-4 me-2 mt-1'> | ||||||
|         <Invite |         <Invite | ||||||
|           invite={n.invite} active={ |           invite={n.invite} active={ | ||||||
|           !n.invite.revoked && |           !n.invite.revoked && | ||||||
| @ -164,9 +164,9 @@ function Invitification ({ n }) { | |||||||
| function InvoicePaid ({ n }) { | function InvoicePaid ({ n }) { | ||||||
|   return ( |   return ( | ||||||
|     <NotificationLayout href={`/invoices/${n.invoice.id}`}> |     <NotificationLayout href={`/invoices/${n.invoice.id}`}> | ||||||
|       <div className='font-weight-bold text-info ml-2 py-1'> |       <div className='fw-bold text-info ms-2 py-1'> | ||||||
|         <Check className='fill-info mr-1' />{n.earnedSats} sats were deposited in your account |         <Check className='fill-info me-1' />{n.earnedSats} sats were deposited in your account | ||||||
|         <small className='text-muted ml-1'>{timeSince(new Date(n.sortTime))}</small> |         <small className='text-muted ms-1'>{timeSince(new Date(n.sortTime))}</small> | ||||||
|       </div> |       </div> | ||||||
|     </NotificationLayout> |     </NotificationLayout> | ||||||
|   ) |   ) | ||||||
| @ -175,9 +175,9 @@ function InvoicePaid ({ n }) { | |||||||
| function Referral ({ n }) { | function Referral ({ n }) { | ||||||
|   return ( |   return ( | ||||||
|     <NotificationLayout> |     <NotificationLayout> | ||||||
|       <small className='font-weight-bold text-secondary ml-2'> |       <small className='fw-bold text-secondary ms-2'> | ||||||
|         someone joined via one of your <Link href='/referrals/month' className='text-reset'>referral links</Link> |         someone joined via one of your <Link href='/referrals/month' className='text-reset'>referral links</Link> | ||||||
|         <small className='text-muted ml-1'>{timeSince(new Date(n.sortTime))}</small> |         <small className='text-muted ms-1'>{timeSince(new Date(n.sortTime))}</small> | ||||||
|       </small> |       </small> | ||||||
|     </NotificationLayout> |     </NotificationLayout> | ||||||
|   ) |   ) | ||||||
| @ -186,7 +186,7 @@ function Referral ({ n }) { | |||||||
| function Votification ({ n }) { | function Votification ({ n }) { | ||||||
|   return ( |   return ( | ||||||
|     <NotificationLayout {...defaultOnClick(n)}> |     <NotificationLayout {...defaultOnClick(n)}> | ||||||
|       <small className='font-weight-bold text-success ml-2'> |       <small className='fw-bold text-success ms-2'> | ||||||
|         your {n.item.title ? 'post' : 'reply'} {n.item.fwdUser ? 'forwarded' : 'stacked'} {n.earnedSats} sats{n.item.fwdUser && ` to @${n.item.fwdUser.name}`} |         your {n.item.title ? 'post' : 'reply'} {n.item.fwdUser ? 'forwarded' : 'stacked'} {n.earnedSats} sats{n.item.fwdUser && ` to @${n.item.fwdUser.name}`} | ||||||
|       </small> |       </small> | ||||||
|       <div> |       <div> | ||||||
| @ -207,7 +207,7 @@ function Votification ({ n }) { | |||||||
| function Mention ({ n }) { | function Mention ({ n }) { | ||||||
|   return ( |   return ( | ||||||
|     <NotificationLayout {...defaultOnClick(n)}> |     <NotificationLayout {...defaultOnClick(n)}> | ||||||
|       <small className='font-weight-bold text-info ml-2'> |       <small className='fw-bold text-info ms-2'> | ||||||
|         you were mentioned in |         you were mentioned in | ||||||
|       </small> |       </small> | ||||||
|       <div> |       <div> | ||||||
| @ -227,7 +227,7 @@ function Mention ({ n }) { | |||||||
| function JobChanged ({ n }) { | function JobChanged ({ n }) { | ||||||
|   return ( |   return ( | ||||||
|     <NotificationLayout {...defaultOnClick(n)}> |     <NotificationLayout {...defaultOnClick(n)}> | ||||||
|       <small className={`font-weight-bold text-${n.item.status === 'ACTIVE' ? 'success' : 'boost'} ml-1`}> |       <small className={`fw-bold text-${n.item.status === 'ACTIVE' ? 'success' : 'boost'} ms-1`}> | ||||||
|         {n.item.status === 'ACTIVE' |         {n.item.status === 'ACTIVE' | ||||||
|           ? 'your job is active again' |           ? 'your job is active again' | ||||||
|           : (n.item.status === 'NOSATS' |           : (n.item.status === 'NOSATS' | ||||||
| @ -306,7 +306,7 @@ function NotificationAlert () { | |||||||
|           <Form className={`d-flex justify-content-end ${supported ? 'visible' : 'invisible'}`} initial={{ pushNotify: hasSubscription }}> |           <Form className={`d-flex justify-content-end ${supported ? 'visible' : 'invisible'}`} initial={{ pushNotify: hasSubscription }}> | ||||||
|             <Checkbox |             <Checkbox | ||||||
|               name='pushNotify' label={<span className='text-muted'>push notifications</span>} |               name='pushNotify' label={<span className='text-muted'>push notifications</span>} | ||||||
|               groupClassName={`${styles.subFormGroup} mb-1 mr-sm-3 mr-0`} |               groupClassName={`${styles.subFormGroup} mb-1 me-sm-3 me-0`} | ||||||
|               inline checked={hasSubscription} handleChange={async () => { |               inline checked={hasSubscription} handleChange={async () => { | ||||||
|                 await sw.togglePushSubscription().catch(setError) |                 await sw.togglePushSubscription().catch(setError) | ||||||
|               }} |               }} | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ export default function PastBounties ({ item }) { | |||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <AccordianItem |     <AccordianItem | ||||||
|       header={<div className='font-weight-bold'>{item.user.name}'s bounties</div>} |       header={<div className='fw-bold'>{item.user.name}'s bounties</div>} | ||||||
|       body={ |       body={ | ||||||
|         <Items |         <Items | ||||||
|           variables={variables} |           variables={variables} | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import React from 'react' | import React from 'react' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import styles from './pay-bounty.module.css' | import styles from './pay-bounty.module.css' | ||||||
| import ActionTooltip from './action-tooltip' | import ActionTooltip from './action-tooltip' | ||||||
| import { useMutation, gql } from '@apollo/client' | import { useMutation, gql } from '@apollo/client' | ||||||
| @ -96,7 +96,7 @@ export default function PayBounty ({ children, item }) { | |||||||
|         className={styles.pay} onClick={() => { |         className={styles.pay} onClick={() => { | ||||||
|           showModal(onClose => ( |           showModal(onClose => ( | ||||||
|             <> |             <> | ||||||
|               <div className='text-center font-weight-bold text-muted'> |               <div className='text-center fw-bold text-muted'> | ||||||
|                 Pay this bounty to {item.user.name}? |                 Pay this bounty to {item.user.name}? | ||||||
|               </div> |               </div> | ||||||
|               <div className='text-center'> |               <div className='text-center'> | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| .pay { | .pay { | ||||||
|     color: var(--success); |     color: var(--bs-success); | ||||||
|     margin-left: 1rem; |     margin-left: 1rem; | ||||||
| } | } | ||||||
| @ -6,7 +6,7 @@ import AdvPostForm, { AdvPostInitial } from './adv-post-form' | |||||||
| import { MAX_POLL_NUM_CHOICES } from '../lib/constants' | import { MAX_POLL_NUM_CHOICES } from '../lib/constants' | ||||||
| import FeeButton, { EditFeeButton } from './fee-button' | import FeeButton, { EditFeeButton } from './fee-button' | ||||||
| import Delete from './delete' | import Delete from './delete' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import { pollSchema } from '../lib/validate' | import { pollSchema } from '../lib/validate' | ||||||
| import { SubSelectInitial } from './sub-select-form' | import { SubSelectInitial } from './sub-select-form' | ||||||
| import CancelButton from './cancel-button' | import CancelButton from './cancel-button' | ||||||
| @ -71,7 +71,7 @@ export function PollForm ({ item, sub, editThreshold, children }) { | |||||||
|       /> |       /> | ||||||
|       <MarkdownInput |       <MarkdownInput | ||||||
|         topLevel |         topLevel | ||||||
|         label={<>text <small className='text-muted ml-2'>optional</small></>} |         label={<>text <small className='text-muted ms-2'>optional</small></>} | ||||||
|         name='text' |         name='text' | ||||||
|         minRows={2} |         minRows={2} | ||||||
|       /> |       /> | ||||||
| @ -82,7 +82,7 @@ export function PollForm ({ item, sub, editThreshold, children }) { | |||||||
|         max={MAX_POLL_NUM_CHOICES} |         max={MAX_POLL_NUM_CHOICES} | ||||||
|         min={2} |         min={2} | ||||||
|         hint={editThreshold |         hint={editThreshold | ||||||
|           ? <div className='text-muted font-weight-bold'><Countdown date={editThreshold} /></div> |           ? <div className='text-muted fw-bold'><Countdown date={editThreshold} /></div> | ||||||
|           : null} |           : null} | ||||||
|       /> |       /> | ||||||
|       <AdvPostForm edit={!!item} /> |       <AdvPostForm edit={!!item} /> | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { gql, useMutation } from '@apollo/client' | import { gql, useMutation } from '@apollo/client' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import { fixedDecimal } from '../lib/format' | import { fixedDecimal } from '../lib/format' | ||||||
| import { timeLeft } from '../lib/time' | import { timeLeft } from '../lib/time' | ||||||
| import { useMe } from './me' | import { useMe } from './me' | ||||||
| @ -94,8 +94,8 @@ export default function Poll ({ item }) { | |||||||
| function PollResult ({ v, progress }) { | function PollResult ({ v, progress }) { | ||||||
|   return ( |   return ( | ||||||
|     <div className={styles.pollResult}> |     <div className={styles.pollResult}> | ||||||
|       <span className={styles.pollOption}>{v.option}{v.meVoted && <Check className='fill-grey ml-1 align-self-center' width={18} height={18} />}</span> |       <span className={styles.pollOption}>{v.option}{v.meVoted && <Check className='fill-grey ms-1 align-self-center' width={18} height={18} />}</span> | ||||||
|       <span className='ml-auto mr-2 align-self-center'>{progress}%</span> |       <span className='ms-auto me-2 align-self-center'>{progress}%</span> | ||||||
|       <div className={styles.pollProgress} style={{ width: `${progress}%` }} /> |       <div className={styles.pollProgress} style={{ width: `${progress}%` }} /> | ||||||
|     </div> |     </div> | ||||||
|   ) |   ) | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| .pollButton { | .pollButton { | ||||||
|     margin-top: .25rem; |     margin-top: .25rem; | ||||||
|     display: block; |     display: block; | ||||||
|     border: 2px solid var(--info); |     border: 2px solid var(--bs-info); | ||||||
|     border-radius: 2rem; |     border-radius: 2rem; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     max-width: 600px; |     max-width: 600px; | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import JobForm from './job-form' | import JobForm from './job-form' | ||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import AccordianItem from './accordian-item' | import AccordianItem from './accordian-item' | ||||||
| import { useMe } from './me' | import { useMe } from './me' | ||||||
| import { useRouter } from 'next/router' | import { useRouter } from 'next/router' | ||||||
| @ -16,7 +16,7 @@ function FreebieDialog () { | |||||||
|     <div className='text-center mb-4 text-muted'> |     <div className='text-center mb-4 text-muted'> | ||||||
|       you have no sats, so this one is on us |       you have no sats, so this one is on us | ||||||
|       <Info> |       <Info> | ||||||
|         <ul className='font-weight-bold'> |         <ul className='fw-bold'> | ||||||
|           <li>Free posts have limited visibility and are hidden on the recent tab until other stackers zap them.</li> |           <li>Free posts have limited visibility and are hidden on the recent tab until other stackers zap them.</li> | ||||||
|           <li>Free posts will not cover posts that cost more than 1 sat.</li> |           <li>Free posts will not cover posts that cost more than 1 sat.</li> | ||||||
|           <li>To get fully visibile and unrestricted posts right away, fund your account with a few sats or earn some on Stacker News.</li> |           <li>To get fully visibile and unrestricted posts right away, fund your account with a few sats or earn some on Stacker News.</li> | ||||||
| @ -39,20 +39,20 @@ export function PostForm ({ type, sub, children }) { | |||||||
|         <Link href={prefix + '/post?type=link'}> |         <Link href={prefix + '/post?type=link'}> | ||||||
|           <Button variant='secondary'>link</Button> |           <Button variant='secondary'>link</Button> | ||||||
|         </Link> |         </Link> | ||||||
|         <span className='mx-3 font-weight-bold text-muted'>or</span> |         <span className='mx-3 fw-bold text-muted'>or</span> | ||||||
|         <Link href={prefix + '/post?type=discussion'}> |         <Link href={prefix + '/post?type=discussion'}> | ||||||
|           <Button variant='secondary'>discussion</Button> |           <Button variant='secondary'>discussion</Button> | ||||||
|         </Link> |         </Link> | ||||||
|         <div className='d-flex mt-4'> |         <div className='d-flex mt-4'> | ||||||
|           <AccordianItem |           <AccordianItem | ||||||
|             headerColor='#6c757d' |             headerColor='#6c757d' | ||||||
|             header={<div className='font-weight-bold text-muted'>more types</div>} |             header={<div className='fw-bold text-muted'>more types</div>} | ||||||
|             body={ |             body={ | ||||||
|               <div className='align-items-center'> |               <div className='align-items-center'> | ||||||
|                 <Link href={prefix + '/post?type=poll'}> |                 <Link href={prefix + '/post?type=poll'}> | ||||||
|                   <Button variant='info'>poll</Button> |                   <Button variant='info'>poll</Button> | ||||||
|                 </Link> |                 </Link> | ||||||
|                 <span className='mx-3 font-weight-bold text-muted'>or</span> |                 <span className='mx-3 fw-bold text-muted'>or</span> | ||||||
|                 <Link href={prefix + '/post?type=bounty'}> |                 <Link href={prefix + '/post?type=bounty'}> | ||||||
|                   <Button variant='info'>bounty</Button> |                   <Button variant='info'>bounty</Button> | ||||||
|                 </Link> |                 </Link> | ||||||
|  | |||||||
| @ -14,9 +14,9 @@ export default function RecentHeader ({ type, sub }) { | |||||||
|         type: router.query.type || type || 'posts' |         type: router.query.type || type || 'posts' | ||||||
|       }} |       }} | ||||||
|     > |     > | ||||||
|       <div className='text-muted font-weight-bold mt-0 mb-3 d-flex justify-content-end align-items-center'> |       <div className='text-muted fw-bold mt-0 mb-3 d-flex justify-content-end align-items-center'> | ||||||
|         <Select |         <Select | ||||||
|           groupClassName='mb-0 ml-2' |           groupClassName='mb-0 ms-2' | ||||||
|           className='w-auto' |           className='w-auto' | ||||||
|           name='type' |           name='type' | ||||||
|           size='sm' |           size='sm' | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ export default function Related ({ title, itemId }) { | |||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <AccordianItem |     <AccordianItem | ||||||
|       header={<div className='font-weight-bold'>related</div>} |       header={<div className='fw-bold'>related</div>} | ||||||
|       body={ |       body={ | ||||||
|         <Items |         <Items | ||||||
|           query={RELATED_ITEMS} |           query={RELATED_ITEMS} | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ function FreebieDialog () { | |||||||
|     <div className='text-muted'> |     <div className='text-muted'> | ||||||
|       you have no sats, so this one is on us |       you have no sats, so this one is on us | ||||||
|       <Info> |       <Info> | ||||||
|         <ul className='font-weight-bold'> |         <ul className='fw-bold'> | ||||||
|           <li>Free comments have limited visibility and are listed at the bottom of the comment section until other stackers zap them.</li> |           <li>Free comments have limited visibility and are listed at the bottom of the comment section until other stackers zap them.</li> | ||||||
|           <li>Free comments will not cover comments that cost more than 1 sat.</li> |           <li>Free comments will not cover comments that cost more than 1 sat.</li> | ||||||
|           <li>To get fully visibile and unrestricted comments right away, fund your account with a few sats or earn some on Stacker News.</li> |           <li>To get fully visibile and unrestricted comments right away, fund your account with a few sats or earn some on Stacker News.</li> | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ | |||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     padding-bottom: .5rem; |     padding: .25rem 0 .5rem 0; | ||||||
|     line-height: 1rem; |     line-height: 1rem; | ||||||
|     vertical-align: middle; |     vertical-align: middle; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| import { Button, Container } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
|  | import Container from 'react-bootstrap/Container' | ||||||
| import styles from './search.module.css' | import styles from './search.module.css' | ||||||
| import SearchIcon from '../svgs/search-line.svg' | import SearchIcon from '../svgs/search-line.svg' | ||||||
| import CloseIcon from '../svgs/close-line.svg' | import CloseIcon from '../svgs/close-line.svg' | ||||||
| @ -57,7 +58,7 @@ export default function Search ({ sub }) { | |||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       <div className={`${styles.searchSection} ${showSearch ? styles.solid : styles.hidden}`}> |       <div className={`${styles.searchSection} ${showSearch ? styles.solid : styles.hidden}`}> | ||||||
|         <Container className={`px-sm-0 ${styles.searchContainer} ${filter ? styles.leaveRoom : ''}`}> |         <Container className={`px-md-0 ${styles.searchContainer} ${filter ? styles.leaveRoom : ''}`}> | ||||||
|           {showSearch |           {showSearch | ||||||
|             ? ( |             ? ( | ||||||
|               <Form |               <Form | ||||||
| @ -71,9 +72,9 @@ export default function Search ({ sub }) { | |||||||
|                 onSubmit={search} |                 onSubmit={search} | ||||||
|               > |               > | ||||||
|                 {filter && |                 {filter && | ||||||
|                   <div className='text-muted font-weight-bold my-3 d-flex align-items-center'> |                   <div className='text-muted fw-bold my-3 d-flex align-items-center'> | ||||||
|                     <Select |                     <Select | ||||||
|                       groupClassName='mr-2 mb-0' |                       groupClassName='me-2 mb-0' | ||||||
|                       onChange={(formik, e) => search({ ...formik?.values, what: e.target.value })} |                       onChange={(formik, e) => search({ ...formik?.values, what: e.target.value })} | ||||||
|                       name='what' |                       name='what' | ||||||
|                       size='sm' |                       size='sm' | ||||||
| @ -91,7 +92,7 @@ export default function Search ({ sub }) { | |||||||
|                         /> |                         /> | ||||||
|                         for |                         for | ||||||
|                         <Select |                         <Select | ||||||
|                           groupClassName='mb-0 ml-2' |                           groupClassName='mb-0 ms-2' | ||||||
|                           onChange={(formik, e) => search({ ...formik?.values, when: e.target.value })} |                           onChange={(formik, e) => search({ ...formik?.values, when: e.target.value })} | ||||||
|                           name='when' |                           name='when' | ||||||
|                           size='sm' |                           size='sm' | ||||||
| @ -105,7 +106,7 @@ export default function Search ({ sub }) { | |||||||
|                     name='q' |                     name='q' | ||||||
|                     required |                     required | ||||||
|                     autoFocus |                     autoFocus | ||||||
|                     groupClassName='mr-3 mb-0 flex-grow-1' |                     groupClassName='me-3 mb-0 flex-grow-1' | ||||||
|                     className='flex-grow-1' |                     className='flex-grow-1' | ||||||
|                     clear |                     clear | ||||||
|                     onChange={async (formik, e) => { |                     onChange={async (formik, e) => { | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Dropdown } from 'react-bootstrap' | import Dropdown from 'react-bootstrap/Dropdown' | ||||||
| import ShareIcon from '../svgs/share-fill.svg' | import ShareIcon from '../svgs/share-fill.svg' | ||||||
| import copy from 'clipboard-copy' | import copy from 'clipboard-copy' | ||||||
| import { useMe } from './me' | import { useMe } from './me' | ||||||
| @ -9,7 +9,7 @@ export default function Share ({ item }) { | |||||||
| 
 | 
 | ||||||
|   return typeof window !== 'undefined' && navigator?.share |   return typeof window !== 'undefined' && navigator?.share | ||||||
|     ? ( |     ? ( | ||||||
|       <div className='ml-auto pointer d-flex align-items-center'> |       <div className='ms-auto pointer d-flex align-items-center'> | ||||||
|         <ShareIcon |         <ShareIcon | ||||||
|           width={20} height={20} |           width={20} height={20} | ||||||
|           className='mx-2 fill-grey theme' |           className='mx-2 fill-grey theme' | ||||||
| @ -28,7 +28,7 @@ export default function Share ({ item }) { | |||||||
|         /> |         /> | ||||||
|       </div>) |       </div>) | ||||||
|     : ( |     : ( | ||||||
|       <Dropdown alignRight className='ml-auto pointer  d-flex align-items-center' as='span'> |       <Dropdown align='end' className='ms-auto pointer  d-flex align-items-center' as='span'> | ||||||
|         <Dropdown.Toggle variant='success' id='dropdown-basic' as='a'> |         <Dropdown.Toggle variant='success' id='dropdown-basic' as='a'> | ||||||
|           <ShareIcon width={20} height={20} className='mx-2 fill-grey theme' /> |           <ShareIcon width={20} height={20} className='mx-2 fill-grey theme' /> | ||||||
|         </Dropdown.Toggle> |         </Dropdown.Toggle> | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Alert } from 'react-bootstrap' | import Alert from 'react-bootstrap/Alert' | ||||||
| import YouTube from '../svgs/youtube-line.svg' | import YouTube from '../svgs/youtube-line.svg' | ||||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||||
| import { gql, useQuery } from '@apollo/client' | import { gql, useQuery } from '@apollo/client' | ||||||
| @ -24,7 +24,7 @@ export default function Snl ({ ignorePreference }) { | |||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex'> |     <div className='d-flex'> | ||||||
|       <Alert |       <Alert | ||||||
|         variant='info' className='font-weight-bold mb-3 d-flex py-2 flex-shrink align-items-center' |         variant='info' className='fw-bold mb-3 d-flex py-2 flex-shrink align-items-center' | ||||||
|         onClose={() => { |         onClose={() => { | ||||||
|           setShow(undefined) |           setShow(undefined) | ||||||
|           localStorage.setItem('snl', new Date()) |           localStorage.setItem('snl', new Date()) | ||||||
| @ -32,7 +32,7 @@ export default function Snl ({ ignorePreference }) { | |||||||
|         dismissible |         dismissible | ||||||
|       > |       > | ||||||
|         <a href='https://www.youtube.com/@stackernews/live'> |         <a href='https://www.youtube.com/@stackernews/live'> | ||||||
|           <YouTube width={24} height={24} className='mr-2 fill-info' />Stacker News Live is streaming this week's top stories |           <YouTube width={24} height={24} className='me-2 fill-info' />Stacker News Live is streaming this week's top stories | ||||||
|         </a> |         </a> | ||||||
|       </Alert> |       </Alert> | ||||||
|     </div> |     </div> | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ export default function SubSelect ({ label, sub, setSub, item, ...props }) { | |||||||
|   const SubInfo = () => ( |   const SubInfo = () => ( | ||||||
|     <Info> |     <Info> | ||||||
|       <div> |       <div> | ||||||
|         <div className='font-weight-bold'>The sub your post will go in ...</div> |         <div className='fw-bold'>The sub your post will go in ...</div> | ||||||
|         <ul> |         <ul> | ||||||
|           <li>If it's bitcoin related, put it in the bitcoin sub.</li> |           <li>If it's bitcoin related, put it in the bitcoin sub.</li> | ||||||
|           <li>If it's nostr related, put it in the nostr sub.</li> |           <li>If it's nostr related, put it in the nostr sub.</li> | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import { useMutation } from '@apollo/client' | import { useMutation } from '@apollo/client' | ||||||
| import { gql } from 'graphql-tag' | import { gql } from 'graphql-tag' | ||||||
| import { Dropdown } from 'react-bootstrap' | import Dropdown from 'react-bootstrap/Dropdown' | ||||||
| 
 | 
 | ||||||
| export default function SubscribeDropdownItem ({ item: { id, meSubscription } }) { | export default function SubscribeDropdownItem ({ item: { id, meSubscription } }) { | ||||||
|   const [subscribeItem] = useMutation( |   const [subscribeItem] = useMutation( | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| import React, { useMemo, useState } from 'react' | import React, { useMemo, useState } from 'react' | ||||||
| import { Dropdown, FormControl } from 'react-bootstrap' | import Dropdown from 'react-bootstrap/Dropdown' | ||||||
|  | import FormControl from 'react-bootstrap/FormControl' | ||||||
| import TocIcon from '../svgs/list-unordered.svg' | import TocIcon from '../svgs/list-unordered.svg' | ||||||
| import { fromMarkdown } from 'mdast-util-from-markdown' | import { fromMarkdown } from 'mdast-util-from-markdown' | ||||||
| import { visit } from 'unist-util-visit' | import { visit } from 'unist-util-visit' | ||||||
| @ -27,7 +28,7 @@ export default function Toc ({ text }) { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Dropdown alignRight className='d-flex align-items-center'> |     <Dropdown align='end' className='d-flex align-items-center'> | ||||||
|       <Dropdown.Toggle as={CustomToggle} id='dropdown-custom-components'> |       <Dropdown.Toggle as={CustomToggle} id='dropdown-custom-components'> | ||||||
|         <TocIcon width={20} height={20} className='mx-2 fill-grey theme' /> |         <TocIcon width={20} height={20} className='mx-2 fill-grey theme' /> | ||||||
|       </Dropdown.Toggle> |       </Dropdown.Toggle> | ||||||
| @ -36,7 +37,7 @@ export default function Toc ({ text }) { | |||||||
|         {toc.map(v => { |         {toc.map(v => { | ||||||
|           return ( |           return ( | ||||||
|             <Dropdown.Item |             <Dropdown.Item | ||||||
|               className={v.depth === 1 ? 'font-weight-bold' : ''} |               className={v.depth === 1 ? 'fw-bold' : ''} | ||||||
|               style={{ |               style={{ | ||||||
|                 marginLeft: `${(v.depth - 1) * 5}px` |                 marginLeft: `${(v.depth - 1) * 5}px` | ||||||
|               }} |               }} | ||||||
|  | |||||||
| @ -201,8 +201,8 @@ export function ZoomableImage ({ src, topLevel, ...props }) { | |||||||
|   if (!src) return null |   if (!src) return null | ||||||
|   if (err) { |   if (err) { | ||||||
|     return ( |     return ( | ||||||
|       <span className='d-flex align-items-center text-warning font-weight-bold pb-1'> |       <span className='d-flex align-items-center text-warning fw-bold pb-1'> | ||||||
|         <FileMissing width={18} height={18} className='fill-warning mr-1' /> |         <FileMissing width={18} height={18} className='fill-warning me-1' /> | ||||||
|         broken image <small>stacker probably used an unreliable host</small> |         broken image <small>stacker probably used an unreliable host</small> | ||||||
|       </span> |       </span> | ||||||
|     ) |     ) | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ export default function TopHeader ({ sub, cat }) { | |||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex'> |     <div className='d-flex'> | ||||||
|       <Form |       <Form | ||||||
|         className='mr-auto' |         className='me-auto' | ||||||
|         initial={{ |         initial={{ | ||||||
|           what: cat, |           what: cat, | ||||||
|           by: router.query.by || '', |           by: router.query.by || '', | ||||||
| @ -42,7 +42,7 @@ export default function TopHeader ({ sub, cat }) { | |||||||
|         }} |         }} | ||||||
|         onSubmit={top} |         onSubmit={top} | ||||||
|       > |       > | ||||||
|         <div className='text-muted font-weight-bold my-3 d-flex align-items-center'> |         <div className='text-muted fw-bold my-3 d-flex align-items-center'> | ||||||
|           top |           top | ||||||
|           <Select |           <Select | ||||||
|             groupClassName='mx-2 mb-0' |             groupClassName='mx-2 mb-0' | ||||||
| @ -63,7 +63,7 @@ export default function TopHeader ({ sub, cat }) { | |||||||
|               /> |               /> | ||||||
|               for |               for | ||||||
|               <Select |               <Select | ||||||
|                 groupClassName='mb-0 ml-2' |                 groupClassName='mb-0 ms-2' | ||||||
|                 onChange={(formik, e) => top({ ...formik?.values, when: e.target.value })} |                 onChange={(formik, e) => top({ ...formik?.values, when: e.target.value })} | ||||||
|                 name='when' |                 name='when' | ||||||
|                 size='sm' |                 size='sm' | ||||||
|  | |||||||
| @ -8,14 +8,15 @@ import { useMe } from './me' | |||||||
| import Rainbow from '../lib/rainbow' | import Rainbow from '../lib/rainbow' | ||||||
| import { useCallback, useEffect, useMemo, useRef, useState } from 'react' | import { useCallback, useEffect, useMemo, useRef, useState } from 'react' | ||||||
| import LongPressable from 'react-longpressable' | import LongPressable from 'react-longpressable' | ||||||
| import { Overlay, Popover } from 'react-bootstrap' | import Overlay from 'react-bootstrap/Overlay' | ||||||
|  | import Popover from 'react-bootstrap/Popover' | ||||||
| import { useShowModal } from './modal' | import { useShowModal } from './modal' | ||||||
| import { useRouter } from 'next/router' | import { useRouter } from 'next/router' | ||||||
| import { LightningConsumer } from './lightning' | import { LightningConsumer } from './lightning' | ||||||
| 
 | 
 | ||||||
| const getColor = (meSats) => { | const getColor = (meSats) => { | ||||||
|   if (!meSats || meSats <= 10) { |   if (!meSats || meSats <= 10) { | ||||||
|     return 'var(--secondary)' |     return 'var(--bs-secondary)' | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const idx = Math.min( |   const idx = Math.min( | ||||||
| @ -33,13 +34,13 @@ const UpvotePopover = ({ target, show, handleClose }) => { | |||||||
|       placement='right' |       placement='right' | ||||||
|     > |     > | ||||||
|       <Popover id='popover-basic'> |       <Popover id='popover-basic'> | ||||||
|         <Popover.Title className='d-flex justify-content-between alert-dismissible' as='h3'>Zapping |         <Popover.Body className='d-flex justify-content-between alert-dismissible' as='h3'>Zapping | ||||||
|           <button type='button' className='close' onClick={handleClose}><span aria-hidden='true'>×</span><span className='sr-only'>Close alert</span></button> |           <button type='button' className='close' onClick={handleClose}><span aria-hidden='true'>×</span><span className='sr-only'>Close alert</span></button> | ||||||
|         </Popover.Title> |         </Popover.Body> | ||||||
|         <Popover.Content> |         <Popover.Body> | ||||||
|           <div className='mb-2'>Press the bolt again to zap {me?.tipDefault || 1} more sat{me?.tipDefault > 1 ? 's' : ''}.</div> |           <div className='mb-2'>Press the bolt again to zap {me?.tipDefault || 1} more sat{me?.tipDefault > 1 ? 's' : ''}.</div> | ||||||
|           <div>Repeatedly press the bolt to zap more sats.</div> |           <div>Repeatedly press the bolt to zap more sats.</div> | ||||||
|         </Popover.Content> |         </Popover.Body> | ||||||
|       </Popover> |       </Popover> | ||||||
|     </Overlay> |     </Overlay> | ||||||
|   ) |   ) | ||||||
| @ -52,13 +53,13 @@ const TipPopover = ({ target, show, handleClose }) => ( | |||||||
|     placement='right' |     placement='right' | ||||||
|   > |   > | ||||||
|     <Popover id='popover-basic'> |     <Popover id='popover-basic'> | ||||||
|       <Popover.Title className='d-flex justify-content-between alert-dismissible' as='h3'>Press and hold |       <Popover.Body className='d-flex justify-content-between alert-dismissible' as='h3'>Press and hold | ||||||
|         <button type='button' className='close' onClick={handleClose}><span aria-hidden='true'>×</span><span className='sr-only'>Close alert</span></button> |         <button type='button' className='close' onClick={handleClose}><span aria-hidden='true'>×</span><span className='sr-only'>Close alert</span></button> | ||||||
|       </Popover.Title> |       </Popover.Body> | ||||||
|       <Popover.Content> |       <Popover.Body> | ||||||
|         <div className='mb-2'>Press and hold bolt to zap a custom amount.</div> |         <div className='mb-2'>Press and hold bolt to zap a custom amount.</div> | ||||||
|         <div>As you zap more, the bolt color follows the rainbow.</div> |         <div>As you zap more, the bolt color follows the rainbow.</div> | ||||||
|       </Popover.Content> |       </Popover.Body> | ||||||
|     </Popover> |     </Popover> | ||||||
|   </Overlay> |   </Overlay> | ||||||
| ) | ) | ||||||
|  | |||||||
| @ -11,10 +11,10 @@ export function UsageHeader () { | |||||||
|         when: router.query.when || 'day' |         when: router.query.when || 'day' | ||||||
|       }} |       }} | ||||||
|     > |     > | ||||||
|       <div className='text-muted font-weight-bold my-3 d-flex align-items-center'> |       <div className='text-muted fw-bold my-3 d-flex align-items-center'> | ||||||
|         stacker analytics for |         stacker analytics for | ||||||
|         <Select |         <Select | ||||||
|           groupClassName='mb-0 ml-2' |           groupClassName='mb-0 ms-2' | ||||||
|           className='w-auto' |           className='w-auto' | ||||||
|           name='when' |           name='when' | ||||||
|           size='sm' |           size='sm' | ||||||
|  | |||||||
| @ -1,4 +1,6 @@ | |||||||
| import { Button, InputGroup, Image } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
|  | import InputGroup from 'react-bootstrap/InputGroup' | ||||||
|  | import Image from 'react-bootstrap/Image' | ||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| import { useRouter } from 'next/router' | import { useRouter } from 'next/router' | ||||||
| import Nav from 'react-bootstrap/Nav' | import Nav from 'react-bootstrap/Nav' | ||||||
| @ -158,23 +160,23 @@ function HeaderHeader ({ user }) { | |||||||
|   const showModal = useShowModal() |   const showModal = useShowModal() | ||||||
| 
 | 
 | ||||||
|   const isMe = me?.name === user.name |   const isMe = me?.name === user.name | ||||||
|   const Satistics = () => <div className={`mb-2 ml-0 ml-sm-1 ${styles.username} text-success`}>{user.stacked} stacked</div> |   const Satistics = () => <div className={`mb-2 ms-0 ms-sm-1 ${styles.username} text-success`}>{user.stacked} stacked</div> | ||||||
| 
 | 
 | ||||||
|   const lnurlp = encodeLNUrl(new URL(`https://stacker.news/.well-known/lnurlp/${user.name}`)) |   const lnurlp = encodeLNUrl(new URL(`https://stacker.news/.well-known/lnurlp/${user.name}`)) | ||||||
|   return ( |   return ( | ||||||
|     <div className='d-flex mt-2 flex-wrap flex-column flex-sm-row'> |     <div className='d-flex mt-2 flex-wrap flex-column flex-sm-row'> | ||||||
|       <HeaderPhoto user={user} isMe={isMe} /> |       <HeaderPhoto user={user} isMe={isMe} /> | ||||||
|       <div className='ml-0 ml-sm-3 mt-3 mt-sm-0 justify-content-center align-self-sm-center'> |       <div className='ms-0 ms-sm-3 mt-3 mt-sm-0 justify-content-center align-self-sm-center'> | ||||||
|         <HeaderNym user={user} isMe={isMe} /> |         <HeaderNym user={user} isMe={isMe} /> | ||||||
|         <Satistics user={user} /> |         <Satistics user={user} /> | ||||||
|         <Button |         <Button | ||||||
|           className='font-weight-bold ml-0' onClick={() => { |           className='fw-bold ms-0' onClick={() => { | ||||||
|             showModal(({ onClose }) => ( |             showModal(({ onClose }) => ( | ||||||
|               <> |               <> | ||||||
|                 <a className='d-flex m-auto p-3' style={{ background: 'white', width: 'fit-content' }} href={`lightning:${lnurlp}`}> |                 <a className='d-flex m-auto p-3' style={{ background: 'white', width: 'fit-content' }} href={`lightning:${lnurlp}`}> | ||||||
|                   <QRCode className='d-flex m-auto' value={lnurlp} renderAs='svg' size={300} /> |                   <QRCode className='d-flex m-auto' value={lnurlp} renderAs='svg' size={300} /> | ||||||
|                 </a> |                 </a> | ||||||
|                 <div className='text-center font-weight-bold text-muted mt-3'>click or scan</div> |                 <div className='text-center fw-bold text-muted mt-3'>click or scan</div> | ||||||
|               </> |               </> | ||||||
|             )) |             )) | ||||||
|           }} |           }} | ||||||
| @ -182,12 +184,12 @@ function HeaderHeader ({ user }) { | |||||||
|           <LightningIcon |           <LightningIcon | ||||||
|             width={20} |             width={20} | ||||||
|             height={20} |             height={20} | ||||||
|             className='mr-1' |             className='me-1' | ||||||
|           />{user.name}@stacker.news |           />{user.name}@stacker.news | ||||||
|         </Button> |         </Button> | ||||||
|         <div className='d-flex flex-column mt-1 ml-0'> |         <div className='d-flex flex-column mt-1 ms-0'> | ||||||
|           <small className='text-muted d-flex-inline'>stacking since: {user.since |           <small className='text-muted d-flex-inline'>stacking since: {user.since | ||||||
|             ? <Link href={`/items/${user.since}`} className='ml-1'>#{user.since}</Link> |             ? <Link href={`/items/${user.since}`} className='ms-1'>#{user.since}</Link> | ||||||
|             : <span>never</span>} |             : <span>never</span>} | ||||||
|           </small> |           </small> | ||||||
|           <small className='text-muted d-flex-inline'>longest cowboy streak: {user.maxStreak !== null ? user.maxStreak : 'none'}</small> |           <small className='text-muted d-flex-inline'>longest cowboy streak: {user.maxStreak !== null ? user.maxStreak : 'none'}</small> | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .nav :global .active { | .nav :global .active { | ||||||
|     border-bottom: 2px solid var(--primary); |     border-bottom: 2px solid var(--bs-primary); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .userimg { | .userimg { | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import Link from 'next/link' | import Link from 'next/link' | ||||||
| import { Image } from 'react-bootstrap' | import Image from 'react-bootstrap/Image' | ||||||
| import { abbrNum } from '../lib/format' | import { abbrNum } from '../lib/format' | ||||||
| import CowboyHat from './cowboy-hat' | import CowboyHat from './cowboy-hat' | ||||||
| import styles from './item.module.css' | import styles from './item.module.css' | ||||||
| @ -67,12 +67,12 @@ export default function UserList ({ ssrData, query, variables, destructureData } | |||||||
|           <Link href={`/${user.name}`}> |           <Link href={`/${user.name}`}> | ||||||
|             <Image |             <Image | ||||||
|               src={user.photoId ? `https://${process.env.NEXT_PUBLIC_AWS_UPLOAD_BUCKET}.s3.amazonaws.com/${user.photoId}` : '/dorian400.jpg'} width='32' height='32' |               src={user.photoId ? `https://${process.env.NEXT_PUBLIC_AWS_UPLOAD_BUCKET}.s3.amazonaws.com/${user.photoId}` : '/dorian400.jpg'} width='32' height='32' | ||||||
|               className={`${userStyles.userimg} mr-2`} |               className={`${userStyles.userimg} me-2`} | ||||||
|             /> |             /> | ||||||
|           </Link> |           </Link> | ||||||
|           <div className={styles.hunk}> |           <div className={styles.hunk}> | ||||||
|             <Link href={`/${user.name}`} className={`${styles.title} d-inline-flex align-items-center text-reset`}> |             <Link href={`/${user.name}`} className={`${styles.title} d-inline-flex align-items-center text-reset`}> | ||||||
|               @{user.name}<CowboyHat className='ml-1 fill-grey' height={14} width={14} user={user} /> |               @{user.name}<CowboyHat className='ms-1 fill-grey' height={14} width={14} user={user} /> | ||||||
|             </Link> |             </Link> | ||||||
|             <div className={styles.other}> |             <div className={styles.other}> | ||||||
|               {statComps.map((Comp, i) => <Comp key={i} user={user} />)} |               {statComps.map((Comp, i) => <Comp key={i} user={user} />)} | ||||||
| @ -94,7 +94,7 @@ export function UsersSkeleton () { | |||||||
|         <Image |         <Image | ||||||
|           src={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/clouds.jpeg`} |           src={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/clouds.jpeg`} | ||||||
|           width='32' height='32' |           width='32' height='32' | ||||||
|           className={`${userStyles.userimg} clouds mr-2`} |           className={`${userStyles.userimg} clouds me-2`} | ||||||
|         /> |         /> | ||||||
|         <div className={styles.hunk}> |         <div className={styles.hunk}> | ||||||
|           <div className={`${styles.name} clouds text-reset`} /> |           <div className={`${styles.name} clouds text-reset`} /> | ||||||
|  | |||||||
| @ -42,12 +42,12 @@ const transformData = data => { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const COLORS = [ | const COLORS = [ | ||||||
|   'var(--secondary)', |   'var(--bs-secondary)', | ||||||
|   'var(--info)', |   'var(--bs-info)', | ||||||
|   'var(--success)', |   'var(--bs-success)', | ||||||
|   'var(--boost)', |   'var(--bs-boost)', | ||||||
|   'var(--theme-grey)', |   'var(--theme-grey)', | ||||||
|   'var(--danger)' |   'var(--bs-danger)' | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| export function WhenAreaChart ({ data }) { | export function WhenAreaChart ({ data }) { | ||||||
| @ -150,7 +150,7 @@ export function WhenComposedChart ({ data, lineNames, areaNames, barNames }) { | |||||||
|         <Tooltip labelFormatter={dateFormatter(when)} contentStyle={{ color: 'var(--theme-color)', backgroundColor: 'var(--theme-body)' }} /> |         <Tooltip labelFormatter={dateFormatter(when)} contentStyle={{ color: 'var(--theme-color)', backgroundColor: 'var(--theme-body)' }} /> | ||||||
|         <Legend /> |         <Legend /> | ||||||
|         {barNames?.map((v, i) => |         {barNames?.map((v, i) => | ||||||
|           <Bar yAxisId='right' key={v} type='monotone' dataKey={v} name={v} stroke='var(--info)' fill='var(--info)' />)} |           <Bar yAxisId='right' key={v} type='monotone' dataKey={v} name={v} stroke='var(--bs-info)' fill='var(--bs-info)' />)} | ||||||
|         {areaNames?.map((v, i) => |         {areaNames?.map((v, i) => | ||||||
|           <Area yAxisId='left' key={v} type='monotone' dataKey={v} name={v} stackId='1' stroke={COLORS[i]} fill={COLORS[i]} />)} |           <Area yAxisId='left' key={v} type='monotone' dataKey={v} name={v} stackId='1' stroke={COLORS[i]} fill={COLORS[i]} />)} | ||||||
|         {lineNames?.map((v, i) => |         {lineNames?.map((v, i) => | ||||||
|  | |||||||
							
								
								
									
										256
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										256
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -23,7 +23,7 @@ | |||||||
|         "babel-plugin-inline-react-svg": "^2.0.1", |         "babel-plugin-inline-react-svg": "^2.0.1", | ||||||
|         "bech32": "^2.0.0", |         "bech32": "^2.0.0", | ||||||
|         "bolt11": "^1.4.0", |         "bolt11": "^1.4.0", | ||||||
|         "bootstrap": "^4.6.2", |         "bootstrap": "^5.3.0", | ||||||
|         "browserslist": "^4.21.4", |         "browserslist": "^4.21.4", | ||||||
|         "canonical-json": "0.0.4", |         "canonical-json": "0.0.4", | ||||||
|         "clipboard-copy": "^4.0.1", |         "clipboard-copy": "^4.0.1", | ||||||
| @ -58,7 +58,7 @@ | |||||||
|         "qrcode.react": "^3.1.0", |         "qrcode.react": "^3.1.0", | ||||||
|         "react": "^18.2.0", |         "react": "^18.2.0", | ||||||
|         "react-avatar-editor": "^13.0.0", |         "react-avatar-editor": "^13.0.0", | ||||||
|         "react-bootstrap": "^1.6.6", |         "react-bootstrap": "^2.8.0", | ||||||
|         "react-countdown": "^2.3.3", |         "react-countdown": "^2.3.3", | ||||||
|         "react-dom": "^18.2.0", |         "react-dom": "^18.2.0", | ||||||
|         "react-longpressable": "^1.1.1", |         "react-longpressable": "^1.1.1", | ||||||
| @ -2859,9 +2859,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@popperjs/core": { |     "node_modules/@popperjs/core": { | ||||||
|       "version": "2.11.6", |       "version": "2.11.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", |       "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", | ||||||
|       "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", |       "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", | ||||||
|       "funding": { |       "funding": { | ||||||
|         "type": "opencollective", |         "type": "opencollective", | ||||||
|         "url": "https://opencollective.com/popperjs" |         "url": "https://opencollective.com/popperjs" | ||||||
| @ -2952,6 +2952,17 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", | ||||||
|       "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" |       "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@react-aria/ssr": { | ||||||
|  |       "version": "3.7.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.0.tgz", | ||||||
|  |       "integrity": "sha512-bfufjg4ESE5giN+Fxj1XIzS5f/YIhqcGc+Ve+vUUKU8xZ8t/Xtjlv8F3kjqDBQdk//n3mluFY7xG1wQVB9rMLQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@swc/helpers": "^0.5.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/@remusao/guess-url-type": { |     "node_modules/@remusao/guess-url-type": { | ||||||
|       "version": "1.2.1", |       "version": "1.2.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@remusao/guess-url-type/-/guess-url-type-1.2.1.tgz", |       "resolved": "https://registry.npmjs.org/@remusao/guess-url-type/-/guess-url-type-1.2.1.tgz", | ||||||
| @ -2989,25 +3000,45 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/@remusao/trie/-/trie-1.4.1.tgz", |       "resolved": "https://registry.npmjs.org/@remusao/trie/-/trie-1.4.1.tgz", | ||||||
|       "integrity": "sha512-yvwa+aCyYI/UjeD39BnpMypG8N06l86wIDW1/PAc6ihBRnodIfZDwccxQN3n1t74wduzaz74m4ZMHZnB06567Q==" |       "integrity": "sha512-yvwa+aCyYI/UjeD39BnpMypG8N06l86wIDW1/PAc6ihBRnodIfZDwccxQN3n1t74wduzaz74m4ZMHZnB06567Q==" | ||||||
|     }, |     }, | ||||||
|     "node_modules/@restart/context": { |  | ||||||
|       "version": "2.1.4", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", |  | ||||||
|       "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", |  | ||||||
|       "peerDependencies": { |  | ||||||
|         "react": ">=16.3.2" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@restart/hooks": { |     "node_modules/@restart/hooks": { | ||||||
|       "version": "0.4.7", |       "version": "0.4.11", | ||||||
|       "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.7.tgz", |       "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", | ||||||
|       "integrity": "sha512-ZbjlEHcG+FQtpDPHd7i4FzNNvJf2enAwZfJbpM8CW7BhmOAbsHpZe3tsHwfQUrBuyrxWqPYp2x5UMnilWcY22A==", |       "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "dequal": "^2.0.2" |         "dequal": "^2.0.3" | ||||||
|       }, |       }, | ||||||
|       "peerDependencies": { |       "peerDependencies": { | ||||||
|         "react": ">=16.8.0" |         "react": ">=16.8.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@restart/ui": { | ||||||
|  |       "version": "1.6.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", | ||||||
|  |       "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@babel/runtime": "^7.21.0", | ||||||
|  |         "@popperjs/core": "^2.11.6", | ||||||
|  |         "@react-aria/ssr": "^3.5.0", | ||||||
|  |         "@restart/hooks": "^0.4.9", | ||||||
|  |         "@types/warning": "^3.0.0", | ||||||
|  |         "dequal": "^2.0.3", | ||||||
|  |         "dom-helpers": "^5.2.0", | ||||||
|  |         "uncontrollable": "^8.0.1", | ||||||
|  |         "warning": "^4.0.3" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "react": ">=16.14.0", | ||||||
|  |         "react-dom": ">=16.14.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@restart/ui/node_modules/uncontrollable": { | ||||||
|  |       "version": "8.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.2.tgz", | ||||||
|  |       "integrity": "sha512-/GDx+K1STGtpgTsj5Dj3J51YaKxZDblbCQHTH1zHLuoBEWodj6MjtRVv3TUijj1JYLRLSFsFzN8NV4M3QV4d9w==", | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "react": ">=16.14.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/@rollup/plugin-babel": { |     "node_modules/@rollup/plugin-babel": { | ||||||
|       "version": "5.3.1", |       "version": "5.3.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", |       "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", | ||||||
| @ -3475,11 +3506,6 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", |       "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", | ||||||
|       "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" |       "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" | ||||||
|     }, |     }, | ||||||
|     "node_modules/@types/invariant": { |  | ||||||
|       "version": "2.2.35", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", |  | ||||||
|       "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==" |  | ||||||
|     }, |  | ||||||
|     "node_modules/@types/json-schema": { |     "node_modules/@types/json-schema": { | ||||||
|       "version": "7.0.12", |       "version": "7.0.12", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", |       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", | ||||||
| @ -4903,9 +4929,9 @@ | |||||||
|       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" |       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" | ||||||
|     }, |     }, | ||||||
|     "node_modules/bootstrap": { |     "node_modules/bootstrap": { | ||||||
|       "version": "4.6.2", |       "version": "5.3.0", | ||||||
|       "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", |       "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz", | ||||||
|       "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==", |       "integrity": "sha512-UnBV3E3v4STVNQdms6jSGO2CvOkjUMdDAVR2V5N4uCMdaIkaQjbcEAMqRimDHIs4uqBYzDAKCQwCB+97tJgHQw==", | ||||||
|       "funding": [ |       "funding": [ | ||||||
|         { |         { | ||||||
|           "type": "github", |           "type": "github", | ||||||
| @ -4917,8 +4943,7 @@ | |||||||
|         } |         } | ||||||
|       ], |       ], | ||||||
|       "peerDependencies": { |       "peerDependencies": { | ||||||
|         "jquery": "1.9.1 - 3", |         "@popperjs/core": "^2.11.7" | ||||||
|         "popper.js": "^1.16.1" |  | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/bplist-parser": { |     "node_modules/bplist-parser": { | ||||||
| @ -14227,31 +14252,42 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/react-bootstrap": { |     "node_modules/react-bootstrap": { | ||||||
|       "version": "1.6.6", |       "version": "2.8.0", | ||||||
|       "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.6.tgz", |       "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", | ||||||
|       "integrity": "sha512-pSzYyJT5u4rc8+5myM8Vid2JG52L8AmYSkpznReH/GM4+FhLqEnxUa0+6HRTaGwjdEixQNGchwY+b3xCdYWrDA==", |       "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@babel/runtime": "^7.14.0", |         "@babel/runtime": "^7.21.0", | ||||||
|         "@restart/context": "^2.1.4", |         "@restart/hooks": "^0.4.9", | ||||||
|         "@restart/hooks": "^0.4.7", |         "@restart/ui": "^1.6.3", | ||||||
|         "@types/invariant": "^2.2.33", |         "@types/react-transition-group": "^4.4.5", | ||||||
|         "@types/prop-types": "^15.7.3", |         "classnames": "^2.3.2", | ||||||
|         "@types/react": ">=16.14.8", |  | ||||||
|         "@types/react-transition-group": "^4.4.1", |  | ||||||
|         "@types/warning": "^3.0.0", |  | ||||||
|         "classnames": "^2.3.1", |  | ||||||
|         "dom-helpers": "^5.2.1", |         "dom-helpers": "^5.2.1", | ||||||
|         "invariant": "^2.2.4", |         "invariant": "^2.2.4", | ||||||
|         "prop-types": "^15.7.2", |         "prop-types": "^15.8.1", | ||||||
|         "prop-types-extra": "^1.1.0", |         "prop-types-extra": "^1.1.0", | ||||||
|         "react-overlays": "^5.1.2", |         "react-transition-group": "^4.4.5", | ||||||
|         "react-transition-group": "^4.4.1", |  | ||||||
|         "uncontrollable": "^7.2.1", |         "uncontrollable": "^7.2.1", | ||||||
|         "warning": "^4.0.3" |         "warning": "^4.0.3" | ||||||
|       }, |       }, | ||||||
|       "peerDependencies": { |       "peerDependencies": { | ||||||
|         "react": ">=16.8.0", |         "@types/react": ">=16.14.8", | ||||||
|         "react-dom": ">=16.8.0" |         "react": ">=16.14.0", | ||||||
|  |         "react-dom": ">=16.14.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependenciesMeta": { | ||||||
|  |         "@types/react": { | ||||||
|  |           "optional": true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/react-bootstrap/node_modules/prop-types": { | ||||||
|  |       "version": "15.8.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", | ||||||
|  |       "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "loose-envify": "^1.4.0", | ||||||
|  |         "object-assign": "^4.1.1", | ||||||
|  |         "react-is": "^16.13.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/react-countdown": { |     "node_modules/react-countdown": { | ||||||
| @ -14337,25 +14373,6 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", |       "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", | ||||||
|       "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" |       "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" | ||||||
|     }, |     }, | ||||||
|     "node_modules/react-overlays": { |  | ||||||
|       "version": "5.2.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", |  | ||||||
|       "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", |  | ||||||
|       "dependencies": { |  | ||||||
|         "@babel/runtime": "^7.13.8", |  | ||||||
|         "@popperjs/core": "^2.11.6", |  | ||||||
|         "@restart/hooks": "^0.4.7", |  | ||||||
|         "@types/warning": "^3.0.0", |  | ||||||
|         "dom-helpers": "^5.2.0", |  | ||||||
|         "prop-types": "^15.7.2", |  | ||||||
|         "uncontrollable": "^7.2.1", |  | ||||||
|         "warning": "^4.0.3" |  | ||||||
|       }, |  | ||||||
|       "peerDependencies": { |  | ||||||
|         "react": ">=16.3.0", |  | ||||||
|         "react-dom": ">=16.3.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/react-resize-detector": { |     "node_modules/react-resize-detector": { | ||||||
|       "version": "8.1.0", |       "version": "8.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-8.1.0.tgz", |       "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-8.1.0.tgz", | ||||||
| @ -20797,9 +20814,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@popperjs/core": { |     "@popperjs/core": { | ||||||
|       "version": "2.11.6", |       "version": "2.11.8", | ||||||
|       "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", |       "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", | ||||||
|       "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" |       "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" | ||||||
|     }, |     }, | ||||||
|     "@prisma/client": { |     "@prisma/client": { | ||||||
|       "version": "2.30.3", |       "version": "2.30.3", | ||||||
| @ -20873,6 +20890,14 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", | ||||||
|       "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" |       "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" | ||||||
|     }, |     }, | ||||||
|  |     "@react-aria/ssr": { | ||||||
|  |       "version": "3.7.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.0.tgz", | ||||||
|  |       "integrity": "sha512-bfufjg4ESE5giN+Fxj1XIzS5f/YIhqcGc+Ve+vUUKU8xZ8t/Xtjlv8F3kjqDBQdk//n3mluFY7xG1wQVB9rMLQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "@swc/helpers": "^0.5.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "@remusao/guess-url-type": { |     "@remusao/guess-url-type": { | ||||||
|       "version": "1.2.1", |       "version": "1.2.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@remusao/guess-url-type/-/guess-url-type-1.2.1.tgz", |       "resolved": "https://registry.npmjs.org/@remusao/guess-url-type/-/guess-url-type-1.2.1.tgz", | ||||||
| @ -20910,17 +20935,35 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/@remusao/trie/-/trie-1.4.1.tgz", |       "resolved": "https://registry.npmjs.org/@remusao/trie/-/trie-1.4.1.tgz", | ||||||
|       "integrity": "sha512-yvwa+aCyYI/UjeD39BnpMypG8N06l86wIDW1/PAc6ihBRnodIfZDwccxQN3n1t74wduzaz74m4ZMHZnB06567Q==" |       "integrity": "sha512-yvwa+aCyYI/UjeD39BnpMypG8N06l86wIDW1/PAc6ihBRnodIfZDwccxQN3n1t74wduzaz74m4ZMHZnB06567Q==" | ||||||
|     }, |     }, | ||||||
|     "@restart/context": { |  | ||||||
|       "version": "2.1.4", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", |  | ||||||
|       "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==" |  | ||||||
|     }, |  | ||||||
|     "@restart/hooks": { |     "@restart/hooks": { | ||||||
|       "version": "0.4.7", |       "version": "0.4.11", | ||||||
|       "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.7.tgz", |       "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", | ||||||
|       "integrity": "sha512-ZbjlEHcG+FQtpDPHd7i4FzNNvJf2enAwZfJbpM8CW7BhmOAbsHpZe3tsHwfQUrBuyrxWqPYp2x5UMnilWcY22A==", |       "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "dequal": "^2.0.2" |         "dequal": "^2.0.3" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "@restart/ui": { | ||||||
|  |       "version": "1.6.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", | ||||||
|  |       "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", | ||||||
|  |       "requires": { | ||||||
|  |         "@babel/runtime": "^7.21.0", | ||||||
|  |         "@popperjs/core": "^2.11.6", | ||||||
|  |         "@react-aria/ssr": "^3.5.0", | ||||||
|  |         "@restart/hooks": "^0.4.9", | ||||||
|  |         "@types/warning": "^3.0.0", | ||||||
|  |         "dequal": "^2.0.3", | ||||||
|  |         "dom-helpers": "^5.2.0", | ||||||
|  |         "uncontrollable": "^8.0.1", | ||||||
|  |         "warning": "^4.0.3" | ||||||
|  |       }, | ||||||
|  |       "dependencies": { | ||||||
|  |         "uncontrollable": { | ||||||
|  |           "version": "8.0.2", | ||||||
|  |           "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.2.tgz", | ||||||
|  |           "integrity": "sha512-/GDx+K1STGtpgTsj5Dj3J51YaKxZDblbCQHTH1zHLuoBEWodj6MjtRVv3TUijj1JYLRLSFsFzN8NV4M3QV4d9w==" | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@rollup/plugin-babel": { |     "@rollup/plugin-babel": { | ||||||
| @ -21347,11 +21390,6 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", |       "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", | ||||||
|       "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" |       "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" | ||||||
|     }, |     }, | ||||||
|     "@types/invariant": { |  | ||||||
|       "version": "2.2.35", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", |  | ||||||
|       "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==" |  | ||||||
|     }, |  | ||||||
|     "@types/json-schema": { |     "@types/json-schema": { | ||||||
|       "version": "7.0.12", |       "version": "7.0.12", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", |       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", | ||||||
| @ -22521,9 +22559,9 @@ | |||||||
|       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" |       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" | ||||||
|     }, |     }, | ||||||
|     "bootstrap": { |     "bootstrap": { | ||||||
|       "version": "4.6.2", |       "version": "5.3.0", | ||||||
|       "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", |       "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.0.tgz", | ||||||
|       "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==" |       "integrity": "sha512-UnBV3E3v4STVNQdms6jSGO2CvOkjUMdDAVR2V5N4uCMdaIkaQjbcEAMqRimDHIs4uqBYzDAKCQwCB+97tJgHQw==" | ||||||
|     }, |     }, | ||||||
|     "bplist-parser": { |     "bplist-parser": { | ||||||
|       "version": "0.2.0", |       "version": "0.2.0", | ||||||
| @ -29311,27 +29349,34 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "react-bootstrap": { |     "react-bootstrap": { | ||||||
|       "version": "1.6.6", |       "version": "2.8.0", | ||||||
|       "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.6.tgz", |       "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", | ||||||
|       "integrity": "sha512-pSzYyJT5u4rc8+5myM8Vid2JG52L8AmYSkpznReH/GM4+FhLqEnxUa0+6HRTaGwjdEixQNGchwY+b3xCdYWrDA==", |       "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@babel/runtime": "^7.14.0", |         "@babel/runtime": "^7.21.0", | ||||||
|         "@restart/context": "^2.1.4", |         "@restart/hooks": "^0.4.9", | ||||||
|         "@restart/hooks": "^0.4.7", |         "@restart/ui": "^1.6.3", | ||||||
|         "@types/invariant": "^2.2.33", |         "@types/react-transition-group": "^4.4.5", | ||||||
|         "@types/prop-types": "^15.7.3", |         "classnames": "^2.3.2", | ||||||
|         "@types/react": ">=16.14.8", |  | ||||||
|         "@types/react-transition-group": "^4.4.1", |  | ||||||
|         "@types/warning": "^3.0.0", |  | ||||||
|         "classnames": "^2.3.1", |  | ||||||
|         "dom-helpers": "^5.2.1", |         "dom-helpers": "^5.2.1", | ||||||
|         "invariant": "^2.2.4", |         "invariant": "^2.2.4", | ||||||
|         "prop-types": "^15.7.2", |         "prop-types": "^15.8.1", | ||||||
|         "prop-types-extra": "^1.1.0", |         "prop-types-extra": "^1.1.0", | ||||||
|         "react-overlays": "^5.1.2", |         "react-transition-group": "^4.4.5", | ||||||
|         "react-transition-group": "^4.4.1", |  | ||||||
|         "uncontrollable": "^7.2.1", |         "uncontrollable": "^7.2.1", | ||||||
|         "warning": "^4.0.3" |         "warning": "^4.0.3" | ||||||
|  |       }, | ||||||
|  |       "dependencies": { | ||||||
|  |         "prop-types": { | ||||||
|  |           "version": "15.8.1", | ||||||
|  |           "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", | ||||||
|  |           "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", | ||||||
|  |           "requires": { | ||||||
|  |             "loose-envify": "^1.4.0", | ||||||
|  |             "object-assign": "^4.1.1", | ||||||
|  |             "react-is": "^16.13.1" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "react-countdown": { |     "react-countdown": { | ||||||
| @ -29400,21 +29445,6 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "react-overlays": { |  | ||||||
|       "version": "5.2.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", |  | ||||||
|       "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", |  | ||||||
|       "requires": { |  | ||||||
|         "@babel/runtime": "^7.13.8", |  | ||||||
|         "@popperjs/core": "^2.11.6", |  | ||||||
|         "@restart/hooks": "^0.4.7", |  | ||||||
|         "@types/warning": "^3.0.0", |  | ||||||
|         "dom-helpers": "^5.2.0", |  | ||||||
|         "prop-types": "^15.7.2", |  | ||||||
|         "uncontrollable": "^7.2.1", |  | ||||||
|         "warning": "^4.0.3" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "react-resize-detector": { |     "react-resize-detector": { | ||||||
|       "version": "8.1.0", |       "version": "8.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-8.1.0.tgz", |       "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-8.1.0.tgz", | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ | |||||||
|     "babel-plugin-inline-react-svg": "^2.0.1", |     "babel-plugin-inline-react-svg": "^2.0.1", | ||||||
|     "bech32": "^2.0.0", |     "bech32": "^2.0.0", | ||||||
|     "bolt11": "^1.4.0", |     "bolt11": "^1.4.0", | ||||||
|     "bootstrap": "^4.6.2", |     "bootstrap": "^5.3.0", | ||||||
|     "browserslist": "^4.21.4", |     "browserslist": "^4.21.4", | ||||||
|     "canonical-json": "0.0.4", |     "canonical-json": "0.0.4", | ||||||
|     "clipboard-copy": "^4.0.1", |     "clipboard-copy": "^4.0.1", | ||||||
| @ -59,7 +59,7 @@ | |||||||
|     "qrcode.react": "^3.1.0", |     "qrcode.react": "^3.1.0", | ||||||
|     "react": "^18.2.0", |     "react": "^18.2.0", | ||||||
|     "react-avatar-editor": "^13.0.0", |     "react-avatar-editor": "^13.0.0", | ||||||
|     "react-bootstrap": "^1.6.6", |     "react-bootstrap": "^2.8.0", | ||||||
|     "react-countdown": "^2.3.3", |     "react-countdown": "^2.3.3", | ||||||
|     "react-dom": "^18.2.0", |     "react-dom": "^18.2.0", | ||||||
|     "react-longpressable": "^1.1.1", |     "react-longpressable": "^1.1.1", | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Image } from 'react-bootstrap' | import Image from 'react-bootstrap/Image' | ||||||
| import { StaticLayout } from '../components/layout' | import { StaticLayout } from '../components/layout' | ||||||
| import styles from '../styles/404.module.css' | import styles from '../styles/404.module.css' | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Image } from 'react-bootstrap' | import Image from 'react-bootstrap/Image' | ||||||
| import { StaticLayout } from '../components/layout' | import { StaticLayout } from '../components/layout' | ||||||
| import styles from '../styles/404.module.css' | import styles from '../styles/404.module.css' | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -60,9 +60,9 @@ function UserItemsHeader ({ type, name }) { | |||||||
|       }} |       }} | ||||||
|       onSubmit={select} |       onSubmit={select} | ||||||
|     > |     > | ||||||
|       <div className='text-muted font-weight-bold mt-0 mb-3 d-flex justify-content-start align-items-center'> |       <div className='text-muted fw-bold mt-0 mb-3 d-flex justify-content-start align-items-center'> | ||||||
|         <Select |         <Select | ||||||
|           groupClassName='mb-0 mr-2' |           groupClassName='mb-0 me-2' | ||||||
|           className='w-auto' |           className='w-auto' | ||||||
|           name='type' |           name='type' | ||||||
|           size='sm' |           size='sm' | ||||||
| @ -80,7 +80,7 @@ function UserItemsHeader ({ type, name }) { | |||||||
|         /> |         /> | ||||||
|         for |         for | ||||||
|         <Select |         <Select | ||||||
|           groupClassName='mb-0 ml-2' |           groupClassName='mb-0 ms-2' | ||||||
|           className='w-auto' |           className='w-auto' | ||||||
|           name='when' |           name='when' | ||||||
|           size='sm' |           size='sm' | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import Layout from '../../components/layout' | import Layout from '../../components/layout' | ||||||
| import { gql, useMutation, useQuery } from '@apollo/client' | import { gql, useMutation, useQuery } from '@apollo/client' | ||||||
| import UserHeader from '../../components/user-header' | import UserHeader from '../../components/user-header' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import styles from '../../styles/user.module.css' | import styles from '../../styles/user.module.css' | ||||||
| import { useState } from 'react' | import { useState } from 'react' | ||||||
| import ItemFull from '../../components/item-full' | import ItemFull from '../../components/item-full' | ||||||
|  | |||||||
| @ -14,14 +14,16 @@ import ErrorBoundary from '../components/error-boundary' | |||||||
| import { LightningProvider } from '../components/lightning' | import { LightningProvider } from '../components/lightning' | ||||||
| import { ServiceWorkerProvider } from '../components/serviceworker' | import { ServiceWorkerProvider } from '../components/serviceworker' | ||||||
| 
 | 
 | ||||||
|  | const SSR = typeof window === 'undefined' | ||||||
|  | 
 | ||||||
| function writeQuery (client, apollo, data) { | function writeQuery (client, apollo, data) { | ||||||
|   if (apollo && data) { |   if (apollo && data) { | ||||||
|     client.writeQuery({ |     client.writeQuery({ | ||||||
|       query: gql`${apollo.query}`, |       query: gql`${apollo.query}`, | ||||||
|       data: data, |       data: data, | ||||||
|       variables: apollo.variables, |       variables: apollo.variables, | ||||||
|       broadcast: false, |       broadcast: !SSR, | ||||||
|       overwrite: true |       overwrite: SSR | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -54,7 +56,7 @@ function MyApp ({ Component, pageProps: { session, ...props } }) { | |||||||
|   */ |   */ | ||||||
|   const { apollo, ssrData, me, price, ...otherProps } = props |   const { apollo, ssrData, me, price, ...otherProps } = props | ||||||
|   // if we are on the server, useEffect won't run
 |   // if we are on the server, useEffect won't run
 | ||||||
|   if (typeof window === 'undefined' && client) { |   if (SSR && client) { | ||||||
|     writeQuery(client, apollo, ssrData) |     writeQuery(client, apollo, ssrData) | ||||||
|   } |   } | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
| @ -64,7 +66,7 @@ function MyApp ({ Component, pageProps: { session, ...props } }) { | |||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       <NextNProgress |       <NextNProgress | ||||||
|         color='var(--primary)' |         color='var(--bs-primary)' | ||||||
|         startPosition={0.3} |         startPosition={0.3} | ||||||
|         stopDelayMs={200} |         stopDelayMs={200} | ||||||
|         height={2} |         height={2} | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Image } from 'react-bootstrap' | import Image from 'react-bootstrap/Image' | ||||||
| import { StaticLayout } from '../components/layout' | import { StaticLayout } from '../components/layout' | ||||||
| 
 | 
 | ||||||
| export default function Email () { | export default function Email () { | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import Layout from '../../components/layout' | import Layout from '../../components/layout' | ||||||
| import { Form, Input, SubmitButton } from '../../components/form' | import { Form, Input, SubmitButton } from '../../components/form' | ||||||
| import { InputGroup } from 'react-bootstrap' | import InputGroup from 'react-bootstrap/InputGroup' | ||||||
| import { gql, useMutation, useQuery } from '@apollo/client' | import { gql, useMutation, useQuery } from '@apollo/client' | ||||||
| import { INVITE_FIELDS } from '../../fragments/invites' | import { INVITE_FIELDS } from '../../fragments/invites' | ||||||
| import AccordianItem from '../../components/accordian-item' | import AccordianItem from '../../components/accordian-item' | ||||||
| @ -58,7 +58,7 @@ function InviteForm () { | |||||||
|         required |         required | ||||||
|       /> |       /> | ||||||
|       <Input |       <Input | ||||||
|         label={<>invitee limit <small className='text-muted ml-2'>optional</small></>} |         label={<>invitee limit <small className='text-muted ms-2'>optional</small></>} | ||||||
|         name='limit' |         name='limit' | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
| @ -113,7 +113,7 @@ export default function Invites () { | |||||||
|         <h2 className='mt-3 mb-0'> |         <h2 className='mt-3 mb-0'> | ||||||
|           invite links |           invite links | ||||||
|         </h2> |         </h2> | ||||||
|         <small className='d-block text-muted font-weight-bold mx-5'>send these to people you trust, e.g. group chats or DMs</small> |         <small className='d-block text-muted fw-bold mx-5'>send these to people you trust, e.g. group chats or DMs</small> | ||||||
|       </div> |       </div> | ||||||
|       <InviteForm /> |       <InviteForm /> | ||||||
|       {active.length > 0 && <InviteList name='active' invites={active} />} |       {active.length > 0 && <InviteList name='active' invites={active} />} | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ import Layout from '../../../components/layout' | |||||||
| import { ITEM_OTS } from '../../../fragments/items' | import { ITEM_OTS } from '../../../fragments/items' | ||||||
| import { getGetServerSideProps } from '../../../api/ssrApollo' | import { getGetServerSideProps } from '../../../api/ssrApollo' | ||||||
| import stringifyCanon from 'canonical-json' | import stringifyCanon from 'canonical-json' | ||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import { useQuery } from '@apollo/client' | import { useQuery } from '@apollo/client' | ||||||
| import { useRouter } from 'next/router' | import { useRouter } from 'next/router' | ||||||
| import PageLoading from '../../../components/page-loading' | import PageLoading from '../../../components/page-loading' | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ export default function Related ({ ssrData }) { | |||||||
|   return ( |   return ( | ||||||
|     <Layout> |     <Layout> | ||||||
|       <Item item={item} /> |       <Item item={item} /> | ||||||
|       <div className='font-weight-bold my-2'>related</div> |       <div className='fw-bold my-2'>related</div> | ||||||
|       <Items |       <Items | ||||||
|         ssrData={ssrData} |         ssrData={ssrData} | ||||||
|         query={RELATED_ITEMS} |         query={RELATED_ITEMS} | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Button } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
| import { CenterLayout } from '../components/layout' | import { CenterLayout } from '../components/layout' | ||||||
| import Snl from '../components/snl' | import Snl from '../components/snl' | ||||||
| import { gql } from 'graphql-tag' | import { gql } from 'graphql-tag' | ||||||
|  | |||||||
| @ -39,7 +39,7 @@ export async function getServerSideProps ({ req, res, query: { callbackUrl, erro | |||||||
| 
 | 
 | ||||||
| function LoginFooter ({ callbackUrl }) { | function LoginFooter ({ callbackUrl }) { | ||||||
|   return ( |   return ( | ||||||
|     <small className='font-weight-bold text-muted pt-4'>Don't have an account? <Link href={{ pathname: '/signup', query: { callbackUrl } }}>sign up</Link></small> |     <small className='fw-bold text-muted pt-4'>Don't have an account? <Link href={{ pathname: '/signup', query: { callbackUrl } }}>sign up</Link></small> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Image } from 'react-bootstrap' | import Image from 'react-bootstrap/Image' | ||||||
| import { StaticLayout } from '../components/layout' | import { StaticLayout } from '../components/layout' | ||||||
| import styles from '../styles/404.module.css' | import styles from '../styles/404.module.css' | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -35,7 +35,7 @@ export default function Referrals ({ ssrData }) { | |||||||
|   const { data } = useQuery(REFERRALS, { variables: { when: router.query.when } }) |   const { data } = useQuery(REFERRALS, { variables: { when: router.query.when } }) | ||||||
|   if (!data && !ssrData) return <PageLoading /> |   if (!data && !ssrData) return <PageLoading /> | ||||||
| 
 | 
 | ||||||
|   const { referrals: { totalSats, totalReferrals, stats } } = data |   const { referrals: { totalSats, totalReferrals, stats } } = data || ssrData | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <CenterLayout footerLinks> |     <CenterLayout footerLinks> | ||||||
| @ -44,10 +44,10 @@ export default function Referrals ({ ssrData }) { | |||||||
|           when: router.query.when |           when: router.query.when | ||||||
|         }} |         }} | ||||||
|       > |       > | ||||||
|         <h4 className='font-weight-bold text-muted text-center pt-5 pb-3 d-flex align-items-center justify-content-center'> |         <h4 className='fw-bold text-muted text-center pt-5 pb-3 d-flex align-items-center justify-content-center'> | ||||||
|           {totalReferrals} referrals & {totalSats} sats in the last |           {totalReferrals} referrals & {totalSats} sats in the last | ||||||
|           <Select |           <Select | ||||||
|             groupClassName='mb-0 ml-2' |             groupClassName='mb-0 ms-2' | ||||||
|             className='w-auto' |             className='w-auto' | ||||||
|             name='when' |             name='when' | ||||||
|             size='sm' |             size='sm' | ||||||
| @ -61,7 +61,7 @@ export default function Referrals ({ ssrData }) { | |||||||
|       <div |       <div | ||||||
|         className='text-small pt-5 px-3 d-flex w-100 align-items-center' |         className='text-small pt-5 px-3 d-flex w-100 align-items-center' | ||||||
|       > |       > | ||||||
|         <div className='nav-item text-muted pr-2' style={{ 'white-space': 'nowrap' }}>referral link:</div> |         <div className='nav-item text-muted pe-2' style={{ 'white-space': 'nowrap' }}>referral link:</div> | ||||||
|         <CopyInput |         <CopyInput | ||||||
|           size='sm' |           size='sm' | ||||||
|           groupClassName='mb-0 w-100' |           groupClassName='mb-0 w-100' | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { gql } from 'graphql-tag' | import { gql } from 'graphql-tag' | ||||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||||
| import { Button, InputGroup } from 'react-bootstrap' | import Button from 'react-bootstrap/Button' | ||||||
|  | import InputGroup from 'react-bootstrap/InputGroup' | ||||||
| import { Cell, Pie, PieChart, ResponsiveContainer, Tooltip } from 'recharts' | import { Cell, Pie, PieChart, ResponsiveContainer, Tooltip } from 'recharts' | ||||||
| import { getGetServerSideProps } from '../api/ssrApollo' | import { getGetServerSideProps } from '../api/ssrApollo' | ||||||
| import { Form, Input, SubmitButton } from '../components/form' | import { Form, Input, SubmitButton } from '../components/form' | ||||||
| @ -68,7 +69,7 @@ export default function Rewards ({ ssrData }) { | |||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <CenterLayout footerLinks> |     <CenterLayout footerLinks> | ||||||
|       <h4 className='font-weight-bold text-muted text-center'> |       <h4 className='fw-bold text-muted text-center'> | ||||||
|         <div> |         <div> | ||||||
|           <RewardLine total={total} /> |           <RewardLine total={total} /> | ||||||
|         </div> |         </div> | ||||||
| @ -85,11 +86,11 @@ export default function Rewards ({ ssrData }) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const COLORS = [ | const COLORS = [ | ||||||
|   'var(--secondary)', |   'var(--bs-secondary)', | ||||||
|   'var(--info)', |   'var(--bs-info)', | ||||||
|   'var(--success)', |   'var(--bs-success)', | ||||||
|   'var(--boost)', |   'var(--bs-boost)', | ||||||
|   'var(--grey)' |   'var(--bs-grey)' | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| function GrowthPieChart ({ data }) { | function GrowthPieChart ({ data }) { | ||||||
| @ -103,7 +104,7 @@ function GrowthPieChart ({ data }) { | |||||||
|           cx='50%' |           cx='50%' | ||||||
|           cy='50%' |           cy='50%' | ||||||
|           outerRadius={80} |           outerRadius={80} | ||||||
|           fill='var(--secondary)' |           fill='var(--bs-secondary)' | ||||||
|           label |           label | ||||||
|         > |         > | ||||||
|           { |           { | ||||||
| @ -151,7 +152,7 @@ export function DonateButton () { | |||||||
|             append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>} |             append={<InputGroup.Text className='text-monospace'>sats</InputGroup.Text>} | ||||||
|           /> |           /> | ||||||
|           <div className='d-flex'> |           <div className='d-flex'> | ||||||
|             <SubmitButton variant='success' className='ml-auto mt-1 px-4' value='TIP'>donate</SubmitButton> |             <SubmitButton variant='success' className='ms-auto mt-1 px-4' value='TIP'>donate</SubmitButton> | ||||||
|           </div> |           </div> | ||||||
|         </Form> |         </Form> | ||||||
|       ))} |       ))} | ||||||
|  | |||||||
| @ -79,7 +79,7 @@ function Satus ({ status }) { | |||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div> |     <div> | ||||||
|       <Icon /><small className={`text-${color} font-weight-bold ml-2`}>{desc}</small> |       <Icon /><small className={`text-${color} fw-bold ms-2`}>{desc}</small> | ||||||
|     </div> |     </div> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| import { Checkbox, Form, Input, SubmitButton, Select, VariableInput } from '../components/form' | import { Checkbox, Form, Input, SubmitButton, Select, VariableInput } from '../components/form' | ||||||
| import { Alert, Button, InputGroup } from 'react-bootstrap' | import Alert from 'react-bootstrap/Alert' | ||||||
|  | import Button from 'react-bootstrap/Button' | ||||||
|  | import InputGroup from 'react-bootstrap/InputGroup' | ||||||
| import { CenterLayout } from '../components/layout' | import { CenterLayout } from '../components/layout' | ||||||
| import { useState } from 'react' | import { useState } from 'react' | ||||||
| import { gql, useMutation, useQuery } from '@apollo/client' | import { gql, useMutation, useQuery } from '@apollo/client' | ||||||
| @ -113,7 +115,7 @@ export default function Settings ({ ssrData }) { | |||||||
|                 label={ |                 label={ | ||||||
|                   <div className='d-flex align-items-center'>turbo zapping |                   <div className='d-flex align-items-center'>turbo zapping | ||||||
|                     <Info> |                     <Info> | ||||||
|                       <ul className='font-weight-bold'> |                       <ul className='fw-bold'> | ||||||
|                         <li>Makes every additional bolt click raise your total zap to another 10x multiple of your default zap</li> |                         <li>Makes every additional bolt click raise your total zap to another 10x multiple of your default zap</li> | ||||||
|                         <li>e.g. if your zap default is 10 sats |                         <li>e.g. if your zap default is 10 sats | ||||||
|                           <ul> |                           <ul> | ||||||
| @ -188,7 +190,7 @@ export default function Settings ({ ssrData }) { | |||||||
|             label={ |             label={ | ||||||
|               <div className='d-flex align-items-center'>hide invoice descriptions |               <div className='d-flex align-items-center'>hide invoice descriptions | ||||||
|                 <Info> |                 <Info> | ||||||
|                   <ul className='font-weight-bold'> |                   <ul className='fw-bold'> | ||||||
|                     <li>Use this if you don't want funding sources to be linkable to your SN identity.</li> |                     <li>Use this if you don't want funding sources to be linkable to your SN identity.</li> | ||||||
|                     <li>It makes your invoice descriptions blank.</li> |                     <li>It makes your invoice descriptions blank.</li> | ||||||
|                     <li>This only applies to invoices you create |                     <li>This only applies to invoices you create | ||||||
| @ -217,7 +219,7 @@ export default function Settings ({ ssrData }) { | |||||||
|             label={ |             label={ | ||||||
|               <div className='d-flex align-items-center'>wild west mode |               <div className='d-flex align-items-center'>wild west mode | ||||||
|                 <Info> |                 <Info> | ||||||
|                   <ul className='font-weight-bold'> |                   <ul className='fw-bold'> | ||||||
|                     <li>don't hide flagged content</li> |                     <li>don't hide flagged content</li> | ||||||
|                     <li>don't down rank flagged content</li> |                     <li>don't down rank flagged content</li> | ||||||
|                   </ul> |                   </ul> | ||||||
| @ -231,7 +233,7 @@ export default function Settings ({ ssrData }) { | |||||||
|             label={ |             label={ | ||||||
|               <div className='d-flex align-items-center'>greeter mode |               <div className='d-flex align-items-center'>greeter mode | ||||||
|                 <Info> |                 <Info> | ||||||
|                   <ul className='font-weight-bold'> |                   <ul className='fw-bold'> | ||||||
|                     <li>see and screen free posts and comments</li> |                     <li>see and screen free posts and comments</li> | ||||||
|                     <li>help onboard new stackers to SN and Lightning</li> |                     <li>help onboard new stackers to SN and Lightning</li> | ||||||
|                     <li>you might be subject to more spam</li> |                     <li>you might be subject to more spam</li> | ||||||
| @ -244,16 +246,16 @@ export default function Settings ({ ssrData }) { | |||||||
|           <AccordianItem |           <AccordianItem | ||||||
|             headerColor='var(--theme-color)' |             headerColor='var(--theme-color)' | ||||||
|             show={settings?.nostrPubkey} |             show={settings?.nostrPubkey} | ||||||
|             header={<h4 className='mb-2 text-left'>nostr <small><a href='https://github.com/nostr-protocol/nips/blob/master/05.md' target='_blank' rel='noreferrer'>NIP-05</a></small></h4>} |             header={<h4 className='text-left'>nostr <small><a href='https://github.com/nostr-protocol/nips/blob/master/05.md' target='_blank' rel='noreferrer'>NIP-05</a></small></h4>} | ||||||
|             body={ |             body={ | ||||||
|               <> |               <> | ||||||
|                 <Input |                 <Input | ||||||
|                   label={<>pubkey <small className='text-muted ml-2'>optional</small></>} |                   label={<>pubkey <small className='text-muted ms-2'>optional</small></>} | ||||||
|                   name='nostrPubkey' |                   name='nostrPubkey' | ||||||
|                   clear |                   clear | ||||||
|                 /> |                 /> | ||||||
|                 <VariableInput |                 <VariableInput | ||||||
|                   label={<>relays <small className='text-muted ml-2'>optional</small></>} |                   label={<>relays <small className='text-muted ms-2'>optional</small></>} | ||||||
|                   name='nostrRelays' |                   name='nostrRelays' | ||||||
|                   clear |                   clear | ||||||
|                   min={0} |                   min={0} | ||||||
| @ -263,7 +265,7 @@ export default function Settings ({ ssrData }) { | |||||||
|               } |               } | ||||||
|           /> |           /> | ||||||
|           <div className='d-flex'> |           <div className='d-flex'> | ||||||
|             <SubmitButton variant='info' className='ml-auto mt-1 px-4'>save</SubmitButton> |             <SubmitButton variant='info' className='ms-auto mt-1 px-4'>save</SubmitButton> | ||||||
|           </div> |           </div> | ||||||
|         </Form> |         </Form> | ||||||
|         <div className='text-left w-100'> |         <div className='text-left w-100'> | ||||||
| @ -301,7 +303,7 @@ function UnlinkObstacle ({ onClose, type, unlinkAuth }) { | |||||||
|     <div> |     <div> | ||||||
|       You are removing your last auth method. It is recommended you link another auth method before removing |       You are removing your last auth method. It is recommended you link another auth method before removing | ||||||
|       your last auth method. If you'd like to proceed anyway, type the following below |       your last auth method. If you'd like to proceed anyway, type the following below | ||||||
|       <div className='text-danger font-weight-bold my-2'> |       <div className='text-danger fw-bold my-2'> | ||||||
|         If I logout, even accidentally, I will never be able to access my account again |         If I logout, even accidentally, I will never be able to access my account again | ||||||
|       </div> |       </div> | ||||||
|       <Form |       <Form | ||||||
| @ -320,7 +322,7 @@ function UnlinkObstacle ({ onClose, type, unlinkAuth }) { | |||||||
|           name='warning' |           name='warning' | ||||||
|           required |           required | ||||||
|         /> |         /> | ||||||
|         <SubmitButton className='d-flex ml-auto' variant='danger'>do it</SubmitButton> |         <SubmitButton className='d-flex ms-auto' variant='danger'>do it</SubmitButton> | ||||||
|       </Form> |       </Form> | ||||||
|     </div> |     </div> | ||||||
|   ) |   ) | ||||||
| @ -379,7 +381,7 @@ function AuthMethods ({ methods }) { | |||||||
|                   noForm |                   noForm | ||||||
|                 /> |                 /> | ||||||
|                 <Button |                 <Button | ||||||
|                   className='ml-2' variant='secondary' onClick={ |                   className='ms-2' variant='secondary' onClick={ | ||||||
|                     async () => { |                     async () => { | ||||||
|                       await unlink('email') |                       await unlink('email') | ||||||
|                     } |                     } | ||||||
| @ -448,7 +450,7 @@ export function EmailLinkForm ({ callbackUrl }) { | |||||||
|           required |           required | ||||||
|           groupClassName='mb-0' |           groupClassName='mb-0' | ||||||
|         /> |         /> | ||||||
|         <SubmitButton className='ml-2' variant='secondary'>Link Email</SubmitButton> |         <SubmitButton className='ms-2' variant='secondary'>Link Email</SubmitButton> | ||||||
|       </div> |       </div> | ||||||
|     </Form> |     </Form> | ||||||
|   ) |   ) | ||||||
|  | |||||||
| @ -9,14 +9,14 @@ function SignUpHeader () { | |||||||
|       <h3 className='w-100 pb-2'> |       <h3 className='w-100 pb-2'> | ||||||
|         Sign up |         Sign up | ||||||
|       </h3> |       </h3> | ||||||
|       <div className='font-weight-bold text-muted pb-4'>Join 15,000+ bitcoiners and start stacking sats today</div> |       <div className='fw-bold text-muted pb-4'>Join 15,000+ bitcoiners and start stacking sats today</div> | ||||||
|     </> |     </> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function SignUpFooter ({ callbackUrl }) { | function SignUpFooter ({ callbackUrl }) { | ||||||
|   return ( |   return ( | ||||||
|     <small className='font-weight-bold text-muted pt-4'>Already have an account? <Link href={{ pathname: '/login', query: { callbackUrl } }}>login</Link></small> |     <small className='fw-bold text-muted pt-4'>Already have an account? <Link href={{ pathname: '/login', query: { callbackUrl } }}>login</Link></small> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| import { gql } from '@apollo/client' | import { gql } from '@apollo/client' | ||||||
| import { getGetServerSideProps } from '../../api/ssrApollo' | import { getGetServerSideProps } from '../../api/ssrApollo' | ||||||
| import Layout from '../../components/layout' | import Layout from '../../components/layout' | ||||||
| import { Col, Row } from 'react-bootstrap' | import Col from 'react-bootstrap/Col' | ||||||
|  | import Row from 'react-bootstrap/Row' | ||||||
| import { UsageHeader } from '../../components/usage-header' | import { UsageHeader } from '../../components/usage-header' | ||||||
| import { WhenLineChart, WhenAreaChart } from '../../components/when-charts' | import { WhenLineChart, WhenAreaChart } from '../../components/when-charts' | ||||||
| import { useRouter } from 'next/router' | import { useRouter } from 'next/router' | ||||||
| @ -65,31 +66,31 @@ export default function Growth ({ | |||||||
|       <UsageHeader /> |       <UsageHeader /> | ||||||
|       <Row> |       <Row> | ||||||
|         <Col className='mt-3'> |         <Col className='mt-3'> | ||||||
|           <div className='text-center text-muted font-weight-bold'>{avg}stackers</div> |           <div className='text-center text-muted fw-bold'>{avg}stackers</div> | ||||||
|           <WhenLineChart data={stackerGrowth} /> |           <WhenLineChart data={stackerGrowth} /> | ||||||
|         </Col> |         </Col> | ||||||
|         <Col className='mt-3'> |         <Col className='mt-3'> | ||||||
|           <div className='text-center text-muted font-weight-bold'>stacking</div> |           <div className='text-center text-muted fw-bold'>stacking</div> | ||||||
|           <WhenAreaChart data={stackingGrowth} /> |           <WhenAreaChart data={stackingGrowth} /> | ||||||
|         </Col> |         </Col> | ||||||
|       </Row> |       </Row> | ||||||
|       <Row> |       <Row> | ||||||
|         <Col className='mt-3'> |         <Col className='mt-3'> | ||||||
|           <div className='text-center text-muted font-weight-bold'>{avg}spenders</div> |           <div className='text-center text-muted fw-bold'>{avg}spenders</div> | ||||||
|           <WhenLineChart data={spenderGrowth} /> |           <WhenLineChart data={spenderGrowth} /> | ||||||
|         </Col> |         </Col> | ||||||
|         <Col className='mt-3'> |         <Col className='mt-3'> | ||||||
|           <div className='text-center text-muted font-weight-bold'>spending</div> |           <div className='text-center text-muted fw-bold'>spending</div> | ||||||
|           <WhenAreaChart data={spendingGrowth} /> |           <WhenAreaChart data={spendingGrowth} /> | ||||||
|         </Col> |         </Col> | ||||||
|       </Row> |       </Row> | ||||||
|       <Row> |       <Row> | ||||||
|         <Col className='mt-3'> |         <Col className='mt-3'> | ||||||
|           <div className='text-center text-muted font-weight-bold'>registrations</div> |           <div className='text-center text-muted fw-bold'>registrations</div> | ||||||
|           <WhenAreaChart data={registrationGrowth} /> |           <WhenAreaChart data={registrationGrowth} /> | ||||||
|         </Col> |         </Col> | ||||||
|         <Col className='mt-3'> |         <Col className='mt-3'> | ||||||
|           <div className='text-center text-muted font-weight-bold'>items</div> |           <div className='text-center text-muted fw-bold'>items</div> | ||||||
|           <WhenAreaChart data={itemGrowth} /> |           <WhenAreaChart data={itemGrowth} /> | ||||||
|         </Col> |         </Col> | ||||||
|       </Row> |       </Row> | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ import { WithdrawlSkeleton } from './withdrawals/[id]' | |||||||
| import { useMe } from '../components/me' | import { useMe } from '../components/me' | ||||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||||
| import { requestProvider } from 'webln' | import { requestProvider } from 'webln' | ||||||
| import { Alert } from 'react-bootstrap' | import Alert from 'react-bootstrap/Alert' | ||||||
| import { CREATE_WITHDRAWL, SEND_TO_LNADDR } from '../fragments/wallet' | import { CREATE_WITHDRAWL, SEND_TO_LNADDR } from '../fragments/wallet' | ||||||
| import { getGetServerSideProps } from '../api/ssrApollo' | import { getGetServerSideProps } from '../api/ssrApollo' | ||||||
| import { amountSchema, lnAddrSchema, withdrawlSchema } from '../lib/validate' | import { amountSchema, lnAddrSchema, withdrawlSchema } from '../lib/validate' | ||||||
| @ -37,7 +37,7 @@ function YouHaveSats () { | |||||||
| function WalletHistory () { | function WalletHistory () { | ||||||
|   return ( |   return ( | ||||||
|     <div className='pt-4'> |     <div className='pt-4'> | ||||||
|       <Link href='/satistics?inc=invoice,withdrawal' className='text-muted font-weight-bold text-underline'> |       <Link href='/satistics?inc=invoice,withdrawal' className='text-muted fw-bold text-underline'> | ||||||
|         wallet history |         wallet history | ||||||
|       </Link> |       </Link> | ||||||
|     </div> |     </div> | ||||||
| @ -54,7 +54,7 @@ export function WalletForm () { | |||||||
|         <Link href='/wallet?type=fund'> |         <Link href='/wallet?type=fund'> | ||||||
|           <Button variant='success'>fund</Button> |           <Button variant='success'>fund</Button> | ||||||
|         </Link> |         </Link> | ||||||
|         <span className='mx-3 font-weight-bold text-muted'>or</span> |         <span className='mx-3 fw-bold text-muted'>or</span> | ||||||
|         <Link href='/wallet?type=withdraw'> |         <Link href='/wallet?type=withdraw'> | ||||||
|           <Button variant='success'>withdraw</Button> |           <Button variant='success'>withdraw</Button> | ||||||
|         </Link> |         </Link> | ||||||
| @ -189,7 +189,7 @@ export function WithdrawlForm () { | |||||||
|         /> |         /> | ||||||
|         <SubmitButton variant='success' className='mt-2'>withdraw</SubmitButton> |         <SubmitButton variant='success' className='mt-2'>withdraw</SubmitButton> | ||||||
|       </Form> |       </Form> | ||||||
|       <span className='my-3 font-weight-bold text-muted'>or via</span> |       <span className='my-3 fw-bold text-muted'>or via</span> | ||||||
|       <Link href='/wallet?type=lnurl-withdraw'> |       <Link href='/wallet?type=lnurl-withdraw'> | ||||||
|         <Button variant='grey'>QR code</Button> |         <Button variant='grey'>QR code</Button> | ||||||
|       </Link> |       </Link> | ||||||
|  | |||||||
| @ -43,7 +43,7 @@ function LoadWithdrawl () { | |||||||
| 
 | 
 | ||||||
|   const TryMaxFee = () => |   const TryMaxFee = () => | ||||||
|     <Link href='/wallet?type=withdraw' className='text-reset text-underline'> |     <Link href='/wallet?type=withdraw' className='text-reset text-underline'> | ||||||
|       <small className='ml-3'>try increasing max fee</small> |       <small className='ms-3'>try increasing max fee</small> | ||||||
|     </Link> |     </Link> | ||||||
| 
 | 
 | ||||||
|   let status = 'pending' |   let status = 'pending' | ||||||
| @ -54,7 +54,7 @@ function LoadWithdrawl () { | |||||||
|       variant = 'confirmed' |       variant = 'confirmed' | ||||||
|       break |       break | ||||||
|     case 'INSUFFICIENT_BALANCE': |     case 'INSUFFICIENT_BALANCE': | ||||||
|       status = <>insufficient balance <small className='ml-3'>contact keyan!</small></> |       status = <>insufficient balance <small className='ms-3'>contact keyan!</small></> | ||||||
|       variant = 'failed' |       variant = 'failed' | ||||||
|       break |       break | ||||||
|     case 'INVALID_PAYMENT': |     case 'INVALID_PAYMENT': | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ export default function Index ({ ssrData }) { | |||||||
|           /> |           /> | ||||||
|         : ( |         : ( | ||||||
|           <div className='text-muted text-center mt-5' style={{ fontFamily: 'lightning', fontSize: '2rem', opacity: '0.75' }}> |           <div className='text-muted text-center mt-5' style={{ fontFamily: 'lightning', fontSize: '2rem', opacity: '0.75' }}> | ||||||
|             <Down width={22} height={22} className='mr-2' />search for something<Down width={22} height={22} className='ml-2' /> |             <Down width={22} height={22} className='me-2' />search for something<Down width={22} height={22} className='ms-2' /> | ||||||
|           </div>)} |           </div>)} | ||||||
|     </SearchLayout> |     </SearchLayout> | ||||||
|   ) |   ) | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ const COLORS = { | |||||||
|     commentBg: 'rgba(255, 255, 255, 0.04)', |     commentBg: 'rgba(255, 255, 255, 0.04)', | ||||||
|     clickToContextColor: 'rgba(255, 255, 255, 0.2)', |     clickToContextColor: 'rgba(255, 255, 255, 0.2)', | ||||||
|     color: '#f8f9fa', |     color: '#f8f9fa', | ||||||
|     brandColor: 'var(--primary)', |     brandColor: 'var(--bs-primary)', | ||||||
|     grey: '#969696', |     grey: '#969696', | ||||||
|     link: '#2e99d1', |     link: '#2e99d1', | ||||||
|     toolbarActive: 'rgba(255, 255, 255, 0.10)', |     toolbarActive: 'rgba(255, 255, 255, 0.10)', | ||||||
|  | |||||||
| @ -1,3 +1,13 @@ | |||||||
|  | $primary: #FADA5E; | ||||||
|  | $secondary: #F6911D; | ||||||
|  | $danger: #c03221; | ||||||
|  | $info: #007cbe; | ||||||
|  | $success: #5c8001; | ||||||
|  | $twitter: #1da1f2; | ||||||
|  | $boost: #8c25f4; | ||||||
|  | $light: #f8f9fa; | ||||||
|  | $dark: #212529; | ||||||
|  | 
 | ||||||
| $theme-colors: ( | $theme-colors: ( | ||||||
|   "primary" : #FADA5E, |   "primary" : #FADA5E, | ||||||
|   "secondary" : #F6911D, |   "secondary" : #F6911D, | ||||||
| @ -6,9 +16,11 @@ $theme-colors: ( | |||||||
|   "success" : #5c8001, |   "success" : #5c8001, | ||||||
|   "twitter" : #1da1f2, |   "twitter" : #1da1f2, | ||||||
|   "boost" : #8c25f4, |   "boost" : #8c25f4, | ||||||
|  |   "light": #f8f9fa, | ||||||
|  |   "dark": #212529, | ||||||
|   "grey" : #e9ecef, |   "grey" : #e9ecef, | ||||||
|   "grey-medium" : #d2d2d2, |   "grey-medium" : #d2d2d2, | ||||||
|   "grey-darkmode": #8c8c8c |   "grey-darkmode": #8c8c8c, | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| $body-bg: #f5f5f7; | $body-bg: #f5f5f7; | ||||||
| @ -20,6 +32,7 @@ $btn-transition: none; | |||||||
| $form-feedback-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='12' height='12'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M2 9h3v12H2a1 1 0 0 1-1-1V10a1 1 0 0 1 1-1zm5.293-1.293l6.4-6.4a.5.5 0 0 1 .654-.047l.853.64a1.5 1.5 0 0 1 .553 1.57L14.6 8H21a2 2 0 0 1 2 2v2.104a2 2 0 0 1-.15.762l-3.095 7.515a1 1 0 0 1-.925.619H8a1 1 0 0 1-1-1V8.414a1 1 0 0 1 .293-.707z' fill='rgba(92, 128, 1, 1)'/%3E%3C/svg%3E"); | $form-feedback-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='12' height='12'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M2 9h3v12H2a1 1 0 0 1-1-1V10a1 1 0 0 1 1-1zm5.293-1.293l6.4-6.4a.5.5 0 0 1 .654-.047l.853.64a1.5 1.5 0 0 1 .553 1.57L14.6 8H21a2 2 0 0 1 2 2v2.104a2 2 0 0 1-.15.762l-3.095 7.515a1 1 0 0 1-.925.619H8a1 1 0 0 1-1-1V8.414a1 1 0 0 1 .293-.707z' fill='rgba(92, 128, 1, 1)'/%3E%3C/svg%3E"); | ||||||
| $form-feedback-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='12' height='12'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M22 15h-3V3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zm-5.293 1.293l-6.4 6.4a.5.5 0 0 1-.654.047L8.8 22.1a1.5 1.5 0 0 1-.553-1.57L9.4 16H3a2 2 0 0 1-2-2v-2.104a2 2 0 0 1 .15-.762L4.246 3.62A1 1 0 0 1 5.17 3H16a1 1 0 0 1 1 1v11.586a1 1 0 0 1-.293.707z' fill='rgba(192,50,33,1)'/%3E%3C/svg%3E"); | $form-feedback-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='12' height='12'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M22 15h-3V3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zm-5.293 1.293l-6.4 6.4a.5.5 0 0 1-.654.047L8.8 22.1a1.5 1.5 0 0 1-.553-1.57L9.4 16H3a2 2 0 0 1-2-2v-2.104a2 2 0 0 1 .15-.762L4.246 3.62A1 1 0 0 1 5.17 3H16a1 1 0 0 1 1 1v11.586a1 1 0 0 1-.293.707z' fill='rgba(192,50,33,1)'/%3E%3C/svg%3E"); | ||||||
| $line-height-base: 1.75; | $line-height-base: 1.75; | ||||||
|  | $input-placeholder-color: #6c757d; | ||||||
| $input-btn-padding-y: .42rem; | $input-btn-padding-y: .42rem; | ||||||
| $input-btn-padding-x: .84rem; | $input-btn-padding-x: .84rem; | ||||||
| $btn-padding-y: .42rem; | $btn-padding-y: .42rem; | ||||||
| @ -33,6 +46,7 @@ $close-text-shadow: none; | |||||||
| $close-color: inherit; | $close-color: inherit; | ||||||
| $alert-border-radius: #{33% 2%} / #{11% 74%}; | $alert-border-radius: #{33% 2%} / #{11% 74%}; | ||||||
| $link-color: #007cbe; | $link-color: #007cbe; | ||||||
|  | $link-decoration: none; | ||||||
| $font-size-base: .9rem; | $font-size-base: .9rem; | ||||||
| $enable-responsive-font-sizes: true; | $enable-responsive-font-sizes: true; | ||||||
| $link-hover-decoration: none; | $link-hover-decoration: none; | ||||||
| @ -42,6 +56,8 @@ $dropdown-link-hover-bg: transparent; | |||||||
| $dropdown-link-active-bg: transparent; | $dropdown-link-active-bg: transparent; | ||||||
| $dropdown-link-color: rgba(0, 0, 0, 0.7); | $dropdown-link-color: rgba(0, 0, 0, 0.7); | ||||||
| $dropdown-link-hover-color: rgba(0, 0, 0, 0.9); | $dropdown-link-hover-color: rgba(0, 0, 0, 0.9); | ||||||
|  | $dropdown-item-padding-x: 1.5rem; | ||||||
|  | $modal-inner-padding: 2rem; | ||||||
| $container-max-widths: ( | $container-max-widths: ( | ||||||
|   sm: 540px, |   sm: 540px, | ||||||
|   md: 720px, |   md: 720px, | ||||||
| @ -51,9 +67,20 @@ $nav-link-padding-y: .1rem; | |||||||
| $nav-tabs-link-active-bg: #fff; | $nav-tabs-link-active-bg: #fff; | ||||||
| $nav-tabs-link-hover-border-color: transparent; | $nav-tabs-link-hover-border-color: transparent; | ||||||
| $nav-tabs-link-active-border-color: #ced4da #ced4da $nav-tabs-link-active-bg; | $nav-tabs-link-active-border-color: #ced4da #ced4da $nav-tabs-link-active-bg; | ||||||
|  | $form-check-input-checked-color: var(--bs-primary); | ||||||
|  | $form-check-input-checked-bg-color: var(--bs-primary); | ||||||
|  | $popover-bg: var(--theme-body); | ||||||
|  | $form-check-input-checked-color: #000; | ||||||
| $tooltip-bg: #5c8001; | $tooltip-bg: #5c8001; | ||||||
|  | $form-select-indicator-color: #808080; | ||||||
|  | $form-select-indicator: url("data:image/svg+xml, %3Csvg fill='#{$form-select-indicator-color}' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath  d='M12 15.0006L7.75732 10.758L9.17154 9.34375L12 12.1722L14.8284 9.34375L16.2426 10.758L12 15.0006Z'%3E%3C/path%3E%3C/svg%3E%0A"); | ||||||
|  | $form-select-bg-position: right .25rem center; | ||||||
|  | $form-select-bg-size: 1.5rem; | ||||||
|  | $popover-body-padding-y: .5rem; | ||||||
|  | $popover-max-width: 320px !default; | ||||||
|  | $popover-border-color: var(--theme-borderColor); | ||||||
| 
 | 
 | ||||||
| @import "~bootstrap/scss/bootstrap"; | @import '../node_modules/bootstrap/scss/bootstrap.scss'; | ||||||
| 
 | 
 | ||||||
| @media screen and (min-width: 899px) { | @media screen and (min-width: 899px) { | ||||||
| 
 | 
 | ||||||
| @ -135,8 +162,8 @@ mark { | |||||||
|   width: 100% !important; |   width: 100% !important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .custom-checkbox.custom-control-inline { | .btn-twitter, .btn-twitter:hover, .btn-twitter:active { | ||||||
|   margin-right: .5rem; |   color: #ffffff !important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .table { | .table { | ||||||
| @ -178,7 +205,7 @@ a:hover { | |||||||
|   border-bottom-color: var(--theme-inputBg); |   border-bottom-color: var(--theme-inputBg); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| select.custom-select, | select, | ||||||
| div[contenteditable], | div[contenteditable], | ||||||
| .form-control { | .form-control { | ||||||
|   background-color: var(--theme-inputBg); |   background-color: var(--theme-inputBg); | ||||||
| @ -186,26 +213,38 @@ div[contenteditable], | |||||||
|   border-color: var(--theme-borderColor); |   border-color: var(--theme-borderColor); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .form-group { | ||||||
|  |   margin-bottom: 1rem; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| select.custom-select { | 
 | ||||||
|  | select.form-select { | ||||||
|   background-color: var(--theme-clickToContextColor); |   background-color: var(--theme-clickToContextColor); | ||||||
|   color: var(--theme-dropdownItemColor); |   color: var(--theme-dropdownItemColor); | ||||||
|   font-weight: bold; |   font-weight: bold; | ||||||
|   border: none; |   border: none; | ||||||
|   background-image: url("data:image/svg+xml, %3Csvg fill='%23808080' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath  d='M12 15.0006L7.75732 10.758L9.17154 9.34375L12 12.1722L14.8284 9.34375L16.2426 10.758L12 15.0006Z'%3E%3C/path%3E%3C/svg%3E%0A"); |   display: inline-block; | ||||||
|   background-repeat: no-repeat; |   width: 100%; | ||||||
|   background-position: right .25rem center; |   height: calc(1.5em + 0.5rem + 2px); | ||||||
|   background-size: 1.5rem; |   padding: 0.25rem 1.84rem 0.25rem 0.5rem; | ||||||
|  |   font-size: .7875rem; | ||||||
|  |   vertical-align: middle; | ||||||
|  |   border-radius: 0.4rem; | ||||||
|  |   appearance: none; | ||||||
|  |   -webkit-appearance: none; | ||||||
|  |   -moz-appearance: none; | ||||||
|  |   appearance: none; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| select.custom-select option { | select option { | ||||||
|   // fix dropdown items not visible in darkmode on some browsers |   // fix dropdown items not visible in darkmode on some browsers | ||||||
|   color: initial; |   color: initial; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| select.custom-select:focus { | select:focus { | ||||||
|   border-color: none !important; |   border-color: none !important; | ||||||
|   box-shadow: none !important; |   box-shadow: none !important; | ||||||
|  |   outline: none !important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -222,6 +261,7 @@ div[contenteditable]:disabled, | |||||||
| .form-control[readonly] { | .form-control[readonly] { | ||||||
|   background-color: var(--theme-inputDisabledBg); |   background-color: var(--theme-inputDisabledBg); | ||||||
|   border-color: var(--theme-borderColor); |   border-color: var(--theme-borderColor); | ||||||
|  |   color: var(--theme-color); | ||||||
|   opacity: 1; |   opacity: 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -296,7 +336,7 @@ div[contenteditable]:disabled, | |||||||
| 
 | 
 | ||||||
| .dropdown-item.active { | .dropdown-item.active { | ||||||
|   color: var(--theme-brandColor) !important; |   color: var(--theme-brandColor) !important; | ||||||
|   text-shadow: 0 0 10px var(--primary); |   text-shadow: 0 0 10px var(--bs-primary); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .dropdown-divider { | .dropdown-divider { | ||||||
| @ -358,6 +398,12 @@ footer { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .input-group-text { | ||||||
|  |   background-color: var(--theme-clickToContextColor); | ||||||
|  |   border-color: var(--theme-borderColor); | ||||||
|  |   color: var(--theme-color); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| textarea.form-control, | textarea.form-control, | ||||||
| div[contenteditable] { | div[contenteditable] { | ||||||
|   line-height: 1rem; |   line-height: 1rem; | ||||||
| @ -444,12 +490,12 @@ div[contenteditable] { | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .dropdown-item.active { | .dropdown-item.active { | ||||||
|   text-shadow: 0 0 10px var(--primary); |   text-shadow: 0 0 10px var(--bs-primary); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| div[contenteditable]:focus, | div[contenteditable]:focus, | ||||||
| .form-control:focus { | .form-control:focus { | ||||||
|   border-color: var(--primary); |   border-color: var(--bs-primary); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .btn-secondary, | .btn-secondary, | ||||||
| @ -491,11 +537,11 @@ div[contenteditable]:focus, | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .fill-secondary { | .fill-secondary { | ||||||
|   fill: var(--secondary); |   fill: var(--bs-secondary); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .fill-boost { | .fill-boost { | ||||||
|   fill: var(--boost); |   fill: var(--bs-boost); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .fill-white { | .fill-white { | ||||||
| @ -503,15 +549,15 @@ div[contenteditable]:focus, | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .fill-success { | .fill-success { | ||||||
|   fill: var(--success); |   fill: var(--bs-success); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .fill-info { | .fill-info { | ||||||
|   fill: var(--info); |   fill: var(--bs-info); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .fill-danger { | .fill-danger { | ||||||
|   fill: var(--danger); |   fill: var(--bs-danger); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .fill-theme-color { | .fill-theme-color { | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ | |||||||
|   align-items: center; |   align-items: center; | ||||||
|   margin-right: -15px; |   margin-right: -15px; | ||||||
|   padding-right: 15px; |   padding-right: 15px; | ||||||
|  |   font-family: monospace; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .detail { | .detail { | ||||||
| @ -31,6 +32,10 @@ | |||||||
|   text-align: center; |   text-align: center; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .sats.head { | ||||||
|  |   font-family: inherit; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .head { | .head { | ||||||
|   font-weight: bold; |   font-weight: bold; | ||||||
|   text-transform: uppercase; |   text-transform: uppercase; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user