diff --git a/.github/workflows/deploy_production.yml b/.github/workflows/deploy_production.yml new file mode 100644 index 0000000..2759a33 --- /dev/null +++ b/.github/workflows/deploy_production.yml @@ -0,0 +1,38 @@ +name: Deploy production Website + +on: + push: + branches: + - main + +defaults: + run: + working-directory: ./frontend + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Build application + run: npm run generate + + - name: Deploy website + env: + APILLON_API_KEY: ${{ secrets.APILLON_API_KEY }} + APILLON_API_SECRET: ${{ secrets.APILLON_API_SECRET }} + WEBSITE_UUID: ${{ secrets.WEBSITE_UUID }} + run: | + npm i -g @apillon/cli + apillon hosting deploy-website ./.output/public --uuid $WEBSITE_UUID --key $APILLON_API_KEY --secret $APILLON_API_SECRET diff --git a/frontend/components/general/Spinner.vue b/frontend/components/general/Spinner.vue index 0de4105..213cb4f 100644 --- a/frontend/components/general/Spinner.vue +++ b/frontend/components/general/Spinner.vue @@ -35,6 +35,7 @@ defineProps({ position: absolute; top: 50%; left: 50%; + color: black; .path { stroke-dasharray: 8, 10; diff --git a/frontend/components/parts/Table/Users.vue b/frontend/components/parts/Table/Users.vue index 3844eed..17d8b36 100644 --- a/frontend/components/parts/Table/Users.vue +++ b/frontend/components/parts/Table/Users.vue @@ -29,7 +29,11 @@ const newUser = ref({ }); function isEditable(row: UserInterface, index: number) { - return !row.email && props.users.length === index + 1; + return ( + !row.email && + (props.users.length === index + 1 || + props.users.length % PaginationValues.PAGE_DEFAULT_LIMIT === index + 1) + ); } const createColumns = (): DataTableColumns => { diff --git a/frontend/composables/useContract.ts b/frontend/composables/useContract.ts index 8eefbd8..6cdbcf4 100644 --- a/frontend/composables/useContract.ts +++ b/frontend/composables/useContract.ts @@ -22,14 +22,42 @@ export default function useContract() { const usedChain = config.public.CHAIN_ID === Chains.MOONBASE ? moonbaseAlpha : moonbeam; const contract = ref(); + async function getTokenOfOwner(index: number) { + return (await contract.value.read.tokenOfOwnerByIndex([address.value, index])) as number; + } + async function getTokenUri(id: number) { return (await contract.value.read.tokenURI([id])) as string; } + async function watchAsset(nftId: string | number) { + if (!walletClient.value) { + await refetch(); + await sleep(200); + } + try { + const contractAddress = contract.value?.address + ? contract.value.address + : config.public.CONTRACT_ADDRESS; + + await walletClient.value.watchAsset({ + type: 'ERC721', + options: { + address: contractAddress, + tokenId: `${nftId}`, + }, + }); + return true; + } catch (e) { + contractError(e); + return false; + } + } + /** * Helper for initializing specific contract */ - async function initContract(contractAddress: string) { + async function initContract(contractAddress: `0x${string}`) { if (!walletClient.value) { await refetch(); await sleep(200); @@ -85,6 +113,9 @@ export default function useContract() { } else if (errorData.includes('valid recovery code')) { // Problem with embedded signature msg = 'Problem with embedded wallet'; + } else if (errorData.includes('Suggested NFT is not owned by the selected account ')) { + msg = + 'Suggested NFT is not owned by the selected account, please try again with other wallet.'; } else if ( errorData.includes('user rejected transaction') || errorData.includes('User rejected the request') @@ -103,7 +134,9 @@ export default function useContract() { return { contract, contractError, + getTokenOfOwner, getTokenUri, initContract, + watchAsset, }; } diff --git a/frontend/lib/config/development.ts b/frontend/lib/config/development.ts index a363209..b3cc6e9 100644 --- a/frontend/lib/config/development.ts +++ b/frontend/lib/config/development.ts @@ -1,10 +1,11 @@ -import { ConfigInterface } from '~/lib/types/general.types'; - const config: ConfigInterface = { APP_URL: 'http://localhost:3000', API_BASE: 'http://localhost:3001', CAPTCHA_KEY: '10000000-ffff-ffff-ffff-000000000001', CHAIN_ID: 1287, + CONTRACT_ADDRESS: null, + METADATA_BASE_URI: null, + METADATA_TOKEN: null, }; export default config; diff --git a/frontend/lib/config/production.ts b/frontend/lib/config/production.ts index 55d455e..5b4ae4a 100644 --- a/frontend/lib/config/production.ts +++ b/frontend/lib/config/production.ts @@ -1,10 +1,13 @@ -import { ConfigInterface } from '~/lib/types/general.types'; - const config: ConfigInterface = { - APP_URL: 'https://ment-stg.nectarnode.io', + APP_URL: 'https://nft.ment.si', API_BASE: 'https://ment-api.apillon.io', CAPTCHA_KEY: 'f363ce6d-7543-4284-9caa-cf3219723f04', CHAIN_ID: 1287, + CONTRACT_ADDRESS: '0x208C1bfa90faC3aED3587a1D9d6F8119aF45FdA6', + METADATA_BASE_URI: + 'https://k2k4r8p41ygxp9ogebtgstf7ix8qqn11qdcu2ld4u08896kei1wmcbj3.ipns.nectarnode.io/', + METADATA_TOKEN: + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjaWQiOiJrMms0cjhwNDF5Z3hwOW9nZWJ0Z3N0ZjdpeDhxcW4xMXFkY3UybGQ0dTA4ODk2a2VpMXdtY2JqMyIsInByb2plY3RfdXVpZCI6IjdhMGQzNzgyLTVhODgtNGYxNS04Yjg4LTA1MTNiOTczNDhjMyIsImlhdCI6MTcwODMyNzg2OCwic3ViIjoiSVBGUy10b2tlbiJ9.dByI1FQ8rj8_dd89r_BtpF0DEdsLNOIovt-7J2mRsB0', }; export default config; diff --git a/frontend/lib/config/staging.ts b/frontend/lib/config/staging.ts index b9841f6..9e2a680 100644 --- a/frontend/lib/config/staging.ts +++ b/frontend/lib/config/staging.ts @@ -1,10 +1,11 @@ -import { ConfigInterface } from '~/lib/types/general.types'; - const config: ConfigInterface = { APP_URL: 'https://app-stg.apillon.io', API_BASE: 'https://api-stg.apillon.io', CAPTCHA_KEY: '10000000-ffff-ffff-ffff-000000000001', CHAIN_ID: 1284, + CONTRACT_ADDRESS: null, + METADATA_BASE_URI: null, + METADATA_TOKEN: null, }; export default config; diff --git a/frontend/lib/types/general.types.ts b/frontend/lib/types/general.types.ts index 5281759..9335798 100644 --- a/frontend/lib/types/general.types.ts +++ b/frontend/lib/types/general.types.ts @@ -6,6 +6,9 @@ declare global { API_BASE: string; CHAIN_ID: number; CAPTCHA_KEY: string; + CONTRACT_ADDRESS: string | null; + METADATA_BASE_URI: string | null; + METADATA_TOKEN: string | null; } type AuthResponseProfile = { diff --git a/frontend/pages/claim.vue b/frontend/pages/claim.vue index 9f1e015..66c0533 100644 --- a/frontend/pages/claim.vue +++ b/frontend/pages/claim.vue @@ -1,5 +1,6 @@