Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add auth and APIs #67

Merged
merged 3 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/components/SuccessCard/SuccesssCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React from 'react';
import styled from 'styled-components';
import tw from 'twin.macro';
import { success } from '../../../config/content';
import { CaptionText, Heading4, LinkButton } from '../shared';
import { CaptionText, Heading4 } from '../shared';
import Button from '../shared/Button';

const SectionContainer = styled.div`
${tw`
Expand Down Expand Up @@ -96,7 +97,7 @@ const SuccesssCard = () => (
<SuccessText>{success.success2}</SuccessText>
</div>
<ButtonContainer>
<LinkButton text={success.btnText} link={success.link} />
<Button text={success.btnText} link={success.link} />
<CaptionText>{success.caption}</CaptionText>
</ButtonContainer>
</LowerContainer>
Expand Down
30 changes: 13 additions & 17 deletions src/components/marginals/Navbar/AuthButton.jsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
import React, { useContext } from 'react';
import { AuthContext } from '../../../utils/Auth';
import { LinkButton } from '../../shared';
import Button from '../../shared/Button';

const AuthButton = ({ text, paddingY, paddingX, outline, bold }) => {
const AuthButton = ({ text, outline, paddingX, paddingY }) => {
const authContext = useContext(AuthContext);
const { login, logout, authenticated } = authContext;

return outline ? (
<LinkButton
outline
method={authenticated ? logout : login}
return (
<Button
variant={outline ? 'outline' : 'primary'}
onClick={authenticated ? logout : login}
text={text || (authenticated ? 'logout' : 'Login')}
paddingY={paddingY}
paddingX={paddingX}
bold={bold}
/>
) : (
<LinkButton
method={authenticated ? logout : login}
text={text || (authenticated ? 'logout' : 'Login')}
paddingY={paddingY}
paddingX={paddingX}
bold={bold}
style={
paddingX && paddingY
? {
padding: `${paddingY}rem ${paddingX}rem`,
}
: {}
}
/>
);
};
Expand Down
25 changes: 0 additions & 25 deletions src/components/shared/Button2.jsx

This file was deleted.

53 changes: 0 additions & 53 deletions src/components/shared/LinkButton.jsx

This file was deleted.

2 changes: 0 additions & 2 deletions src/components/shared/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ export { default as NavText } from './Typography/NavText';
export { default as ButtonText } from './Typography/ButtonText';
export { default as CaptionText } from './Typography/CaptionText';
export { default as Container } from './Container';
export { default as LinkButton } from './LinkButton';
export { default as SectionContainer } from './SectionContainer';
export { default as ModalBox } from './ModalBox';
export { default as Button2 } from './Button2';
export { default as About } from './About';
export { default as Layout } from './Layout';
17 changes: 17 additions & 0 deletions src/pages/payment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { Heading1, Layout } from '../components';

const PaymentPage = () => {
// eslint-disable-next-line no-console
console.log('Payment page');

return (
<Layout>
<Heading1>Payment</Heading1>
{/* Payment form here */}
TODO - Payment form
</Layout>
);
};

export default PaymentPage;
2 changes: 1 addition & 1 deletion src/pages/playground.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
import React from 'react';
import React, { useContext } from 'react';

Check failure on line 2 in src/pages/playground.js

View workflow job for this annotation

GitHub Actions / eslint / Eslint Check

'useContext' is defined but never used
import { Helmet } from 'react-helmet';
import FAQSection from '../components/FAQSection/FAQSection';

Expand Down
17 changes: 17 additions & 0 deletions src/pages/register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { Heading1, Layout } from '../components';

const RegistrationPage = () => {
// eslint-disable-next-line no-console
console.log('Registration page');

return (
<Layout>
<Heading1>Registration</Heading1>
{/* Registration form here */}
TODO - Registration form
</Layout>
);
};

export default RegistrationPage;
162 changes: 162 additions & 0 deletions src/utils/Api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import axios from 'axios';
import { toast } from 'react-toastify';
import { navigate } from 'gatsby';

// Configure and an instance of axios
export const avenueApi = axios.create({
baseURL: process.env.GATSBY_AVENUE_API_URL,
timeout: 60000,
timeoutErrorMessage: 'Request Timeout: Please try again',
});

export const zimbraApi = axios.create({
baseURL: 'https://mail.nitrkl.ac.in/home/~/',
timeout: 60000,
timeoutErrorMessage: 'Request Timeout: Please try again',
});

class Api {
constructor() {
if (!Api.instance) {
Api.instance = this;
this.avenueApi = avenueApi;
this.zimbraApi = zimbraApi;
}
}

// Get the singleton instance of the API
static getInstance() {
if (!Api.instance) {
Api.instance = new Api();
}
return Api.instance;
}

async getEvents(event) {
return this.avenueApi.get('/events', {
params: { type: event, orgID: '65133eb72c5708eb84bf53d6' },
});
}

async fetchUserDetails({ uid, accessToken }) {
try {
const { data: avenueUser } = await this.avenueApi.get('/user', {
params: { uid },
headers: { Authorization: `Bearer ${accessToken}` },
});

if (avenueUser) {
if (!avenueUser.festID.includes('innovision-2023') && !avenueUser.rollNumber) {
toast.error('Kindly do the payment');
navigate('/payment');
}
} else {
toast.info('You are not registered for Innovision 2023. Please register to continue.');
navigate('/register');
}

return avenueUser;
} catch (error) {
toast.error('Unable to fetch user details');
return null;
}
}

async registerUser({ uid, accessToken, payload, sideEffects }) {
try {
const { data: newUser } = await this.avenueApi
.post(
'/user',
{ uid, payload },
{
headers: { Authorization: `Bearer ${accessToken}` },
},
)
.catch((error) => {
throw new Error(error.response.data);
});

if (newUser) {
if (sideEffects) sideEffects(newUser);
} else throw new Error('Error saving user');
} catch (error) {
toast.error(error?.message);
if (error?.message === 'User with this roll number already registered')
toast.info('Kindly use the email registered during previous fests to login');
throw new Error('Error saving user');
}
}

async initiatePayment({ buyerName, email, phone, amount, sideEffects, accessToken }) {
try {
const { data: generatedLink } = await this.avenueApi.post(
'/payment/instamojo',
{
amount,
purpose: 'NITRUTSAV-2023 | REGISTRATION',
buyerName,
email,
phone,
redirectUrl: process.env.GATSBY_AVENUE_REDIRECT_URL,
webhook: 'https://avenue-api.nitrkl.in/payment/webhook',
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
},
);

if (!generatedLink) {
throw new Error('Something went wrong: Failed to generate payment link');
}

if (sideEffects) sideEffects(generatedLink);
return generatedLink;
} catch (error) {
throw new Error(error.message || 'Something went Wrong, please try again');
}
}

async verifyZimbra({ rollNumber, password, sideEffects }) {
try {
const { status } = await this.zimbraApi.post('zimbra-login', {
params: {
username: rollNumber,
password,
},
});

if (status === 200) {
if (sideEffects) sideEffects();
} else {
throw new Error('Invalid Credentials');
}
} catch (error) {
throw new Error(error.message || 'Something went Wrong, please try again');
}
}

async bookEvent({ userID, eventID, accessToken, sideEffects }) {
const { data: registeredEvent } = await this.avenueApi.post(
'/user/registration',
{
userID,
eventID,
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
},
);

if (registeredEvent.userID === userID) {
if (sideEffects) sideEffects(registeredEvent);
} else {
throw new Error('Unable to register for event, please try again');
}
}
}

export default Api;
Loading
Loading