After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 639 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 552 KiB |
After Width: | Height: | Size: 972 KiB |
After Width: | Height: | Size: 6.8 KiB |
@ -0,0 +1,14 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React from 'react' |
||||||
|
|
||||||
|
function CustomButtonGroupAsArrows ({ next, previous }) { |
||||||
|
return ( |
||||||
|
<div style={{ textAlign: "center" }}> |
||||||
|
<h4>These buttons can be positioned anywhere you want on the screen</h4> |
||||||
|
<button onClick={previous}>Prev</button> |
||||||
|
<button onClick={next}>Next</button> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default CustomButtonGroupAsArrows |
@ -0,0 +1,20 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React from 'react' |
||||||
|
|
||||||
|
const CustomNavButtons = ({ next, previous, goToSlide, ...rest }) => { |
||||||
|
const { carouselState: { currentSlide, totalItems } } = rest |
||||||
|
return ( |
||||||
|
<div className="mt-1 d-flex justify-content-end carousel-button-group"> |
||||||
|
<button className={currentSlide === 0 ? 'disable py-1 border btn' : 'py-1 border btn'} onClick={() => previous()}> |
||||||
|
<i className="fas fa-angle-left"></i> |
||||||
|
</button> |
||||||
|
<button className={currentSlide + 1 === totalItems ? 'disable py-1 border btn' : 'py-1 border btn'} onClick={() => { |
||||||
|
if (currentSlide + 1 < totalItems) goToSlide(currentSlide + 1) |
||||||
|
}} > |
||||||
|
<i className="fas fa-angle-right"></i> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default CustomNavButtons |
@ -0,0 +1,73 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React, { useEffect, useState, useRef, useContext } from 'react' |
||||||
|
import { ThemeContext, themes } from '../themeContext' |
||||||
|
import Carousel from 'react-multi-carousel' |
||||||
|
import 'react-multi-carousel/lib/styles.css' |
||||||
|
import CustomNavButtons from './customNavButtons' |
||||||
|
|
||||||
|
function HomeTabFeatured() { |
||||||
|
const themeFilter = useContext(ThemeContext) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
return () => { |
||||||
|
} |
||||||
|
}, []) |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="pt-3 pl-2" id="hTFeaturedeSection"> |
||||||
|
<label style={{ fontSize: "1.2rem" }}>Featured</label> |
||||||
|
<div className="mb-2"> |
||||||
|
<div className="w-100 d-flex flex-column" style={{ height: "200px" }}> |
||||||
|
<ThemeContext.Provider value={ themeFilter }> |
||||||
|
<Carousel |
||||||
|
customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />} |
||||||
|
arrows={false} |
||||||
|
swipeable={false} |
||||||
|
draggable={true} |
||||||
|
showDots={true} |
||||||
|
responsive={{ desktop: { breakpoint: { max: 2000, min: 1024 }, items: 1 } }} |
||||||
|
renderDotsOutside={true} |
||||||
|
ssr={true} // means to render carousel on server-side.
|
||||||
|
infinite={true} |
||||||
|
centerMode={false} |
||||||
|
autoPlay={true} |
||||||
|
keyBoardControl={true} |
||||||
|
containerClass="border carousel-container" |
||||||
|
sliderClass="px-2 h-100 justify-content-between" |
||||||
|
deviceType={"desktop"} |
||||||
|
itemClass="px-2 carousel-item-padding-10-px" |
||||||
|
autoPlaySpeed={15000} |
||||||
|
dotListClass="position-relative mt-2" |
||||||
|
> |
||||||
|
<div className="d-flex"> |
||||||
|
<img src={"assets/img/bgRemi.webp"} style={{ flex: "1", height: "170px", maxWidth: "170px"}} alt="" ></img> |
||||||
|
<div className="h6 w-50 p-4" style={{ flex: "1"}}> |
||||||
|
<h5>JUMP INTO WEB3</h5> |
||||||
|
<span>The Remix Project is a rich toolset which can be used for the entire journey of contract development by users of any knowledge level, and as a learning lab for teaching and experimenting with Ethereum.</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className="d-flex"> |
||||||
|
<img src={"/assets/img/remixRewardUser.webp"} style={{ flex: "1", height: "170px", maxWidth: "170px" }} alt="" ></img> |
||||||
|
<div className="h6 p-4" style={{ flex: "1"}}> |
||||||
|
<h5>REMIX REWARDS</h5> |
||||||
|
<p style={{fontStyle: 'italic'}}>NFTs for our users!</p> |
||||||
|
<span>Remix Project rewards contributors, beta testers, and UX research participants with NFTs deployed on Optimism. Remix Reward holders are able to mint a second “Remixer” user NFT badge to give to any other user of their choice</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className="d-flex"> |
||||||
|
<img src={"/assets/img/remixRewardBetaTester.webp"} style={{ flex: "1", height: "170px", maxWidth: "170px" }} alt="" ></img> |
||||||
|
<div className="h6 p-4" style={{ flex: "1"}}> |
||||||
|
<h5>BETA TESTING</h5> |
||||||
|
<p style={{fontStyle: 'italic'}}>Our community supports us.</p> |
||||||
|
<span>You can join Beta Testing before each release of Remix IDE. Help us test now and get a handle on new features!</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</Carousel> |
||||||
|
</ThemeContext.Provider> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default HomeTabFeatured |
@ -0,0 +1,125 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React, { useEffect, useState, useRef, useContext } from 'react' |
||||||
|
import PluginButton from './pluginButton' |
||||||
|
import { ThemeContext, themes } from '../themeContext' |
||||||
|
import Carousel from 'react-multi-carousel' |
||||||
|
import 'react-multi-carousel/lib/styles.css' |
||||||
|
import CustomNavButtons from './customNavButtons' |
||||||
|
declare global { |
||||||
|
interface Window { |
||||||
|
_paq: any |
||||||
|
} |
||||||
|
} |
||||||
|
const _paq = window._paq = window._paq || [] //eslint-disable-line
|
||||||
|
|
||||||
|
interface HomeTabFeaturedPluginsProps { |
||||||
|
plugin: any |
||||||
|
} |
||||||
|
|
||||||
|
function HomeTabFeaturedPlugins ({plugin}: HomeTabFeaturedPluginsProps) { |
||||||
|
|
||||||
|
const themeFilter = useContext(ThemeContext) |
||||||
|
const carouselRef = useRef(null) |
||||||
|
|
||||||
|
// Todo doesn't work
|
||||||
|
useEffect(() => { |
||||||
|
window.addEventListener("scroll", handleScroll) |
||||||
|
return () => { |
||||||
|
window.removeEventListener("scroll", handleScroll) |
||||||
|
} |
||||||
|
}, []) |
||||||
|
|
||||||
|
const handleScroll = (e) => { |
||||||
|
} |
||||||
|
|
||||||
|
const startSolidity = async () => { |
||||||
|
await plugin.appManager.activatePlugin(['solidity', 'udapp', 'solidityStaticAnalysis', 'solidityUnitTesting']) |
||||||
|
plugin.verticalIcons.select('solidity') |
||||||
|
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'solidity']) |
||||||
|
} |
||||||
|
const startStarkNet = async () => { |
||||||
|
await plugin.appManager.activatePlugin('starkNet_compiler') |
||||||
|
plugin.verticalIcons.select('starkNet_compiler') |
||||||
|
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'starkNet_compiler']) |
||||||
|
} |
||||||
|
const startSolhint = async () => { |
||||||
|
await plugin.appManager.activatePlugin(['solidity', 'solhint']) |
||||||
|
plugin.verticalIcons.select('solhint') |
||||||
|
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'solhint']) |
||||||
|
} |
||||||
|
const startSourceVerify = async () => { |
||||||
|
await plugin.appManager.activatePlugin(['solidity', 'sourcify']) |
||||||
|
plugin.verticalIcons.select('sourcify') |
||||||
|
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'sourcify']) |
||||||
|
}
|
||||||
|
const startSolidityUnitTesting = async () => { |
||||||
|
await plugin.appManager.activatePlugin(['solidity', 'solidityUnitTesting']) |
||||||
|
plugin.verticalIcons.select('solidityUnitTesting') |
||||||
|
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'solidityUnitTesting']) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="pl-2 w-100" id="hTFeaturedPlugins"> |
||||||
|
<label className="" style={{fontSize: "1.2rem"}}>Featured Plugins</label> |
||||||
|
<div className="w-100 d-flex flex-column"> |
||||||
|
<ThemeContext.Provider value={ themeFilter }> |
||||||
|
<Carousel
|
||||||
|
ref={carouselRef} |
||||||
|
focusOnSelect |
||||||
|
customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />} |
||||||
|
arrows={false} |
||||||
|
swipeable={false} |
||||||
|
draggable={true} |
||||||
|
showDots={false} |
||||||
|
responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }} |
||||||
|
renderButtonGroupOutside={true} |
||||||
|
ssr={true} // means to render carousel on server-side.
|
||||||
|
keyBoardControl={true} |
||||||
|
containerClass="carousel-container" |
||||||
|
deviceType={"desktop"} |
||||||
|
itemClass="w-100" |
||||||
|
> |
||||||
|
<PluginButton |
||||||
|
imgPath="assets/img/solidityLogo.webp" |
||||||
|
envID="solidityLogo" |
||||||
|
envText="Solidity" |
||||||
|
description="Compile, test and analyse smart contract." |
||||||
|
remixMaintained={true} |
||||||
|
callback={() => startSolidity()} |
||||||
|
/> |
||||||
|
<PluginButton |
||||||
|
imgPath="assets/img/starkNetLogo.webp" |
||||||
|
envID="starkNetLogo" |
||||||
|
envText="StarkNet" |
||||||
|
description="Compile and deploy contracts with Cairo, a native language for StarkNet." |
||||||
|
l2={true} |
||||||
|
callback={() => startStarkNet()} |
||||||
|
/> |
||||||
|
<PluginButton |
||||||
|
imgPath="assets/img/solhintLogo.webp" |
||||||
|
envID="solhintLogo" envText="Solhint linter" |
||||||
|
description="Solhint is an open source project for linting Solidity code." |
||||||
|
callback={() => startSolhint()} |
||||||
|
/> |
||||||
|
<PluginButton |
||||||
|
imgPath="assets/img/sourcifyNewLogo.webp" |
||||||
|
envID="sourcifyLogo" |
||||||
|
envText="Sourcify" |
||||||
|
description="Solidity contract and metadata verification service." |
||||||
|
callback={() => startSourceVerify()} |
||||||
|
/> |
||||||
|
<PluginButton |
||||||
|
imgPath="assets/img/unitTesting.webp" |
||||||
|
envID="sUTLogo" |
||||||
|
envText="Solidity unit testing" |
||||||
|
description="Write and run unit tests for your contracts in Solidity." |
||||||
|
callback={() => startSolidityUnitTesting()} |
||||||
|
/> |
||||||
|
</Carousel> |
||||||
|
</ThemeContext.Provider> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default HomeTabFeaturedPlugins |
@ -0,0 +1,161 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React, { useState, useRef, useReducer } from 'react' |
||||||
|
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
|
||||||
|
import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
|
||||||
|
|
||||||
|
interface HomeTabFileProps { |
||||||
|
plugin: any |
||||||
|
} |
||||||
|
|
||||||
|
const loadingInitialState = { |
||||||
|
tooltip: '', |
||||||
|
showModalDialog: false, |
||||||
|
importSource: '' |
||||||
|
} |
||||||
|
|
||||||
|
const loadingReducer = (state = loadingInitialState, action) => { |
||||||
|
return { ...state, tooltip: action.tooltip, showModalDialog: false, importSource: '' } |
||||||
|
} |
||||||
|
|
||||||
|
function HomeTabFile ({plugin}: HomeTabFileProps) { |
||||||
|
const [state, setState] = useState<{ |
||||||
|
searchInput: string, |
||||||
|
showModalDialog: boolean, |
||||||
|
modalInfo: { title: string, loadItem: string, examples: Array<string> }, |
||||||
|
importSource: string, |
||||||
|
toasterMsg: string |
||||||
|
}>({ |
||||||
|
searchInput: '', |
||||||
|
showModalDialog: false, |
||||||
|
modalInfo: { title: '', loadItem: '', examples: [] }, |
||||||
|
importSource: '', |
||||||
|
toasterMsg: '' |
||||||
|
}) |
||||||
|
|
||||||
|
const [, dispatch] = useReducer(loadingReducer, loadingInitialState) |
||||||
|
|
||||||
|
const inputValue = useRef(null) |
||||||
|
|
||||||
|
const processLoading = () => { |
||||||
|
const contentImport = plugin.contentImport |
||||||
|
const workspace = plugin.fileManager.getProvider('workspace') |
||||||
|
contentImport.import( |
||||||
|
state.importSource, |
||||||
|
(loadingMsg) => dispatch({ tooltip: loadingMsg }), |
||||||
|
async (error, content, cleanUrl, type, url) => { |
||||||
|
if (error) { |
||||||
|
toast(error.message || error) |
||||||
|
} else { |
||||||
|
try { |
||||||
|
if (await workspace.exists(type + '/' + cleanUrl)) toast('File already exists in workspace') |
||||||
|
else { |
||||||
|
workspace.addExternal(type + '/' + cleanUrl, content, url) |
||||||
|
plugin.call('menuicons', 'select', 'filePanel') |
||||||
|
}
|
||||||
|
} catch (e) { |
||||||
|
toast(e.message) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
) |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, showModalDialog: false, importSource: '' } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const toast = (message: string) => { |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, toasterMsg: message } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const createNewFile = async () => { |
||||||
|
plugin.verticalIcons.select('filePanel') |
||||||
|
await plugin.call('filePanel', 'createNewFile') |
||||||
|
} |
||||||
|
|
||||||
|
const uploadFile = async (target) => { |
||||||
|
await plugin.call('filePanel', 'uploadFile', target) |
||||||
|
} |
||||||
|
|
||||||
|
const connectToLocalhost = () => { |
||||||
|
plugin.appManager.activatePlugin('remixd') |
||||||
|
} |
||||||
|
const importFromGist = () => { |
||||||
|
plugin.call('gistHandler', 'load', '') |
||||||
|
plugin.verticalIcons.select('filePanel') |
||||||
|
} |
||||||
|
|
||||||
|
const showFullMessage = (title: string, loadItem: string, examples: Array<string>) => { |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, showModalDialog: true, modalInfo: { title: title, loadItem: loadItem, examples: examples } } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const hideFullMessage = () => { //eslint-disable-line
|
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, showModalDialog: false, importSource: '' } |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const examples = state.modalInfo.examples.map((urlEl, key) => (<div key={key} className="p-1 user-select-auto"><a>{urlEl}</a></div>)) |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<ModalDialog |
||||||
|
id='homeTab' |
||||||
|
title={ 'Import from ' + state.modalInfo.title } |
||||||
|
okLabel='Import' |
||||||
|
hide={ !state.showModalDialog } |
||||||
|
handleHide={ () => hideFullMessage() } |
||||||
|
okFn={ () => processLoading() } |
||||||
|
> |
||||||
|
<div className="p-2 user-select-auto"> |
||||||
|
{ state.modalInfo.loadItem !== '' && <span>Enter the { state.modalInfo.loadItem } you would like to load.</span> } |
||||||
|
{ state.modalInfo.examples.length !== 0 && |
||||||
|
<> |
||||||
|
<div>e.g</div> |
||||||
|
<div> |
||||||
|
{ examples } |
||||||
|
</div> |
||||||
|
</> } |
||||||
|
<input |
||||||
|
ref={inputValue} |
||||||
|
type='text' |
||||||
|
name='prompt_text' |
||||||
|
id='inputPrompt_text' |
||||||
|
className="w-100 mt-1 form-control" |
||||||
|
data-id="homeTabModalDialogCustomPromptText" |
||||||
|
value={state.importSource} |
||||||
|
onInput={(e) => { |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, importSource: inputValue.current.value } |
||||||
|
}) |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</ModalDialog> |
||||||
|
<Toaster message={state.toasterMsg} /> |
||||||
|
<div className="justify-content-start mt-1 p-2 border-bottom d-flex flex-column" id="hTFileSection"> |
||||||
|
<label style={{fontSize: "1rem"}}>Files</label> |
||||||
|
<button className="btn btn-primary p-2 border my-1" data-id="homeTabNewFile" style={{width: 'fit-content'}} onClick={() => createNewFile()}>New File</button> |
||||||
|
<label className="btn p-2 border my-1" style={{width: 'fit-content'}} htmlFor="openFileInput">Open File</label> |
||||||
|
<input title="open file" type="file" id="openFileInput" onChange={(event) => { |
||||||
|
event.stopPropagation() |
||||||
|
plugin.verticalIcons.select('filePanel') |
||||||
|
uploadFile(event.target) |
||||||
|
}} multiple /> |
||||||
|
<button className="btn p-2 border my-1" style={{width: 'fit-content'}} onClick={() => connectToLocalhost()}>Connect to Localhost</button> |
||||||
|
<label className="pt-2">Load From</label> |
||||||
|
<div className="d-flex"> |
||||||
|
<button className="btn p-2 border mr-2" data-id="landingPageImportFromGitHubButton" onClick={() => showFullMessage('GitHub', 'github URL', ['https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/nf-token-metadata.sol', 'https://github.com/OpenZeppelin/openzeppelin-solidity/blob/67bca857eedf99bf44a4b6a0fc5b5ed553135316/contracts/access/Roles.sol'])}>GitHub</button> |
||||||
|
<button className="btn p-2 border mr-2" data-id="landingPageImportFromGistButton" onClick={() => importFromGist()}>Gist</button> |
||||||
|
<button className="btn p-2 border mr-2" onClick={() => showFullMessage('Ipfs', 'ipfs URL', ['ipfs://<ipfs-hash>'])}>IPFS</button>
|
||||||
|
<button className="btn p-2 border" onClick={() => showFullMessage('Https', 'http/https raw content', ['https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/token/ERC20/ERC20.sol'])}>HTTPS</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default HomeTabFile |
@ -0,0 +1,88 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React, { useEffect, useState, useRef, useContext } from 'react' |
||||||
|
import { ThemeContext, themes } from '../themeContext' |
||||||
|
import Carousel from 'react-multi-carousel' |
||||||
|
import WorkspaceTemplate from './workspaceTemplate' |
||||||
|
import 'react-multi-carousel/lib/styles.css' |
||||||
|
import CustomNavButtons from './customNavButtons' |
||||||
|
declare global { |
||||||
|
interface Window { |
||||||
|
_paq: any |
||||||
|
} |
||||||
|
} |
||||||
|
const _paq = window._paq = window._paq || [] //eslint-disable-line
|
||||||
|
|
||||||
|
interface HomeTabGetStartedProps { |
||||||
|
plugin: any |
||||||
|
} |
||||||
|
|
||||||
|
function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) { |
||||||
|
const themeFilter = useContext(ThemeContext) |
||||||
|
|
||||||
|
const createWorkspace = async (templateName) => { |
||||||
|
await plugin.appManager.activatePlugin('filePanel') |
||||||
|
const timeStamp = Date.now() |
||||||
|
await plugin.call('filePanel', 'createWorkspace', templateName + "_" + timeStamp, templateName) |
||||||
|
await plugin.call('filePanel', 'setWorkspace', templateName + "_" + timeStamp) |
||||||
|
plugin.verticalIcons.select('filePanel') |
||||||
|
_paq.push(['trackEvent', 'homeGetStarted', templateName]) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="pl-2" id="hTGetStartedSection"> |
||||||
|
<label style={{fontSize: "1.2rem"}}> |
||||||
|
<span className="mr-2" style={{fontWeight: "bold"}}> |
||||||
|
Get Started |
||||||
|
</span> |
||||||
|
- Project Templates |
||||||
|
</label> |
||||||
|
<div className="w-100 d-flex flex-column"> |
||||||
|
<ThemeContext.Provider value={ themeFilter }> |
||||||
|
<Carousel
|
||||||
|
focusOnSelect |
||||||
|
customButtonGroup={<CustomNavButtons next={undefined} previous={undefined} goToSlide={undefined} />} |
||||||
|
arrows={false} |
||||||
|
swipeable={false} |
||||||
|
draggable={true} |
||||||
|
showDots={false} |
||||||
|
responsive={{ desktop: { breakpoint: { max: 3000, min: 1024 }, items: 5} }} |
||||||
|
renderButtonGroupOutside={true} |
||||||
|
ssr={true} // means to render carousel on server-side.
|
||||||
|
keyBoardControl={true} |
||||||
|
containerClass="carousel-container" |
||||||
|
deviceType={"desktop"} |
||||||
|
itemClass="w-100" |
||||||
|
> |
||||||
|
<WorkspaceTemplate |
||||||
|
gsID="starkNetLogo" |
||||||
|
workspaceTitle="Blank" |
||||||
|
description="Create an empty workspace." |
||||||
|
callback={() => createWorkspace("blank")} /> |
||||||
|
<WorkspaceTemplate |
||||||
|
gsID="solhintLogo" |
||||||
|
workspaceTitle="Remix Default" |
||||||
|
description="Create a workspace with sample files." |
||||||
|
callback={() => createWorkspace("remixDefault")} /> |
||||||
|
<WorkspaceTemplate |
||||||
|
gsID="sourcifyLogo" |
||||||
|
workspaceTitle="OpenZeppelin ERC20" |
||||||
|
description="Create an ERC20 token by importing OpenZeppelin library." |
||||||
|
callback={() => createWorkspace("ozerc20")} /> |
||||||
|
<WorkspaceTemplate |
||||||
|
gsID="sUTLogo" |
||||||
|
workspaceTitle="OpenZeppelin ERC721" |
||||||
|
description="Create an NFT token by importing OpenZeppelin library." |
||||||
|
callback={() => createWorkspace("ozerc721")} /> |
||||||
|
<WorkspaceTemplate |
||||||
|
gsID="sUTLogo" |
||||||
|
workspaceTitle="0xProject ERC20" |
||||||
|
description="Create an ERC20 token by importing 0xProject contract." |
||||||
|
callback={() => createWorkspace("zeroxErc20")} /> |
||||||
|
</Carousel> |
||||||
|
</ThemeContext.Provider> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default HomeTabGetStarted |
@ -0,0 +1,76 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React, { useEffect, useState, useContext } from 'react' |
||||||
|
import { ThemeContext } from '../themeContext' |
||||||
|
declare global { |
||||||
|
interface Window { |
||||||
|
_paq: any |
||||||
|
} |
||||||
|
} |
||||||
|
const _paq = window._paq = window._paq || [] //eslint-disable-line
|
||||||
|
|
||||||
|
enum VisibleTutorial { |
||||||
|
Basics, |
||||||
|
Intermediate, |
||||||
|
Advanced |
||||||
|
} |
||||||
|
interface HomeTabLearnProps { |
||||||
|
plugin: any |
||||||
|
} |
||||||
|
|
||||||
|
function HomeTabLearn ({plugin}: HomeTabLearnProps) { |
||||||
|
const [state, setState] = useState<{ |
||||||
|
visibleTutorial: VisibleTutorial |
||||||
|
}>({ |
||||||
|
visibleTutorial: VisibleTutorial.Basics |
||||||
|
}) |
||||||
|
|
||||||
|
const themeFilter = useContext(ThemeContext) |
||||||
|
|
||||||
|
const openLink = () => { |
||||||
|
window.open("https://remix-ide.readthedocs.io/en/latest/remix_tutorials_learneth.html?highlight=learneth#learneth-tutorial-repos", '_blank') |
||||||
|
} |
||||||
|
|
||||||
|
const startLearnEthTutorial = async (tutorial) => { |
||||||
|
await plugin.appManager.activatePlugin(['solidity', 'LearnEth', 'solidityUnitTesting']) |
||||||
|
plugin.call('LearnEth', 'startTutorial', 'ethereum/remix-workshops', 'master', tutorial) |
||||||
|
plugin.verticalIcons.select('LearnEth') |
||||||
|
_paq.push(['trackEvent', 'homeTab', 'startLearnEthTutorial', tutorial]) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="d-flex px-2 pb-2 pt-2 d-flex flex-column" id="hTLearnSection"> |
||||||
|
<div className="d-flex justify-content-between"> |
||||||
|
<label className="py-2 align-self-center m-0" style={{fontSize: "1.2rem"}}>Learn</label> |
||||||
|
<button |
||||||
|
onClick={ ()=> openLink()} |
||||||
|
className="h-100 px-2 pt-0 btn" |
||||||
|
> |
||||||
|
<img className="align-self-center" src="assets/img/learnEthLogo.webp" alt="" style={ { filter: themeFilter.filter, width: "1rem", height: "1ren" } } /> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
<div className="d-flex flex-column"> |
||||||
|
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Basics }})}> |
||||||
|
<label className="float-left" style={{fontSize: "1rem"}}>Remix Basics</label> |
||||||
|
{(state.visibleTutorial === VisibleTutorial.Basics) && <div className="pt-2 d-flex flex-column text-left"> |
||||||
|
<span>Introduction to Remix's interface and concepts used in Ethereum, as well as the basics of Solidity.</span> |
||||||
|
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('basics')}>Get Started</button> |
||||||
|
</div>} |
||||||
|
</button> |
||||||
|
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Intermediate }})}> |
||||||
|
<label className="float-left" style={{fontSize: "1rem"}}>Remix Intermediate</label> |
||||||
|
{(state.visibleTutorial === VisibleTutorial.Intermediate) && <div className="pt-2 d-flex flex-column text-left">Using the web3.js to interact with a contract. Using Recorder tool. |
||||||
|
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('useofweb3js')}>Get Started</button> |
||||||
|
</div>} |
||||||
|
</button> |
||||||
|
<button className="d-flex flex-column btn border" onClick={() => setState((prevState) => {return { ...prevState, visibleTutorial: VisibleTutorial.Advanced }})}> |
||||||
|
<label className="float-left" style={{fontSize: "1rem"}}>Remix Advanced</label> |
||||||
|
{(state.visibleTutorial === VisibleTutorial.Advanced) && <div className="pt-2 d-flex flex-column text-left">Learn the Proxy Pattern and working with Libraries in Remix. Learn to use the Debugger. |
||||||
|
<button className="btn btn-sm btn-secondary mt-2" style={{width: 'fit-content'}} onClick={() => startLearnEthTutorial('deploylibraries')}>Get Started</button> |
||||||
|
</div>} |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default HomeTabLearn |
@ -0,0 +1,28 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React from 'react' |
||||||
|
|
||||||
|
function HomeTabScamAlert () { |
||||||
|
return ( |
||||||
|
<div className="" id="hTScamAlertSection"> |
||||||
|
<label className="pl-2 text-danger" style={{fontSize: "1.2rem"}}>Scam Alert</label> |
||||||
|
<div className="py-2 ml-2 mb-1 align-self-end mb-2 d-flex flex-column border border-danger"> |
||||||
|
<span className="pl-4 mt-2"> |
||||||
|
<i className="pr-2 text-danger fas fa-exclamation-triangle"></i> |
||||||
|
<b>Scam Alerts:</b> |
||||||
|
</span> |
||||||
|
<span className="pl-4 mt-1"> |
||||||
|
The only URL Remix uses is remix.ethereum.org
|
||||||
|
</span> |
||||||
|
<span className="pl-4 mt-1">
|
||||||
|
Beware of online videos promoting "liquidity front runner bots":
|
||||||
|
<a className="pl-2 remixui_home_text" target="__blank" href="https://medium.com/remix-ide/remix-in-youtube-crypto-scams-71c338da32d">Learn more</a> |
||||||
|
</span> |
||||||
|
<span className="pl-4 mt-1"> |
||||||
|
Additional safety tips: <a className="remixui_home_text" target="__blank" href="https://remix-ide.readthedocs.io/en/latest/security.html">here</a> |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default HomeTabScamAlert |
@ -0,0 +1,148 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||||
|
import BasicLogo from 'libs/remix-ui/vertical-icons-panel/src/lib/components/BasicLogo' |
||||||
|
import { ThemeContext } from '../themeContext' |
||||||
|
import React, { useEffect, useState, useRef, useContext } from 'react' |
||||||
|
import { OverlayTrigger, Tooltip } from 'react-bootstrap'// eslint-disable-line
|
||||||
|
|
||||||
|
function HomeTabTitle() { |
||||||
|
useEffect(() => { |
||||||
|
document.addEventListener("keyup", (e) => handleSearchKeyDown(e)) |
||||||
|
return () => { |
||||||
|
document.removeEventListener("keyup", handleSearchKeyDown) |
||||||
|
} |
||||||
|
}, []) |
||||||
|
const [state, setState] = useState<{ |
||||||
|
searchDisable: boolean |
||||||
|
}>({ |
||||||
|
searchDisable: true |
||||||
|
}) |
||||||
|
|
||||||
|
const themeFilter = useContext(ThemeContext) |
||||||
|
const searchInputRef = useRef(null) |
||||||
|
const remiAudioEl = useRef(null) |
||||||
|
|
||||||
|
const playRemi = async () => { |
||||||
|
remiAudioEl.current.play() |
||||||
|
} |
||||||
|
const handleSearchKeyDown = (e: KeyboardEvent) => { |
||||||
|
if (e.target !== searchInputRef.current) return |
||||||
|
if (e.key === "Enter") { |
||||||
|
openLink() |
||||||
|
searchInputRef.current.value = "" |
||||||
|
} else { |
||||||
|
setState(prevState => { |
||||||
|
return { ...prevState, searchDisable: searchInputRef.current.value === "" } |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const openLink = (url = "") => { |
||||||
|
if (url === "") { |
||||||
|
window.open("https://remix-ide.readthedocs.io/en/latest/search.html?q=" + searchInputRef.current.value + "&check_keywords=yes&area=default", '_blank') |
||||||
|
} else { |
||||||
|
window.open(url, '_blank') |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="px-2 pb-2 pt-2 d-flex flex-column border-bottom" id="hTTitleSection"> |
||||||
|
<div className="mr-4 d-flex"> |
||||||
|
<div onClick={() => playRemi()} style={{ filter: themeFilter.filter}} > |
||||||
|
<BasicLogo classList="align-self-end remixui_home_logoImg" solid={false} /> |
||||||
|
</div> |
||||||
|
<audio |
||||||
|
id="remiAudio" |
||||||
|
muted={false} |
||||||
|
src="assets/audio/remiGuitar-single-power-chord-A-minor.wav" |
||||||
|
ref={remiAudioEl} |
||||||
|
></audio> |
||||||
|
</div> |
||||||
|
<div className="d-flex justify-content-between"> |
||||||
|
<span className="h-80 text-uppercase" style={{ fontSize: 'xx-large', fontFamily: "Noah, sans-serif" }}>Remix</span> |
||||||
|
<span> |
||||||
|
<OverlayTrigger placement={'top'} overlay={ |
||||||
|
<Tooltip className="text-nowrap" id="overlay-tooltip"> |
||||||
|
<span className="border bg-light text-dark p-1 pr-3">Remix Youtube Playlist</span> |
||||||
|
</Tooltip> |
||||||
|
}> |
||||||
|
<button |
||||||
|
onClick={() => openLink("https://www.youtube.com/channel/UCjTUPyFEr2xDGN6Cg8nKDaA")} |
||||||
|
className="border-0 h-100 btn fab fa-youtube"> |
||||||
|
</button> |
||||||
|
</OverlayTrigger> |
||||||
|
|
||||||
|
<OverlayTrigger placement={'top'} overlay={ |
||||||
|
<Tooltip className="text-nowrap" id="overlay-tooltip"> |
||||||
|
<span className="border bg-light text-dark p-1 pr-3">Remix Twitter Profile</span> |
||||||
|
</Tooltip> |
||||||
|
}> |
||||||
|
<button |
||||||
|
onClick={() => openLink("https://twitter.com/EthereumRemix")} |
||||||
|
className="border-0 h-100 pl-2 btn fab fa-twitter"> |
||||||
|
</button> |
||||||
|
</OverlayTrigger> |
||||||
|
|
||||||
|
<OverlayTrigger placement={'top'} overlay={ |
||||||
|
<Tooltip className="text-nowrap" id="overlay-tooltip"> |
||||||
|
<span className="border bg-light text-dark p-1 pr-3">Remix Linkedin Profile</span> |
||||||
|
</Tooltip> |
||||||
|
}> |
||||||
|
<button |
||||||
|
onClick={() => openLink("https://www.linkedin.com/company/ethereum-remix/")} |
||||||
|
className="border-0 h-100 pl-2 btn fa fa-linkedin"> |
||||||
|
</button> |
||||||
|
</OverlayTrigger> |
||||||
|
|
||||||
|
<OverlayTrigger placement={'top'} overlay={ |
||||||
|
<Tooltip className="text-nowrap" id="overlay-tooltip"> |
||||||
|
<span className="border bg-light text-dark p-1 pr-3">Remix Medium Posts</span> |
||||||
|
</Tooltip> |
||||||
|
}> |
||||||
|
<button |
||||||
|
onClick={() => openLink("https://medium.com/remix-ide")} |
||||||
|
className="border-0 h-100 pl-2 btn fab fa-medium"> |
||||||
|
</button> |
||||||
|
</OverlayTrigger> |
||||||
|
|
||||||
|
<OverlayTrigger placement={'top'} overlay={ |
||||||
|
<Tooltip className="text-nowrap" id="overlay-tooltip"> |
||||||
|
<span className="border bg-light text-dark p-1 pr-3">Remix Gitter channel</span> |
||||||
|
</Tooltip> |
||||||
|
}> |
||||||
|
<button |
||||||
|
onClick={() => openLink("https://gitter.im/ethereum/remix")} |
||||||
|
className="border-0 h-100 pl-2 btn fab fa-gitter"> |
||||||
|
</button> |
||||||
|
</OverlayTrigger> |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
<b className="pb-1 text-dark" style={{ fontStyle: 'italic' }}>The Native IDE for Web3 Development.</b> |
||||||
|
<div className="pb-1" id="hTGeneralLinks"> |
||||||
|
<a className="remixui_home_text" target="__blank" href="https://remix-project.org">Website</a> |
||||||
|
<a className="pl-2 remixui_home_text" target="__blank" href="https://remix-ide.readthedocs.io/en/latest">Documentation</a> |
||||||
|
<a className="pl-2 remixui_home_text" target="__blank" href="https://remix-plugin-docs.readthedocs.io/en/latest/">Remix Plugin</a> |
||||||
|
<a className="pl-2 remixui_home_text" target="__blank" href="https://github.com/ethereum/remix-desktop/releases">Remix Desktop</a> |
||||||
|
</div> |
||||||
|
<div className="d-flex pb-1 align-items-center"> |
||||||
|
<input |
||||||
|
ref={searchInputRef} |
||||||
|
type="text" |
||||||
|
className="border form-control border-right-0" |
||||||
|
id="searchInput" |
||||||
|
placeholder="Search Documentation" |
||||||
|
data-id="terminalInputSearch" |
||||||
|
/> |
||||||
|
<button |
||||||
|
className="form-control border d-flex align-items-center p-2 justify-content-center fas fa-search bg-light" |
||||||
|
onClick={(e) => openLink()} |
||||||
|
disabled={state.searchDisable} |
||||||
|
style={{ width: "3rem" }} |
||||||
|
> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default HomeTabTitle |
@ -1,12 +0,0 @@ |
|||||||
.RSSFeed-item img { |
|
||||||
width: 100%; |
|
||||||
} |
|
||||||
|
|
||||||
.RSSFeed-item .truncate { |
|
||||||
max-height: 500px; |
|
||||||
overflow: hidden; |
|
||||||
} |
|
||||||
|
|
||||||
.RSSFeed-item .more-button { |
|
||||||
|
|
||||||
} |
|
@ -1,42 +0,0 @@ |
|||||||
import React, { useState, useEffect } from "react"; |
|
||||||
import Parser from "rss-parser"; |
|
||||||
import './rssFeed.css'; |
|
||||||
|
|
||||||
interface RSSFeedProps { |
|
||||||
feedUrl: string, |
|
||||||
maxItems: number, |
|
||||||
} |
|
||||||
|
|
||||||
export function RSSFeed({ feedUrl, maxItems }: RSSFeedProps) { |
|
||||||
const [feed, setFeed] = useState(null); |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
const fetchData = async () => { |
|
||||||
const parser = new Parser() |
|
||||||
const feed = await parser.parseURL(feedUrl); |
|
||||||
for (const item of feed.items) { |
|
||||||
item.content = item['content:encoded'] |
|
||||||
item.date = new Date(item.pubDate).toLocaleDateString('en-US', { |
|
||||||
month: 'short', |
|
||||||
day: 'numeric' |
|
||||||
}) |
|
||||||
} |
|
||||||
setFeed(feed); |
|
||||||
}; |
|
||||||
fetchData(); |
|
||||||
}, [feedUrl]); |
|
||||||
|
|
||||||
|
|
||||||
return (<> |
|
||||||
{feed && feed.items.slice(0, maxItems).map((item: any, index: any) => ( |
|
||||||
<div className='RSSFeed-item' key={index}> |
|
||||||
<a target="_blank" href={item.link}><h3>{item.title}</h3></a> |
|
||||||
<p>Author: {item.creator}</p> |
|
||||||
<h4>{item.date}</h4> |
|
||||||
<div className="truncate" dangerouslySetInnerHTML={{ __html: item.content }} /> |
|
||||||
<a className="more-button btn mb-3" target="_blank" href={item.link}>READ MORE</a> |
|
||||||
<hr></hr> |
|
||||||
</div> |
|
||||||
))} |
|
||||||
</>) |
|
||||||
} |
|
@ -0,0 +1,116 @@ |
|||||||
|
import * as React from "react"; |
||||||
|
export interface ResponsiveType { |
||||||
|
[key: string]: { |
||||||
|
breakpoint: { max: number; min: number }; |
||||||
|
items: number; |
||||||
|
partialVisibilityGutter?: number; // back-ward compatible, because previously there has been a typo
|
||||||
|
paritialVisibilityGutter?: number; |
||||||
|
slidesToSlide?: number; |
||||||
|
}; |
||||||
|
} |
||||||
|
export function isMouseMoveEvent( |
||||||
|
e: React.MouseEvent | React.TouchEvent |
||||||
|
): e is React.MouseEvent { |
||||||
|
return "clientX" && "clientY" in e; |
||||||
|
} |
||||||
|
export interface CarouselProps { |
||||||
|
responsive: ResponsiveType; |
||||||
|
deviceType?: string; |
||||||
|
ssr?: boolean; |
||||||
|
slidesToSlide?: number; |
||||||
|
draggable?: boolean; |
||||||
|
arrows?: boolean; // show or hide arrows.
|
||||||
|
renderArrowsWhenDisabled?: boolean; // Allow for the arrows to have a disabled attribute instead of not showing them
|
||||||
|
swipeable?: boolean; |
||||||
|
removeArrowOnDeviceType?: string | Array<string>; |
||||||
|
children: any; |
||||||
|
customLeftArrow?: React.ReactElement<any> | null; |
||||||
|
customRightArrow?: React.ReactElement<any> | null; |
||||||
|
customDot?: React.ReactElement<any> | null; |
||||||
|
customButtonGroup?: React.ReactElement<any> | null; |
||||||
|
infinite?: boolean; |
||||||
|
minimumTouchDrag?: number; // default 50px. The amount of distance to drag / swipe in order to move to the next slide.
|
||||||
|
afterChange?: (previousSlide: number, state: StateCallBack) => void; // Change callback after sliding everytime. `(previousSlide, currentState) => ...`
|
||||||
|
beforeChange?: (nextSlide: number, state: StateCallBack) => void; // Change callback before sliding everytime. `(previousSlide, currentState) => ...`
|
||||||
|
sliderClass?: string; // Use this to style your own track list.
|
||||||
|
itemClass?: string; // Use this to style your own Carousel item. For example add padding-left and padding-right
|
||||||
|
itemAriaLabel?: string; // Use this to add your own Carousel item aria-label.if it is not defined the child aria label will be applied if the child dont have one than a default empty string will be applied
|
||||||
|
containerClass?: string; // Use this to style the whole container. For example add padding to allow the "dots" or "arrows" to go to other places without being overflown.
|
||||||
|
className?: string; // Use this to style the whole container with styled-components
|
||||||
|
dotListClass?: string; // Use this to style the dot list.
|
||||||
|
keyBoardControl?: boolean; |
||||||
|
centerMode?: boolean; // show previous and next set of items partially
|
||||||
|
autoPlay?: boolean; |
||||||
|
autoPlaySpeed?: number; // default 3000ms
|
||||||
|
showDots?: boolean; |
||||||
|
renderDotsOutside?: boolean; // show dots outside of the container for custom styling.
|
||||||
|
renderButtonGroupOutside?: boolean; // show buttonGroup outside of the container for custom styling.
|
||||||
|
// Show next/previous item partially
|
||||||
|
// partialVisible has to be used in conjunction with the responsive props, details are in documentation.
|
||||||
|
// it shows the next set of items partially, different from centerMode as it shows both.
|
||||||
|
partialVisible?: boolean; |
||||||
|
partialVisbile?: boolean; // old typo - deprecated (will be remove in 3.0)
|
||||||
|
customTransition?: string; |
||||||
|
transitionDuration?: number; |
||||||
|
// if you are using customTransition, make sure to put the duration here.
|
||||||
|
// for example, customTransition="all .5" then put transitionDuration as 500.
|
||||||
|
// this is needed for the resizing to work.
|
||||||
|
focusOnSelect?: boolean; |
||||||
|
additionalTransfrom?: number; // this is only used if you want to add additional transfrom to the current transform
|
||||||
|
pauseOnHover?: boolean; |
||||||
|
shouldResetAutoplay?: boolean; |
||||||
|
rewind?: boolean; |
||||||
|
rewindWithAnimation?: boolean; |
||||||
|
rtl?: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export type StateCallBack = CarouselInternalState; |
||||||
|
|
||||||
|
export type Direction = "left" | "right" | "" | undefined; |
||||||
|
export type SkipCallbackOptions = |
||||||
|
| boolean |
||||||
|
| { skipBeforeChange?: boolean; skipAfterChange?: boolean }; |
||||||
|
export interface ButtonGroupProps { |
||||||
|
previous?: () => void; |
||||||
|
next?: () => void; |
||||||
|
goToSlide?: (index: number, skipCallbacks?: SkipCallbackOptions) => void; |
||||||
|
carouselState?: StateCallBack; |
||||||
|
} |
||||||
|
export interface ArrowProps { |
||||||
|
onClick?: () => void; |
||||||
|
carouselState?: StateCallBack; |
||||||
|
} |
||||||
|
export interface DotProps { |
||||||
|
index?: number; |
||||||
|
active?: boolean; |
||||||
|
onClick?: () => void; |
||||||
|
carouselState?: StateCallBack; |
||||||
|
} |
||||||
|
|
||||||
|
export interface CarouselInternalState { |
||||||
|
itemWidth: number; |
||||||
|
containerWidth: number; |
||||||
|
slidesToShow: number; |
||||||
|
currentSlide: number; |
||||||
|
totalItems: number; |
||||||
|
domLoaded: boolean; |
||||||
|
deviceType?: string; |
||||||
|
transform: number; |
||||||
|
} |
||||||
|
|
||||||
|
export default class Carousel extends React.Component<CarouselProps> { |
||||||
|
previous: (slidesHavePassed: number) => void; |
||||||
|
next: (slidesHavePassed: number) => void; |
||||||
|
goToSlide: (slide: number, skipCallbacks?: SkipCallbackOptions) => void; |
||||||
|
state: CarouselInternalState; |
||||||
|
setClones: ( |
||||||
|
slidesToShow: number, |
||||||
|
itemWidth?: number, |
||||||
|
forResizing?: boolean |
||||||
|
) => void; // reset carousel in infinite mode.
|
||||||
|
setItemsToShow: (shouldCorrectItemPosition?: boolean) => void; // reset carousel in non-infinite mode.
|
||||||
|
correctClonesPosition: ({ domLoaded }: { domLoaded: boolean }) => void; |
||||||
|
onMove: boolean; |
||||||
|
direction: Direction; |
||||||
|
containerRef: React.RefObject<HTMLDivElement>; |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||||
|
import React, { useContext } from 'react' |
||||||
|
interface WorkspaceTemplateProps { |
||||||
|
gsID: string, |
||||||
|
workspaceTitle: string, |
||||||
|
callback: any, |
||||||
|
description: string, |
||||||
|
} |
||||||
|
|
||||||
|
function WorkspaceTemplate ({ gsID, workspaceTitle, description, callback }: WorkspaceTemplateProps) { |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="d-flex remixui_home_workspaceTemplate"> |
||||||
|
<button |
||||||
|
className="btn border-secondary p-1 d-flex flex-column text-nowrap justify-content-center align-items-center mr-2 remixui_home_workspaceTemplate" |
||||||
|
data-id={'landingPageStart' + gsID} |
||||||
|
onClick={() => callback()} |
||||||
|
> |
||||||
|
<div className="w-100 p-2 h-100 align-items-start d-flex flex-column"> |
||||||
|
<label className="h6 pb-1 text-uppercase text-dark remixui_home_cursorStyle">{workspaceTitle}</label> |
||||||
|
<div className="remixui_home_gtDescription">{description}</div> |
||||||
|
</div> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default WorkspaceTemplate |
@ -1,12 +1,20 @@ |
|||||||
import React from 'react' |
import React from 'react' |
||||||
|
interface BasicLogoProps { |
||||||
|
classList?: string, |
||||||
|
solid?: boolean |
||||||
|
} |
||||||
|
|
||||||
function BasicLogo () { |
function BasicLogo ({classList = "", solid = true}: BasicLogoProps) { |
||||||
return (<svg id="Ebene_2" data-name="Ebene 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 105 100"> |
if (solid) { |
||||||
|
return (<svg id="Ebene_2" className={classList} data-name="Ebene 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 105 100"> |
||||||
<path d="M91.84,35a.09.09,0,0,1-.1-.07,41,41,0,0,0-79.48,0,.09.09,0,0,1-.1.07C9.45,35,1,35.35,1,42.53c0,8.56,1,16,6,20.32,2.16,1.85,5.81,2.3,9.27,2.22a44.4,44.4,0,0,0,6.45-.68.09.09,0,0,0,.06-.15A34.81,34.81,0,0,1,17,45c0-.1,0-.21,0-.31a35,35,0,0,1,70,0c0,.1,0,.21,0,.31a34.81,34.81,0,0,1-5.78,19.24.09.09,0,0,0,.06.15,44.4,44.4,0,0,0,6.45.68c3.46.08,7.11-.37,9.27-2.22,5-4.27,6-11.76,6-20.32C103,35.35,94.55,35,91.84,35Z"/> |
<path d="M91.84,35a.09.09,0,0,1-.1-.07,41,41,0,0,0-79.48,0,.09.09,0,0,1-.1.07C9.45,35,1,35.35,1,42.53c0,8.56,1,16,6,20.32,2.16,1.85,5.81,2.3,9.27,2.22a44.4,44.4,0,0,0,6.45-.68.09.09,0,0,0,.06-.15A34.81,34.81,0,0,1,17,45c0-.1,0-.21,0-.31a35,35,0,0,1,70,0c0,.1,0,.21,0,.31a34.81,34.81,0,0,1-5.78,19.24.09.09,0,0,0,.06.15,44.4,44.4,0,0,0,6.45.68c3.46.08,7.11-.37,9.27-2.22,5-4.27,6-11.76,6-20.32C103,35.35,94.55,35,91.84,35Z"/> |
||||||
<path d="M52,74,25.4,65.13a.1.1,0,0,0-.1.17L51.93,91.93a.1.1,0,0,0,.14,0L78.7,65.3a.1.1,0,0,0-.1-.17L52,74A.06.06,0,0,1,52,74Z"/> |
<path d="M52,74,25.4,65.13a.1.1,0,0,0-.1.17L51.93,91.93a.1.1,0,0,0,.14,0L78.7,65.3a.1.1,0,0,0-.1-.17L52,74A.06.06,0,0,1,52,74Z"/> |
||||||
<path d="M75.68,46.9,82,45a.09.09,0,0,0,.08-.09,29.91,29.91,0,0,0-.87-6.94.11.11,0,0,0-.09-.08l-6.43-.58a.1.1,0,0,1-.06-.18l4.78-4.18a.13.13,0,0,0,0-.12,30.19,30.19,0,0,0-3.65-6.07.09.09,0,0,0-.11,0l-5.91,2a.1.1,0,0,1-.12-.14L72.19,23a.11.11,0,0,0,0-.12,29.86,29.86,0,0,0-5.84-4.13.09.09,0,0,0-.11,0l-4.47,4.13a.1.1,0,0,1-.17-.07l.09-6a.1.1,0,0,0-.07-.1,30.54,30.54,0,0,0-7-1.47.1.1,0,0,0-.1.07l-2.38,5.54a.1.1,0,0,1-.18,0l-2.37-5.54a.11.11,0,0,0-.11-.06,30,30,0,0,0-7,1.48.12.12,0,0,0-.07.1l.08,6.05a.09.09,0,0,1-.16.07L37.8,18.76a.11.11,0,0,0-.12,0,29.75,29.75,0,0,0-5.83,4.13.11.11,0,0,0,0,.12l2.59,5.6a.11.11,0,0,1-.13.14l-5.9-2a.11.11,0,0,0-.12,0,30.23,30.23,0,0,0-3.62,6.08.11.11,0,0,0,0,.12l4.79,4.19a.1.1,0,0,1-.06.17L23,37.91a.1.1,0,0,0-.09.07A29.9,29.9,0,0,0,22,44.92a.1.1,0,0,0,.07.1L28.4,47a.1.1,0,0,1,0,.18l-5.84,3.26a.16.16,0,0,0,0,.11,30.17,30.17,0,0,0,2.1,6.76c.32.71.67,1.4,1,2.08a.1.1,0,0,0,.06,0L52,68.16H52l26.34-8.78a.1.1,0,0,0,.06-.05,30.48,30.48,0,0,0,3.11-8.88.1.1,0,0,0-.05-.11l-5.83-3.26A.1.1,0,0,1,75.68,46.9Z"/> |
<path d="M75.68,46.9,82,45a.09.09,0,0,0,.08-.09,29.91,29.91,0,0,0-.87-6.94.11.11,0,0,0-.09-.08l-6.43-.58a.1.1,0,0,1-.06-.18l4.78-4.18a.13.13,0,0,0,0-.12,30.19,30.19,0,0,0-3.65-6.07.09.09,0,0,0-.11,0l-5.91,2a.1.1,0,0,1-.12-.14L72.19,23a.11.11,0,0,0,0-.12,29.86,29.86,0,0,0-5.84-4.13.09.09,0,0,0-.11,0l-4.47,4.13a.1.1,0,0,1-.17-.07l.09-6a.1.1,0,0,0-.07-.1,30.54,30.54,0,0,0-7-1.47.1.1,0,0,0-.1.07l-2.38,5.54a.1.1,0,0,1-.18,0l-2.37-5.54a.11.11,0,0,0-.11-.06,30,30,0,0,0-7,1.48.12.12,0,0,0-.07.1l.08,6.05a.09.09,0,0,1-.16.07L37.8,18.76a.11.11,0,0,0-.12,0,29.75,29.75,0,0,0-5.83,4.13.11.11,0,0,0,0,.12l2.59,5.6a.11.11,0,0,1-.13.14l-5.9-2a.11.11,0,0,0-.12,0,30.23,30.23,0,0,0-3.62,6.08.11.11,0,0,0,0,.12l4.79,4.19a.1.1,0,0,1-.06.17L23,37.91a.1.1,0,0,0-.09.07A29.9,29.9,0,0,0,22,44.92a.1.1,0,0,0,.07.1L28.4,47a.1.1,0,0,1,0,.18l-5.84,3.26a.16.16,0,0,0,0,.11,30.17,30.17,0,0,0,2.1,6.76c.32.71.67,1.4,1,2.08a.1.1,0,0,0,.06,0L52,68.16H52l26.34-8.78a.1.1,0,0,0,.06-.05,30.48,30.48,0,0,0,3.11-8.88.1.1,0,0,0-.05-.11l-5.83-3.26A.1.1,0,0,1,75.68,46.9Z"/> |
||||||
</svg> |
</svg> |
||||||
) |
) |
||||||
|
} else { |
||||||
|
return (<img className="" src="assets/img/remix_logo_light.webp" style={{height: "3rem"}} alt=""></img>) |
||||||
|
} |
||||||
} |
} |
||||||
|
|
||||||
export default BasicLogo |
export default BasicLogo |