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: Add user profile with dropdown after sign in through github #535

Merged
51 changes: 51 additions & 0 deletions __tests__/home/home.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,57 @@ describe('Home Page', () => {
expect(repoLinkStyle).toBeTruthy();
});

it('Check user profile with dropdown options', async () => {
const DROPDOWN_OPTIONS = [
{
name: 'Home',
link: 'https://dashboard.realdevsquad.com/',
},
{
name: 'Status',
link: 'https://my.realdevsquad.com/',
},
{
name: 'Profile',
link: 'https://my.realdevsquad.com/profile',
},
{
name: 'Tasks',
link: 'https://my.realdevsquad.com/tasks',
},
{
name: 'Identity',
link: 'https://my.realdevsquad.com/identity',
},
];

const userName = await page.$eval(
'#user-name',
(element) => element.textContent,
);
const userImage = await page.$eval('#user-img', (element) => element.src);
expect(userName).toContain(superUserData.first_name);
expect(userImage).toEqual(superUserData.picture.url);

const userInfoButton = await page.$('.user-info');
await userInfoButton.click();

const hrefs = await page.$$eval(
'.dropdown-list .dropdown-item a',
(elements) => elements.map((element) => element.getAttribute('href')),
);

const expectedHrefs = DROPDOWN_OPTIONS.map((option) => option.link);

expect(hrefs).toEqual(expectedHrefs);

const signoutButton = await page.$('#signout-option');
await signoutButton.click();
const signinButton = await page.$('.sign-in-btn');

expect(signinButton).toBeTruthy();
});

it('should display the Sync Onboarding 31d+ button', async () => {
const syncOnboarding31dPlusUsersButton = await page.$(
'#sync-onboarding-31d-plus-users',
Expand Down
1 change: 0 additions & 1 deletion constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const DISABLED = 'disabled';
const STATUS_BASE_URL_PROD = 'https://status.realdevsquad.com';
const STATUS_BASE_URL_STAGING = 'https://staging-status.realdevsquad.com';
const STATUS_BASE_URL = STATUS_BASE_URL_PROD;

const dummyPicture = 'https://dashboard.realdevsquad.com/images/avatar.png';
const USER_MANAGEMENT_URL =
'https://dashboard.realdevsquad.com/users/details/?username=';
9 changes: 8 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@
<a
href="https://github.com/login/oauth/authorize?client_id=23c78f66ab7964e5ef97"
>Sign In <span>With GitHub</span>
<img src="images/github.png" alt="" />
<img src="images/github.png" class="user-avatar" />
</a>
</div>
<div class="user-info">
<span id="user-name"></span>
<span>
<img id="user-img" src="" alt="" />
</span>
</div>
<div id="dropdown"></div>
</nav>

<section id="sync-buttons" class="element-display-remove">
Expand Down
4 changes: 4 additions & 0 deletions mock-data/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ const superUserData = {
twitter_id: 'Codesh_',
first_name: 'Kotesh',
username: 'kotesh',
picture: {
publicId: 'profile/w2XR9Gkid6Kg5xCJ5Elm/rzh3cwff7hh7srvg63mb',
url: 'https://res.cloudinary.com/realdevsquad/image/upload/v1692990078/profile/w2XR9Gkid6Kg5xCJ5Elm/rzh3cwff7hh7srvg63mb.png',
},
};
module.exports = {
allUsersData,
Expand Down
100 changes: 100 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,106 @@ addClickEventListener(
syncNicknamesStatusUpdate,
'POST',
);

const DROPDOWN_OPTIONS = [
{
name: 'Home',
link: 'https://dashboard.realdevsquad.com/',
},
{
name: 'Status',
link: 'https://my.realdevsquad.com/',
},
{
name: 'Profile',
link: 'https://my.realdevsquad.com/profile',
},
{
name: 'Tasks',
link: 'https://my.realdevsquad.com/tasks',
},
{
name: 'Identity',
link: 'https://my.realdevsquad.com/identity',
},
];

async function handleUserSignin() {
try {
const self_user = await getSelfUser();
if (self_user) {
const signInButton = document.querySelector('.sign-in-btn');
signInButton.style.display = 'none';
const dropdown = document.getElementById('dropdown');
const userInfo = document.querySelector('.user-info');
const username = document.getElementById('user-name');
const userImage = document.getElementById('user-img');

username.innerText = `Hello, ${self_user.first_name}!`;
userImage.setAttribute('src', self_user?.picture.url);
userInfo.classList.add('active');
const dropdownList = createElement({
type: 'ul',
attributes: {
class: 'dropdown-list',
},
});

DROPDOWN_OPTIONS.forEach((option) => {
const listElement = createElement({
type: 'li',
attributes: {
class: 'dropdown-item',
},
});
const anchorElement = createElement({
type: 'a',
attributes: {
class: 'dropdown-link',
},
});
anchorElement.href = `${option.link}`;
anchorElement.innerText = `${option.name}`;
listElement.append(anchorElement);
dropdownList.append(listElement);
});
const horizontalLine = createElement({
type: 'hr',
attributes: {
class: 'line',
},
});

dropdownList.append(horizontalLine);
const signOutElement = createElement({
type: 'li',
attributes: {
class: 'dropdown-item',
id: 'signout-option',
},
});
signOutElement.classList.add('dropdown-link');

dropdownList.append(signOutElement);
signOutElement.innerText = 'Sign Out';
dropdown.append(dropdownList);

userInfo.addEventListener('click', () => {
iamitprakash marked this conversation as resolved.
Show resolved Hide resolved
if (dropdown.classList.contains('active')) {
dropdown.classList.remove('active');
} else {
dropdown.classList.add('active');
}
});

signOutElement.addEventListener('click', () => {
signout('/auth/signout');
});
}
} catch (error) {}
}
handleUserSignin();

addClickEventListener(
syncIdle7dUsersButton,
'/discord-actions/group-idle-7d',
Expand Down
79 changes: 79 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
--blue-color: #1d1283;
--success-color: green;
--failure-color: #f44336;
--lightblue-color: #0d6efd;
--lightgray-color: #d7d6d6;
}

body {
Expand Down Expand Up @@ -367,6 +369,77 @@ footer {
.element-display-remove {
display: none !important;
}
/* Dropdown container */

#dropdown {
display: none;
position: absolute;
width: 9.5rem;
right: 1.5rem;
text-align: center;
top: 3rem;
z-index: 100;
flex-direction: column;
justify-content: center;
padding: 0.63rem 0;
background-color: var(--white-color);
border-radius: 0.63rem;
font-size: 0.75rem;
box-shadow: rgba(60, 64, 67, 0.3) 0 0.06rem 0.13rem 0,
rgba(60, 64, 67, 0.15) 0 0.13rem 0.38rem 0.13rem;
}

#signout-option {
cursor: pointer;
}

#dropdown.active {
display: flex;
}

.dropdown-list {
list-style-type: none;
padding-left: 0;
margin-left: 0;
cursor: pointer;
color: var(--lightblue-color);
font-weight: 700;
}
.dropdown-item {
padding: 0.65rem 0;
}
.dropdown-item:hover {
background-color: var(--lightgray-color);
transition: background-color 0.31s ease-in-out;
}
.dropdown-link {
display: block;
width: 100%;
text-decoration: none;
color: var(--lightblue-color);
}

.user-info {
display: none;
position: absolute;
align-items: center;
gap: 0.5rem;
cursor: pointer;
color: var(--white-color);
order: 3;
font-size: smaller;
font-weight: bold;
}
.user-info.active {
display: flex;
right: 0.5rem;
}

.user-info img {
width: 1.75rem;
height: 1.75rem;
border-radius: 100%;
}

/* MEDIA QUERY */

Expand Down Expand Up @@ -403,6 +476,9 @@ footer {
.nav-links .links a {
color: var(--blue-color);
}
.user-info {
position: inherit;
}
}

@media only screen and (max-width: 600px) {
Expand All @@ -412,4 +488,7 @@ footer {
.action-button {
text-align: center;
}
.logo {
display: none;
}
}
26 changes: 21 additions & 5 deletions utils.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
async function getSelfUser() {
async function getSelfUser(endpoint = '/users/self') {
try {
const res = await fetch(`${API_BASE_URL}/users/self`, {
const res = await fetch(`${API_BASE_URL}${endpoint}`, {
method: 'GET',
credentials: 'include',
headers: {
'Content-type': 'application/json',
},
});
const self_user = await res.json();
if (res.status === 200) {
return self_user;
if (endpoint === '/users/self') {
const self_user = await res.json();
if (res.status === 200) {
return self_user;
}
} else {
location.reload();
}
} catch (err) {}
}
Expand Down Expand Up @@ -65,3 +69,15 @@ function debounce(func, delay) {
async function addDelay(milliSeconds) {
await new Promise((resolve) => setTimeout(resolve, milliSeconds));
}

async function signout() {
try {
await fetch('https://api.realdevsquad.com/auth/signout', {
method: 'GET',
khemchand-twt11 marked this conversation as resolved.
Show resolved Hide resolved
credentials: 'include',
});
location.reload();
} catch (error) {
console.error('Signout failed:', error);
}
}
khemchand-twt11 marked this conversation as resolved.
Show resolved Hide resolved
Loading