Voila!
This commit is contained in:
parent
b4a9ac2806
commit
8e3da8e315
13 changed files with 5361 additions and 0 deletions
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# 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
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
30
README.md
Normal file
30
README.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
2
next-env.d.ts
vendored
Normal file
2
next-env.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
25
package.json
Normal file
25
package.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "bada-frame",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "9.5.3",
|
||||
"react": "16.13.1",
|
||||
"react-bootstrap": "^1.3.0",
|
||||
"react-dom": "16.13.1",
|
||||
"scrypt-js": "^3.0.1",
|
||||
"styled-components": "^5.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.6.4",
|
||||
"@types/react": "^16.9.49",
|
||||
"@types/styled-components": "^5.1.3",
|
||||
"babel-plugin-styled-components": "^1.11.1",
|
||||
"typescript": "^4.0.2"
|
||||
}
|
||||
}
|
BIN
public/icon.png
Normal file
BIN
public/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
16
src/components/Navbar.tsx
Normal file
16
src/components/Navbar.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import styled from 'styled-components';
|
||||
|
||||
const Navbar = styled.div`
|
||||
padding: 8px 12px;
|
||||
font-size: 20px;
|
||||
line-height: 2rem;
|
||||
background-color: #212121;
|
||||
color: #fff;
|
||||
min-height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.7);
|
||||
margin-bottom: 10px;
|
||||
`;
|
||||
|
||||
export default Navbar;
|
49
src/pages/_app.tsx
Normal file
49
src/pages/_app.tsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import React from 'react';
|
||||
import styled, {createGlobalStyle } from 'styled-components';
|
||||
import Navbar from 'components/Navbar';
|
||||
|
||||
const GlobalStyles = createGlobalStyle`
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #303030;
|
||||
}
|
||||
|
||||
#__next {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
vertical-align: middle;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
:root {
|
||||
--primary: #e26f99,
|
||||
};
|
||||
`;
|
||||
|
||||
const Image = styled.img`
|
||||
max-height: 28px;
|
||||
margin-right: 5px;
|
||||
`;
|
||||
|
||||
export default function App({ Component, pageProps }) {
|
||||
return (
|
||||
<>
|
||||
<GlobalStyles />
|
||||
<Navbar>
|
||||
<Image src="/icon.png" />
|
||||
ente
|
||||
</Navbar>
|
||||
<Component />
|
||||
</>
|
||||
);
|
||||
}
|
53
src/pages/_document.tsx
Normal file
53
src/pages/_document.tsx
Normal file
|
@ -0,0 +1,53 @@
|
|||
import Document, {
|
||||
Html, Head, Main, NextScript,
|
||||
} from 'next/document'
|
||||
import { ServerStyleSheet } from 'styled-components'
|
||||
|
||||
export default class MyDocument extends Document {
|
||||
static async getInitialProps(ctx) {
|
||||
const sheet = new ServerStyleSheet()
|
||||
const originalRenderPage = ctx.renderPage
|
||||
|
||||
try {
|
||||
ctx.renderPage = () =>
|
||||
originalRenderPage({
|
||||
enhanceApp: (App) => (props) =>
|
||||
sheet.collectStyles(<App {...props} />),
|
||||
})
|
||||
|
||||
const initialProps = await Document.getInitialProps(ctx)
|
||||
return {
|
||||
...initialProps,
|
||||
styles: (
|
||||
<>
|
||||
{initialProps.styles}
|
||||
{sheet.getStyleElement()}
|
||||
</>
|
||||
),
|
||||
}
|
||||
} finally {
|
||||
sheet.seal()
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
|
||||
<link rel="icon" href="/icon.png" type="image/png"/>
|
||||
<script src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js" crossorigin></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
|
||||
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
}
|
6
src/pages/api/hello.ts
Normal file
6
src/pages/api/hello.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||
|
||||
export default (req, res) => {
|
||||
res.statusCode = 200
|
||||
res.json({ name: 'John Doe' })
|
||||
}
|
38
src/pages/index.tsx
Normal file
38
src/pages/index.tsx
Normal file
|
@ -0,0 +1,38 @@
|
|||
import React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
import Card from 'react-bootstrap/Card';
|
||||
import Form from 'react-bootstrap/Form';
|
||||
import Button from 'react-bootstrap/Button';
|
||||
|
||||
const Container = styled.div`
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<Container>
|
||||
<Card style={{ minWidth: '300px' }}>
|
||||
<Card.Body>
|
||||
<Card.Title>
|
||||
Login
|
||||
</Card.Title>
|
||||
<Form>
|
||||
<Form.Group controlId="formBasicEmail">
|
||||
<Form.Label>Email address</Form.Label>
|
||||
<Form.Control type="email" placeholder="Enter email" />
|
||||
<Form.Text className="text-muted">
|
||||
We'll never share your email with anyone else.
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
<Button variant="primary" type="submit" block>
|
||||
Submit
|
||||
</Button>
|
||||
</Form>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</Container>
|
||||
)
|
||||
}
|
87
src/utils/strings/vernacularStrings.ts
Normal file
87
src/utils/strings/vernacularStrings.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
/** Enums of supported locale */
|
||||
export enum locale {
|
||||
en='en',
|
||||
hi='hi',
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a template with placeholders which can then be
|
||||
* substituted at run time. Enabling the developer to create
|
||||
* different template for different locale and populate them
|
||||
* at run time.
|
||||
*
|
||||
* @param strings
|
||||
* @param keys
|
||||
*/
|
||||
export function template(strings: TemplateStringsArray, ...keys: string[]) {
|
||||
return ((...values: any[]) => {
|
||||
const dict = values[values.length - 1] || {};
|
||||
const result = [strings[0]];
|
||||
keys.forEach((key, i) => {
|
||||
const value = Number.isInteger(key) ? values[key] : dict[key];
|
||||
result.push(value, strings[i + 1]);
|
||||
});
|
||||
return result.join('');
|
||||
});
|
||||
}
|
||||
|
||||
/** Type for vernacular string constants */
|
||||
export type VernacularConstants<T> = {
|
||||
[locale.en]: T,
|
||||
[locale.hi]?: {
|
||||
[x in keyof T]?: string | ReturnType<typeof template>;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a valid locale from string and defaults
|
||||
* to English.
|
||||
*
|
||||
* @param lang
|
||||
*/
|
||||
export const getLocale = (lang: string) => {
|
||||
switch (lang) {
|
||||
case locale.hi:
|
||||
return locale.hi;
|
||||
default:
|
||||
return locale.en;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Global English constants.
|
||||
*/
|
||||
const englishConstants = {
|
||||
ENTE: 'Ente',
|
||||
};
|
||||
|
||||
/**
|
||||
* Global constants
|
||||
*/
|
||||
const globalConstants: VernacularConstants<typeof englishConstants> = {
|
||||
en: englishConstants,
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to extend global constants with local constants
|
||||
* @param localConstants
|
||||
*/
|
||||
export function getConstantValue<T>(localConstants: VernacularConstants<T>) {
|
||||
const searchParam = typeof window !== 'undefined' ? window.location.search : '';
|
||||
const query = new URLSearchParams(searchParam);
|
||||
const currLocale = getLocale(query.get('lang'));
|
||||
|
||||
if (currLocale !== 'en') {
|
||||
return {
|
||||
...globalConstants.en,
|
||||
...localConstants.en,
|
||||
...globalConstants[currLocale],
|
||||
...localConstants[currLocale],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...globalConstants[currLocale],
|
||||
...localConstants[currLocale],
|
||||
};
|
||||
}
|
30
tsconfig.json
Normal file
30
tsconfig.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"baseUrl": "./src"
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx", "src/pages/index.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
Loading…
Add table
Reference in a new issue