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

Fix/815 #927

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
49 changes: 40 additions & 9 deletions src/Me/Navigation/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import { useRouter } from 'next/router';
import classNames from 'classnames';
import styled from 'styled-components/macro';
Expand All @@ -10,34 +10,56 @@ import IconHome from '../../assets/me/home.svg';
import Mentorships from '../../assets/me/icon-survey.svg';
import IconMentors from '../../assets/me/mentors.svg';
import IconLogout from '../../assets/me/icon-door-exit.svg';
import TawkIcon from '../../assets/me/tawk.svg';
import { useUser } from '../../context/userContext/UserContext';
import { useRoutes } from '../../hooks/useRoutes'
import { useRoutes } from '../../hooks/useRoutes';
import { hideWidget, toggleChat, showWidget } from '../../utils/tawk';
import { useDeviceType } from '../../hooks/useDeviceType';

const MenuItem = ({
icon: Icon,
label,
to,
onClick,
}: {
icon: string;
label: string;
to: string;
to?: string;
onClick?: () => void;
}) => {
const router = useRouter();
if (to) {
return (
<Link href={to}>
<NavItemDecoration
className={classNames({ active: router.pathname === to })}
>
<Icon />
<Label>{label}</Label>
</NavItemDecoration>
</Link>
);
}
return (
<Link href={to}>
<NavItemDecoration
className={classNames({ active: router.pathname === to })}
>
<button onClick={onClick}>
<NavItemDecoration>
<Icon />
<Label>{label}</Label>
</NavItemDecoration>
</Link>
</button>
);
};

const Navbar = () => {
const { isAdmin, logout } = useUser();
const urls = useRoutes();
const { isMobile } = useDeviceType();

useEffect(() => {
if (!isMobile) return showWidget();
hideWidget();
}, [isMobile]);

return (
<>
<Menu>
Expand All @@ -46,8 +68,17 @@ const Navbar = () => {
alt="Logo"
/>
<MenuItem to={urls.me.get()} icon={IconHome} label="Home" />
<MenuItem to={urls.me.requests.get()} icon={Mentorships} label="Mentorships" />
<MenuItem
to={urls.me.requests.get()}
icon={Mentorships}
label="Mentorships"
/>
{isMobile && (
<MenuItem onClick={toggleChat} icon={TawkIcon} label="Tawk" />
)}

<MenuItem to={urls.root.get()} icon={IconMentors} label="Mentors" />

{isAdmin && (
<MenuItem to={urls.me.admin.get()} icon={IconMentors} label="Admin" />
)}
Expand Down
81 changes: 39 additions & 42 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import partition from 'lodash/partition';
import * as Sentry from '@sentry/browser';
import { Application, Mentor, User } from '../types/models';
import { setVisitor } from '../utils/tawk';

type RequestMethod = 'POST' | 'GET' | 'PUT' | 'DELETE';
type ErrorResponse = {
success: false;
Expand All @@ -31,11 +30,11 @@ export const paths = {
let currentUser: User | undefined;

export default class ApiService {
mentorsPromise: Promise<Mentor[]> | null = null
auth: any
mentorsPromise: Promise<Mentor[]> | null = null;
auth: any;

constructor(auth: any) {
this.auth = auth
this.auth = auth;
}

makeApiCall = async <T>(
Expand Down Expand Up @@ -96,7 +95,7 @@ export default class ApiService {
message: error,
};
}
}
};

getCurrentUser = async (): Promise<typeof currentUser> => {
if (!currentUser && this.auth.isAuthenticated()) {
Expand All @@ -110,31 +109,31 @@ export default class ApiService {
}
}
return currentUser;
}
};

clearCurrentUser = () => {
currentUser = undefined;
localStorage.removeItem(USER_LOCAL_KEY);
}
};

getMentors = async () => {
if (!this.mentorsPromise) {
this.mentorsPromise = this.makeApiCall<Mentor[]>(`${paths.MENTORS}?limit=1300&available=true`).then(
(response) => {
if (response?.success) {
const [available, unavailable] = partition(
response.data || [],
(mentor) => mentor.available
);
return [...shuffle(available), ...unavailable];
} else {
return [];
}
this.mentorsPromise = this.makeApiCall<Mentor[]>(
`${paths.MENTORS}?limit=1300&available=true`
).then((response) => {
if (response?.success) {
const [available, unavailable] = partition(
response.data || [],
(mentor) => mentor.available
);
return [...shuffle(available), ...unavailable];
} else {
return [];
}
);
});
}
return this.mentorsPromise;
}
};

getUser = async (userId: string) => {
if (this.mentorsPromise != null) {
Expand All @@ -149,7 +148,7 @@ export default class ApiService {
return response.data;
}
return null;
}
};

getFavorites = async () => {
const { _id: userId } = (await this.getCurrentUser())!;
Expand All @@ -161,18 +160,18 @@ export default class ApiService {
return response.data.mentors.map((mentor) => mentor._id);
}
return [];
}
};

addMentorToFavorites = async (mentorId: string) => {
const { _id: userId } = (await this.getCurrentUser())!;
const { _id: userId } = (await this.getCurrentUser())!;

const response = await this.makeApiCall(
`${paths.USERS}/${userId}/favorites/${mentorId}`,
{},
'POST'
);
return !!response?.success;
}
};

createApplicationIfNotExists = async (user: User) => {
if (await this.userHasPendingApplication(user)) {
Expand All @@ -194,7 +193,7 @@ export default class ApiService {
? messages.EDIT_DETAILS_APPLICATION_SUBMITTED
: response?.message,
};
}
};

updateMentor = async (mentor: Mentor) => {
const response = await this.makeApiCall(
Expand All @@ -206,7 +205,7 @@ export default class ApiService {
this.storeUserInLocalStorage(mentor);
}
return !!response?.success;
}
};

updateMentorAvatar = async (mentor: Mentor, value: FormData) => {
const response = await this.makeApiCall(
Expand All @@ -219,7 +218,7 @@ export default class ApiService {
await this.fetchCurrentItem();
}
return currentUser!;
}
};

updateMentorAvailability = async (isAvailable: boolean) => {
let currentUser = (await this.getCurrentUser())!;
Expand All @@ -233,7 +232,7 @@ export default class ApiService {
this.storeUserInLocalStorage({ ...currentUser, available: isAvailable });
}
return !!response?.success;
}
};

deleteMentor = async (mentorId: string) => {
const response = await this.makeApiCall(
Expand All @@ -242,7 +241,7 @@ export default class ApiService {
'DELETE'
);
return !!response?.success;
}
};

getPendingApplications = async () => {
const response = await this.makeApiCall<Application[]>(
Expand All @@ -251,7 +250,7 @@ export default class ApiService {
'GET'
);
return response?.success ? response.data : [];
}
};

approveApplication = async (mentor: Mentor) => {
const response = await this.makeApiCall(
Expand All @@ -262,7 +261,7 @@ export default class ApiService {
'PUT'
);
return !!response?.success;
}
};

declineApplication = async (mentor: Mentor, reason: string) => {
const response = await this.makeApiCall(
Expand All @@ -274,7 +273,7 @@ export default class ApiService {
'PUT'
);
return !!response?.success;
}
};

applyForMentorship = async (
mentor: Mentor,
Expand All @@ -298,11 +297,11 @@ export default class ApiService {
localStorage.setItem(USER_MENTORSHIP_REQUEST, JSON.stringify(payload));
}
return !!response?.success;
}
};

getMyMentorshipApplication = () => {
return JSON.parse(localStorage.getItem(USER_MENTORSHIP_REQUEST) || '{}');
}
};

getMentorshipRequests = async (userId: string) => {
const response = await this.makeApiCall(
Expand All @@ -311,7 +310,7 @@ export default class ApiService {
'GET'
);
return response?.success ? response.data : [];
}
};

updateMentorshipReqStatus = async (
requestId: string,
Expand All @@ -327,7 +326,7 @@ export default class ApiService {
'PUT'
);
return res;
}
};

// Private methods
getErrorMessage = (error: { constraints: Record<string, string> }[]) => {
Expand All @@ -338,13 +337,13 @@ export default class ApiService {
return error;
}
return messages.GENERIC_ERROR;
}
};

storeUserInLocalStorage = (user: User = currentUser!) => {
if (user) {
localStorage.setItem(USER_LOCAL_KEY, JSON.stringify(user));
}
}
};

fetchCurrentItem = async () => {
currentUser = await this.makeApiCall<User>(`${paths.USERS}/current`).then(
Expand All @@ -362,19 +361,17 @@ export default class ApiService {
username: name,
});
});

setVisitor({
name,
email,
roles,
});

return response.data;
}
}
);
this.storeUserInLocalStorage();
}
};

userHasPendingApplication = async (user: User) => {
const response = await this.makeApiCall<Application[]>(
Expand All @@ -385,5 +382,5 @@ export default class ApiService {
}

return false;
}
};
}
1 change: 1 addition & 0 deletions src/assets/me/tawk.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion src/external-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ export declare global {
interface Window {
Tawk_API: TawkAPI;
ga(operation: 'send', event: 'pageview'): void;
ga(operation: 'send', event: 'event', category: string, action: string, label?: string): void;
ga(
operation: 'send',
event: 'event',
category: string,
action: string,
label?: string
): void;
}
}
Loading