This repository contains source code for POA website.
Solution has 2 main parts. Admin dashboard and page for NFT(POAPs) claim. In admin dashboard, admin manages it's events, see their status, statistic, ... Admin can create new POAP event, set its title, start and end time and link it with existing NFT collection created in Apillon platform.
Second part of solution is website which is meant to be displayed at the event. Flow:
- User scans qr code from page
- Qr code contains URL to page, where user enter its email
- Email with instructions and link for mint is sent to that address
- User navigates to minting page, connects his wallet and mint NFT to it
- Recieved NFT is a POA
- node >= 18.16.1
- Nuxt 3
- Vue 3 w/ TypeScript
- Pinia Store
- NaiveUI
- TailwindCSS
Before uploading the website to (Apillon) hosting, feel free to edit the code, add any customization or just review whether everything works as expected.
To preview the website on your computer you need to serve a http server from the root folder of the website. For example, you can run node package http-server from root folder like this:
npm install
npm run dev
To deploy the website on Apillon hosting you need to build project with a command below:
npm run generate
And then deploy folder dist according to this documentation: Wiki
- If not already, register to Apillon.io
- Log in to Apillon console and create new website inside your project.
- Select all files of your website (as configured in the previous step) and use drag&drop action to pull the files into the Hosting bucket
- Once the files are uploaded, push them to Staging and finally to the Production
- Add your custom domain (as displayed in the dashboards UI)
- Review your newly deployed website
To deploy your website to Apillon Hosting you should:
- Clone this repository and configure it to your needs.
- If not already, register to Apillon.io
- Log in to Apillon console and create new website inside your project.
- In settings, create an API KEY with storage permissions. Write down API key and API secret.
- In your github repository setup actions secrets (variables)
- WEBSITE_UUID : copy UUID from website overview in Apillon dashboard
- APILLON_API_KEY : your previously created API key
- APILLON_API_SECRET : your previously created API secret
Now everything should be ready. When you will push to master branch, your website should start deploy to Apillon IPFS hosting. Monitor progress on Apillon.io dashboard. After some time you'll be able to get IPNS url and also setup your own domain.
You can change behavior of the automatic deployment by editing ../.github/workflows/deploy.yml.
Naive UI is used for default frontend components.
Its styles can be modified globally in /lib/config/naive.ts
- docs.
Each naive component also has the :theme-overrides
prop to overwrite styles per specific usage.
<n-tabs
type="segment"
size="small"
:theme-overrides="{ panePaddingSmall: '1.5rem 0 0 0' }"
></n-tabs>
API interaction should be done with api wrapper globally imported as $api
(/lib/utils/api.ts
).
API global interceptors (onRequest, onResponse, onForbidden) are also defined in /lib/utils/api.ts
.
Api requests throw errors, handle them with try catches. useHandleError(e)
can be used for general error handling (eg. toast display).
try {
await $api.post('/login', formData);
} catch (e: any) {
useHandleError(e);
}
Many common tasks can be solved with using helper functions from vueuse. Use those instead of reinventing the wheel.
eg.
useIntersectionObserver();
useInfiniteScroll();
useScroll();
useScrollLock();
Add icon svg to /assets/icons
, then use <NuxtIcon :name="" />
component to use the icon - set name prop to filename. Implements nuxt-icons.
Control size with font-size.
<NuxtIcon name="close" class="inline-block text-[18px] mr-3 align-middle" />
For basic styles, use tailwind breakpoint system. For js usage, use useScreen
composable.
const screens = reactive(useScreen());
// or
const { isXl } = useScreen();
<div v-if="screens.isXl" class="w-8 h-8 bg-red"></div>
<div v-else class="w-8 h-8 bg-blue"></div>
Implements naive-ui modal.
<Modal v-model:show="isModal" title="MY Modal">
<div>ETC</div>
</Modal>
Wallet integration can be implemented with use-wagmi and viem. Docs for wagmi: docs (react docs, but most hooks are supported).
Check for implementation on branch crypto
.
Configuration is in /plugins/use-wagmi.ts
.
Helpers are in /composables/blockchain/**
and /components/parts/Wallet/**
.
Use Nuxt i18n.
Check for implementation on branch i18n
. Basically:
- install module and add config to
nuxt.config.ts
- add translation json file:
/locales/en.json
- add language switch component
In template
In script
const { t } = useI18n();
const label = t('investments.details.location');
Internal links can be simple paths if using strategy: 'no_prefix'
. Otherwise localePath()
helper should be used.