Skip to content

Commit

Permalink
feat: connection to firebase database for setting questions
Browse files Browse the repository at this point in the history
  • Loading branch information
ghimiresdp committed Apr 1, 2023
1 parent 8c196fc commit 93940a0
Show file tree
Hide file tree
Showing 15 changed files with 832 additions and 208 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,31 @@ bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/can
でブートストラップされた CIT-Coin フロントエンド プロジェクト [Next.js](https://nextjs.org/)
プロジェクトです。

## Encoding Google API Keys:

This application needs
[`Google Service Account`](https://cloud.google.com/iam/docs/service-account-overview)
for running and accessing `Google Sheets` and `Google Firebase Database`.

If you want to encode keys to base64 format for setting it in an environment
variable, you can check it with the following command:

**Example:**

```shell
yarn encode-keys --file keys/google-sheets-service-account.json
```

## Running the Interface

We can simply run the `dev` command to run the Next.js app in the development mode. to build, We can run the `build` command.
We can simply run the `dev` command to run the Next.js app in the development mode. to build, We can run the `build`
command.

```shell
yarn dev # development server
yarn build
```


## External Links:

1. Spreadsheets API: https://developers.google.com/sheets/api/quickstart/js
Expand Down
10 changes: 10 additions & 0 deletions keys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,15 @@
> *Note:* _This folder contains sensitive key files. Do not commit any files from this directory._
The folder might contain key files for:

- GOOGLE SHEETS API
- GOOGLE IAM Service Account Credentials, etc.

If you want to encode keys to base64 format for setting it in an environment variable, you can check it with the
following command

**Example:**

```shell
yarn encode-keys --file keys/google-sheets-service-account.json
```
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "cypress open --e2e --browser electron"
"test": "cypress open --e2e --browser electron",
"encode-keys": "node scripts/encode-google-keys.js"
},
"dependencies": {
"@chakra-ui/icons": "^2.0.17",
Expand All @@ -19,6 +20,7 @@
"@types/react-dom": "18.0.11",
"axios": "^1.3.4",
"ethers": "^5",
"firebase": "^9.19.1",
"framer-motion": "^10.2.4",
"google-spreadsheet": "^3.3.0",
"googleapis": "^113.0.0",
Expand Down
39 changes: 39 additions & 0 deletions scripts/encode-google-keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const { readFile, writeFile } = require('fs');
const path = require('path');
// process.argv
// let filename = fs.open(process.argv([1]))

// console.log(process.argv);
// console.log(process.argv.indexOf('--file'))
const path_idx = process.argv.indexOf('--file') + 1;

if (path_idx < 1 || process.argv.length < path_idx) {
console.log(`
invalid arguments supplied !!
please try with arguments:
--file [ path_of_the_file ]
`);
process.exit(1);
}

const filename = process.argv[path_idx];

let file = readFile(filename, (err, data) => {
let content = data.toString('base64');

console.log(content, '\n');

writeFile(`${filename}.txt`, content, (err) => {
if (err) {
console.log('Could not write to the file');
process.exit(1);
} else {
console.log(`successfully wrote key to ${path.resolve(filename)}.txt`);
process.exit(0);
}
});
});
6 changes: 3 additions & 3 deletions src/components/admin/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const AdminSetting = () => {
<Button
type={'submit'} my={5} colorScheme={'blue'}
isLoading={contractWriteLoading}
isDisabled={(!!configError || !isAddress(admin) || admin==currentAdmin)}
isDisabled={(!!configError || !isAddress(admin) || admin == currentAdmin)}
>{t('SUBMIT')}</Button>
</form>);
};
Expand All @@ -126,9 +126,9 @@ export const Settings = () => {
<Heading mb={5}>{t('settings.HEADING')}</Heading>
<Stack spacing={10}>
<RewardPointSetting />
<hr/>
<hr />
<AdminSetting />
<hr/>
<hr />
</Stack>
</Container>
);
Expand Down
31 changes: 31 additions & 0 deletions src/components/admin/StudentManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,36 @@ const AddSingleStudentForm = () => {
</form>);
};


const AddMultipleStudentForm = () => {
const { t } = useTranslation('admin');

return (<form onSubmit={(event) => {
event.preventDefault();
// ContractWrite?.();
}}>
<FormControl isInvalid={false}>
{/*todo: change later*/}
<FormLabel>
{t('students.ENTER_ADDRESS')}
</FormLabel>
<Input
fontFamily={'mono'}
// value={studentAddress}
// onChange={(event) => {
// setStudentAddress(event.target.value as `0x${string}`);
// }}
/>
<FormErrorMessage>{t('students.ENTER_VALID_ADDRESS')}</FormErrorMessage>
</FormControl>
<Button
type={'submit'} my={5} colorScheme={'blue'}
// isLoading={contractWriteLoading}
// isDisabled={(!!configError || !isAddress(studentAddress))}
>{t('students.ADD_STUDENT')}</Button>
</form>);
};

export const StudentManager = () => {
const { t } = useTranslation('admin');
return (<>
Expand All @@ -58,6 +88,7 @@ export const StudentManager = () => {
<Stack spacing={10}>
<AddSingleStudentForm />
<hr />
<AddMultipleStudentForm/>
<hr />
<hr />
</Stack>
Expand Down
28 changes: 22 additions & 6 deletions src/layouts/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ import { default as NextLink } from 'next/link';
import { MoonIcon, SunIcon, LockIcon, UnlockIcon, WarningIcon } from '@chakra-ui/icons';
import setLanguage from 'next-translate/setLanguage';
import Head from 'next/head';
import { useAccount, useNetwork } from 'wagmi';
import { useAccount, useContractReads, useNetwork } from 'wagmi';
import { NavLink } from '@/components';
import { defaultChain } from '@/utils/contract';
import { defaultChain, getContractAddress } from '@/utils/contract';
import { ConnectionProfile } from '@/components/wallet';
import LearnToEarnABI from '@/utils/abis/LearnToEarn.json';

interface LayoutProps {
children: React.ReactNode;
Expand All @@ -38,6 +39,20 @@ const Layout = ({ children }: LayoutProps) => {
const { t, lang } = useTranslation('common');
const { colorMode, toggleColorMode } = useColorMode();

const LearnContract = {
address: getContractAddress('LearnToEarn'),
abi: LearnToEarnABI,
chainId: chain?.id,
};

const {
data: adminAddresses,
isError: contractReadError,
isLoading,
} = useContractReads({
contracts: ['admin', 'dev', 'owner'].map((_func) => ({ ...LearnContract, functionName: _func })),
});

return (
<>
<Head>
Expand All @@ -46,7 +61,7 @@ const Layout = ({ children }: LayoutProps) => {
<meta name='viewport' content='width=device-width, initial-scale=1' />
<link rel='icon' href='/favicon.ico' />
</Head>
<Flex px={8}>
<Flex px={8} position={'fixed'} top={0} left={0} right={0}>
<NavLink as={NextLink} href='/' mr={16}>
<Heading size='md'>
<pre>{t('nav.HEADING')}</pre>
Expand All @@ -72,11 +87,12 @@ const Layout = ({ children }: LayoutProps) => {
? 'orange'
: 'red'
}
leftIcon={isConnected &&chain?.id===defaultChain.id ?<LockIcon/>: isConnected? <WarningIcon/>: <UnlockIcon />}
leftIcon={isConnected && chain?.id === defaultChain.id ? <LockIcon /> : isConnected ? <WarningIcon /> :
<UnlockIcon />}
>
{isConnected ? `${t('wallet.CONNECTED')} - ${chain?.name}` : t('wallet.NOT_CONNECTED')}
</Button>
{isConnected && chain?.id === defaultChain.id && <NavLink href='/admin'>
{isConnected && chain?.id === defaultChain.id && adminAddresses?.includes(address) && <NavLink href='/admin'>
{t('nav.ADMIN')}
</NavLink>}
<Button size='md' onClick={toggleColorMode} p={4}>
Expand All @@ -102,7 +118,7 @@ const Layout = ({ children }: LayoutProps) => {
</ModalFooter>
</ModalContent>
</Modal>
<Box p={5} minH={'80vh'}>
<Box overflowY={'auto'} position={'fixed'} top={'60px'} left={0} right={0} bottom={0}>
{!isConnected && <Alert status={'error'}>
<AlertIcon />
{t('wallet.CONNECT_TO_CONTINUE')}
Expand Down
10 changes: 6 additions & 4 deletions src/pages/admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const Admin = () => {
{
title: t('tab.MANAGE_STUDENTS'),
icon: FaUsers,
component: <StudentManager/>,
component: <StudentManager />,
},
{
title: t('tab.STATISTICS'),
Expand All @@ -70,16 +70,18 @@ const Admin = () => {
{t('NO_PERMISSION')}
</Alert>)}
{isConnected && chain?.id === defaultChain.id && hasPermissions &&
<Tabs isLazy={true} orientation={'vertical'} variant={'unstyled'} colorScheme={'blue'} minHeight={'90vh'}>
<TabList width={300} minWidth={300} bg={'#cdf2'} borderRight={'solid #cdf8'}>
<Tabs
isLazy={true} orientation={'vertical'} variant={'unstyled'} colorScheme={'blue'} height={'100%'}
>
<TabList width={250} minWidth={250} bg={'#cdf2'} borderRight={'solid #cdf8'}>
{adminComponents.map(({ title, icon }, idx) => (
<Tab fontSize={'md'} key={idx} justifyContent={'flex-start'}
_selected={{ color: 'blue.500', fontWeight: 'bold' }}>
<Icon as={icon} mr={3} boxSize={5} />
{title}
</Tab>))}
</TabList>
<TabPanels>
<TabPanels overflowY={'auto'}>
{adminComponents.map(({ component }, idx) => <TabPanel key={idx}>{component}</TabPanel>)}
</TabPanels>
</Tabs>}
Expand Down
Loading

1 comment on commit 93940a0

@vercel
Copy link

@vercel vercel bot commented on 93940a0 Apr 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

cit-coin-ui – ./

cit-coin-ui-git-dev-pitpa.vercel.app
cit-coin-ui.vercel.app
cit-coin-ui-pitpa.vercel.app

Please sign in to comment.