Skip to content

Commit

Permalink
Updated frontend (#2139)
Browse files Browse the repository at this point in the history
* feat: update contracts

* feat:update frontend
  • Loading branch information
matiasbenary authored Apr 11, 2024
1 parent 86f6799 commit dc17129
Show file tree
Hide file tree
Showing 41 changed files with 4,558 additions and 28,125 deletions.
5 changes: 2 additions & 3 deletions src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ export const successContractToText = (contract: Contract) =>

const frontendTemplates: FrontendMessage = {
'next-page': 'NextJS (Classic)',
'next-app': 'NextJS (App Router)',
vanilla: 'Vanilla-JS',
'next-app': 'NextJS (App Router)'
};

export const successFrontendToText = (frontend: Frontend) =>
Expand Down Expand Up @@ -118,7 +117,7 @@ export const argsError = (msg: string) =>
show(chalk`{red Arguments error: {white ${msg}}}
Run {blue npx create-near-app} without arguments, or use:
npx create-near-app <projectName> [--frontend next|vanilla|none] [--contract rs|ts|none]`);
npx create-near-app <projectName> [--frontend next-app|next-page] [--contract rs|ts|none]`);

export const unsupportedNodeVersion = (supported: string) =>
show(chalk`{red We support node.js version ${supported} or later}`);
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type Contract = 'ts' | 'rs' | 'none';
export const CONTRACTS: Contract[] = ['ts', 'rs', 'none'];
export type Frontend = 'next-app' | 'next-page' | 'vanilla' | 'none';
export const FRONTENDS: Frontend[] = ['next-app' , 'next-page', 'vanilla', 'none'];
export type Frontend = 'next-app' | 'next-page' | 'none';
export const FRONTENDS: Frontend[] = ['next-app' , 'next-page', 'none'];
export type App = 'contract' | 'gateway';
export const APPS: App[] = ['contract', 'gateway'];
export type ProjectName = string;
Expand Down
3 changes: 1 addition & 2 deletions src/user-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import fs from 'fs';
export async function getUserArgs(): Promise<UserConfig> {
program
.argument('[projectName]')
.option('--frontend [next|vanilla|none]')
.option('--frontend [next-page|next-app|none]')
.option('--contract [ts|rs|none]')
.option('--install')
.addHelpText('after', 'You can create a frontend or a contract with tests');
Expand All @@ -45,7 +45,6 @@ const contractChoices: Choices<Contract> = [
const frontendChoices: Choices<Frontend> = [
{ title: 'NextJs (Classic)', description: 'A composable app built using Next.js, React and Near components', value: 'next-page' },
{ title: 'NextJS (App Router)', description: 'A composable app built using Next.js, React and Near components', value: 'next-app' },
{ title: 'Vanilla JS', description: 'A framework-less web app with limited capabilities.', value: 'vanilla' },
];

const appPrompt: PromptObject = {
Expand Down
39 changes: 3 additions & 36 deletions templates/frontend/next-app/.gitignore
Original file line number Diff line number Diff line change
@@ -1,36 +1,3 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
**/node_modules
**/.next
yarn.lock
37 changes: 16 additions & 21 deletions templates/frontend/next-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,27 @@
"lint": "next lint"
},
"dependencies": {
"@near-wallet-selector/core": "^8.5.1",
"@near-wallet-selector/here-wallet": "^8.5.1",
"@near-wallet-selector/modal-ui": "^8.5.1",
"@near-wallet-selector/my-near-wallet": "^8.5.1",
"@web3-onboard/core": "^2.20.2",
"@web3-onboard/injected-wallets": "^2.10.1",
"@web3-onboard/ledger": "^2.4.6",
"@web3-onboard/react": "^2.8.7",
"@web3-onboard/walletconnect": "^2.3.9",
"@near-wallet-selector/core": "^8.9.6",
"@near-wallet-selector/here-wallet": "^8.9.6",
"@near-wallet-selector/modal-ui": "^8.9.6",
"@near-wallet-selector/my-near-wallet": "^8.9.6",
"@web3-onboard/core": "^2.21.4",
"@web3-onboard/injected-wallets": "^2.10.14",
"@web3-onboard/ledger": "^2.6.0",
"@web3-onboard/react": "^2.8.15",
"@web3-onboard/walletconnect": "^2.5.4",
"base64-js": "^1.5.1",
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.11.1",
"ieee754": "^1.2.1",
"near-api-js": "^2.1.3",
"near-social-vm": "github:NearSocial/VM#2.5.2",
"next": "14.0.1",
"pino-pretty": "^10.2.3",
"near-api-js": "^3.0.4",
"near-social-vm": "github:gagdiez/VM" ,
"next": "14.1.4",
"pino-pretty": "^11.0.0",
"react": "^18",
"react-bootstrap": "2.9.1",
"react-bootstrap-icons": "^1.10.3",
"react-dom": "^18",
"react-singleton-hook": "^4.0.1",
"zustand": "^4.4.4"
"zustand": "^4.5.2"
},
"devDependencies": {
"eslint": "^8.53",
"eslint-config-next": "14.0.1"
"eslint": "^9.0",
"eslint-config-next": "14.1.4"
}
}
21 changes: 10 additions & 11 deletions templates/frontend/next-app/src/app/hello-components/page.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
'use client';
import dynamic from 'next/dynamic';

import styles from '@/app/app.module.css';
import { DocsCard, HelloNearCard } from '@/components/cards';
import { NetworkId, ComponentMap } from '@/config';
import { NetworkId, Components } from '@/config';

const Component = dynamic(() => import('@/components/vm-component'), { ssr: false });

const socialComponents = ComponentMap[NetworkId];

export default function HelloComponents() {

return (
Expand All @@ -16,20 +15,20 @@ export default function HelloComponents() {
<div className={styles.description}>
<p>
Loading components from: &nbsp;
<code className={styles.code}>{socialComponents.socialDB}</code>
<code className={styles.code}>{Components.socialDB}</code>
</p>
</div>
<div className={styles.center}>
<h1> <code>Multi-chain</code> Components Made Simple </h1>
</div>
<div className='row'>
<div className='col-6'>
<Component src={socialComponents.HelloNear} />
<p className='my-4'>&nbsp;</p>
<Component src={socialComponents.LoveNear} />
<div className="col-6">
<Component src={Components.HelloNear} />
<p className="my-4">&nbsp;</p>
<Component src={Components.LoveNear} />
</div>
<div className='col-6'>
<Component src={socialComponents.Lido} />
<div className="col-6">
<Component src={Components.Lido} />
</div>
</div>
<hr />
Expand All @@ -41,4 +40,4 @@ export default function HelloComponents() {
</main>
</>
);
}
}
28 changes: 17 additions & 11 deletions templates/frontend/next-app/src/app/hello-near/page.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
'use client';

import { DocsCard, HelloComponentsCard } from '@/components/cards';
import { useWallet } from '@/wallets/wallet-selector';
import { useState, useEffect } from 'react';
import { HelloNearContract, NetworkId } from '../../config';
import styles from '../app.module.css';

import { useStore } from '../layout';

// Contract that the app will interact with
const CONTRACT = HelloNearContract[NetworkId];
const CONTRACT = HelloNearContract;

export default function HelloNear() {
const { signedAccountId, viewMethod, callMethod } = useWallet();
const { signedAccountId, wallet } = useStore();

const [greeting, setGreeting] = useState('loading...');
const [newGreeting, setNewGreeting] = useState('loading...');
const [loggedIn, setLoggedIn] = useState(false);
const [showSpinner, setShowSpinner] = useState(false);

useEffect(() => {
viewMethod && viewMethod(CONTRACT, 'get_greeting', {}).then(
greeting => setGreeting(greeting)
);
}, [viewMethod]);
if (!wallet) return;

wallet.viewMethod({ contractId: CONTRACT, method: 'get_greeting' })
.then(greeting => setGreeting(greeting));
}, [wallet]);

useEffect(() => {
setLoggedIn(!!signedAccountId);
}, [signedAccountId]);

const saveGreeting = async () => {
const storeGreeting = async () => {
setShowSpinner(true);
await callMethod(CONTRACT, 'set_greeting', { greeting });
const res = await wallet.callMethod({ contractId: CONTRACT, method: 'set_greeting', args: { greeting: newGreeting } });
const greeting = await wallet.viewMethod({ contractId: CONTRACT, method: 'get_greeting' });
setGreeting(greeting);
setShowSpinner(false);
};

Expand All @@ -43,9 +49,9 @@ export default function HelloNear() {
<div className={styles.center}>
<h1 className="w-100"> The contract says: <code>{greeting}</code> </h1>
<div className="input-group" hidden={!loggedIn}>
<input type="text" className="form-control w-20" placeholder="Store a new greeting" onChange={t => { setGreeting(t.target.value); } } />
<input type="text" className="form-control w-20" placeholder="Store a new greeting" onChange={t => setNewGreeting(t.target.value)} />
<div className="input-group-append">
<button className="btn btn-secondary" onClick={saveGreeting}>
<button className="btn btn-secondary" onClick={storeGreeting}>
<span hidden={showSpinner}> Save </span>
<i className="spinner-border spinner-border-sm" hidden={!showSpinner}></i>
</button>
Expand Down
30 changes: 25 additions & 5 deletions templates/frontend/next-app/src/app/layout.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
'use client';
import './globals.css';
import '@near-wallet-selector/modal-ui/styles.css';

import { NetworkId } from '@/config';
// react
import { useEffect } from "react";
import { create as createStore } from 'zustand';

// app
import './globals.css';
import { Navigation } from '@/components/navigation';
import { useInitWallet } from '@/wallets/wallet-selector';
import { NetworkId, HelloNearContract } from '@/config';

// wallet-selector
import { Wallet } from '@/wallets/near-wallet';

// store to share wallet and signedAccountId
export const useStore = createStore((set) => ({
wallet: undefined,
signedAccountId: '',
setWallet: (wallet) => set({ wallet }),
setSignedAccountId: (signedAccountId) => set({ signedAccountId })
}))

// Layout Component
export default function RootLayout({ children }) {
const { setWallet, setSignedAccountId } = useStore();

useInitWallet({ createAccessKeyFor: '', networkId: NetworkId });
useEffect(() => {
const wallet = new Wallet({ networkId: NetworkId, createAccessKeyFor: HelloNearContract });
wallet.startUp(setSignedAccountId);
setWallet(wallet);
}, []);

return (
<html lang="en">
Expand Down
15 changes: 8 additions & 7 deletions templates/frontend/next-app/src/components/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,31 @@ import Image from 'next/image';
import Link from 'next/link';
import { useEffect, useState } from 'react';

import NearLogo from 'public/near-logo.svg';
import { useWallet } from '@/wallets/wallet-selector';
import { useStore } from '@/app/layout';

export const Navigation = () => {

const { signedAccountId, logOut, logIn } = useWallet();
const { signedAccountId, wallet } = useStore();
const [action, setAction] = useState(() => { });
const [label, setLabel] = useState('Loading...');

useEffect(() => {
if (!wallet) return;

if (signedAccountId) {
setAction(() => logOut);
setAction(() => wallet.signOut);
setLabel(`Logout ${signedAccountId}`);
} else {
setAction(() => logIn);
setAction(() => wallet.signIn);
setLabel('Login');
}
}, [signedAccountId, logOut, logIn, setAction, setLabel]);
}, [signedAccountId, wallet]);

return (
<nav className="navbar navbar-expand-lg">
<div className="container-fluid">
<Link href="/" passHref legacyBehavior>
<Image priority src={NearLogo} alt="NEAR" width="30" height="24" className="d-inline-block align-text-top" />
<Image priority src="/near-logo.svg" alt="NEAR" width="30" height="24" className="d-inline-block align-text-top" />
</Link>
<div className='navbar-nav pt-1'>
<button className="btn btn-secondary" onClick={action} > {label} </button>
Expand Down
15 changes: 7 additions & 8 deletions templates/frontend/next-app/src/components/vm-component.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
'use client';
import { useEffect } from 'react';
import { useInitNear, Widget, EthersProviderContext } from 'near-social-vm';

import { useWallet } from '@/wallets/wallet-selector';
import { Widget, EthersProviderContext } from 'near-social-vm';
import { useEthersProviderContext } from '@/wallets/web3-wallet';
import { useInitNear } from 'near-social-vm';
import { useEffect } from 'react';
import { useStore } from '@/app/layout';
import { NetworkId } from '@/config';

export default function Component({ src }) {
const ethersContext = useEthersProviderContext();
const { selector } = useWallet();
const { wallet } = useStore();
const { initNear } = useInitNear();

useEffect(() => {
initNear && selector && initNear({ networkId: NetworkId, selector });
}, [initNear, selector]);
wallet && initNear && initNear({ networkId: NetworkId, selector: wallet.selector });
}, [wallet, initNear]);

return (
<div>
Expand Down
12 changes: 7 additions & 5 deletions templates/frontend/next-app/src/config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
export const NetworkId = 'testnet';

export const HelloNearContract = {
const contractPerNetwork = {
mainnet: 'hello.near-examples.near',
testnet: 'hello.near-examples.testnet',
}

export const ComponentMap = {
const componentsPerNetwork = {
mainnet: {
socialDB: 'social.near',
Lido: 'zavodil.near/widget/Lido',
Expand All @@ -18,4 +16,8 @@ export const ComponentMap = {
HelloNear: 'influencer.testnet/widget/HelloNear',
LoveNear: 'influencer.testnet/widget/LoveNear',
}
}
}

export const NetworkId = 'testnet';
export const HelloNearContract = contractPerNetwork[NetworkId];
export const Components = componentsPerNetwork[NetworkId];
Loading

0 comments on commit dc17129

Please sign in to comment.