Skip to content

Commit 2ac28d3

Browse files
devvaannshabose
authored andcommitted
feat: user profile implementation
1 parent 1210d24 commit 2ac28d3

File tree

6 files changed

+279
-2
lines changed

6 files changed

+279
-2
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<div class="profile-popup">
2+
<div class="popup-header">
3+
<h1 class="popup-title">Welcome to Phoenix Code</h1>
4+
</div>
5+
<div class="popup-body">
6+
<button id="phoenix-signin-btn" class="btn btn-primary" style="width: 100%; margin: 5px 0; padding: 10px 0;">
7+
<i class="fa fa-sign-in-alt" style="margin-right: 5px;"></i>
8+
Sign in to your account
9+
</button>
10+
<div style="margin-top: 20px; text-align: center;">
11+
<button id="phoenix-support-btn" class="btn btn-link" style="color: #adb9bd;">
12+
<i class="fa fa-question-circle" style="margin-right: 5px;"></i>
13+
Contact support
14+
</button>
15+
</div>
16+
</div>
17+
</div>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<div class="profile-popup">
2+
<div class="popup-header">
3+
<div style="display: flex; align-items: center;">
4+
<div style="width: 40px; height: 40px; border-radius: 50%; background-color: #0099ff; color: white; display: flex; align-items: center; justify-content: center; margin-right: 15px; font-weight: bold; font-size: 16px;">
5+
CA
6+
</div>
7+
<div>
8+
<div>Charly A.</div>
9+
<div style="color: #3c3; font-weight: normal; font-size: 16px;">Paid Plan</div>
10+
</div>
11+
</div>
12+
</div>
13+
<div class="popup-body">
14+
<div style="margin-bottom: 20px;">
15+
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
16+
<span>AI quota used</span>
17+
<span>7,000 / 10,000 tokens</span>
18+
</div>
19+
<div style="width: 100%; height: 8px; background-color: #444; border-radius: 4px; overflow: hidden;">
20+
<div style="width: 70%; height: 100%; background-color: #3c3; border-radius: 4px;"></div>
21+
</div>
22+
</div>
23+
24+
<button id="phoenix-account-btn" class="btn btn-default" style="width: 100%; margin: 5px 0; padding: 8px 0; text-align: left;">
25+
<i class="fa fa-user" style="margin-right: 8px; width: 20px; text-align: center;"></i>
26+
Account details
27+
</button>
28+
29+
<button id="phoenix-support-btn" class="btn btn-default" style="width: 100%; margin: 5px 0; padding: 8px 0; text-align: left;">
30+
<i class="fa fa-question-circle" style="margin-right: 8px; width: 20px; text-align: center;"></i>
31+
Contact support
32+
</button>
33+
34+
<button id="phoenix-signout-btn" class="btn btn-default" style="width: 100%; margin: 5px 0; padding: 8px 0; text-align: left; color: #f55;">
35+
<i class="fa fa-sign-out-alt" style="margin-right: 8px; width: 20px; text-align: center;"></i>
36+
Sign out
37+
</button>
38+
</div>
39+
</div>

src/extensionsIntegrated/Phoenix/main.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ define(function (require, exports, module) {
3232
Strings = require("strings"),
3333
Dialogs = require("widgets/Dialogs"),
3434
NotificationUI = require("widgets/NotificationUI"),
35-
DefaultDialogs = require("widgets/DefaultDialogs");
35+
DefaultDialogs = require("widgets/DefaultDialogs"),
36+
ProfileMenu = require("./profile-menu");
3637

3738
const PERSIST_STORAGE_DIALOG_DELAY_SECS = 60000;
3839
let $icon;
@@ -48,7 +49,7 @@ define(function (require, exports, module) {
4849
})
4950
.appendTo($("#main-toolbar .bottom-buttons"));
5051
$icon.on('click', ()=>{
51-
console.log("User profile button was clicked");
52+
ProfileMenu.init();
5253
});
5354
}
5455
function _showUnSupportedBrowserDialogue() {
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
define(function (require, exports, module) {
2+
const loginTemplate = require("text!./html/login-dialog.html");
3+
const profileTemplate = require("text!./html/profile-panel.html");
4+
5+
// for the popup DOM element
6+
let $popup = null;
7+
8+
// this is to track whether the popup is visible or not
9+
let isPopupVisible = false;
10+
11+
// if user is logged in we show the profile menu, otherwise we show the login menu
12+
const isLoggedIn = false;
13+
14+
function _handleSignInBtnClick() {
15+
console.log("User clicked sign in button");
16+
}
17+
18+
function _handleSignOutBtnClick() {
19+
console.log("User clicked sign out");
20+
}
21+
22+
function _handleContactSupportBtnClick() {
23+
Phoenix.app.openURLInDefaultBrowser(brackets.config.support_url);
24+
}
25+
26+
function _handleAccountDetailsBtnClick() {
27+
console.log("User clicked account details");
28+
}
29+
30+
/**
31+
* Close the popup if it's open
32+
* this is called at various instances like when the user click on the profile icon even if the popup is open
33+
* or when user clicks somewhere else on the document
34+
*/
35+
function closePopup() {
36+
if ($popup) {
37+
$popup.remove();
38+
$popup = null;
39+
isPopupVisible = false;
40+
41+
// remove global click handler
42+
$(document).off("click.profilePopup");
43+
}
44+
}
45+
46+
/**
47+
* handle clicks outside the popup to close it
48+
*/
49+
function handleDocumentClick(e) {
50+
// If popup exists and click is outside the popup
51+
if ($popup && $popup.length && !$popup[0].contains(e.target)) {
52+
// If the click is not on the user-profile-button (which would toggle the popup)
53+
if (e.target.id !== "user-profile-button" && !$(e.target).closest("#user-profile-button").length) {
54+
closePopup();
55+
}
56+
}
57+
}
58+
59+
/**
60+
* this function is to position the popup near the profile button
61+
*/
62+
function positionPopup() {
63+
const $profileButton = $("#user-profile-button");
64+
65+
if ($profileButton.length && $popup) {
66+
const buttonPos = $profileButton.offset();
67+
const popupWidth = $popup.outerWidth();
68+
const windowWidth = $(window).width();
69+
70+
// pos above the profile button
71+
let top = buttonPos.top - $popup.outerHeight() - 10;
72+
73+
// If popup would go off the right edge of the window, align right edge of popup with right edge of button
74+
let left = Math.min(
75+
buttonPos.left - popupWidth + $profileButton.outerWidth(),
76+
windowWidth - popupWidth - 10
77+
);
78+
79+
// never go off left edge
80+
left = Math.max(10, left);
81+
82+
$popup.css({
83+
top: top + "px",
84+
left: left + "px"
85+
});
86+
}
87+
}
88+
89+
/**
90+
* Shows the sign-in popup when the user is not logged in
91+
*/
92+
function showLoginPopup() {
93+
// If popup is already visible, just close it
94+
if (isPopupVisible) {
95+
closePopup();
96+
return;
97+
}
98+
99+
// create the popup element
100+
closePopup(); // close any existing popup first
101+
$popup = $(loginTemplate);
102+
$("body").append($popup);
103+
isPopupVisible = true;
104+
105+
// Position the popup
106+
positionPopup();
107+
108+
// event handlers for buttons
109+
$popup.find("#phoenix-signin-btn").on("click", function () {
110+
_handleSignInBtnClick();
111+
closePopup();
112+
});
113+
114+
$popup.find("#phoenix-support-btn").on("click", function () {
115+
_handleContactSupportBtnClick();
116+
closePopup();
117+
});
118+
119+
// Set up global click handler to close popup when clicking outside
120+
// Delay attaching to avoid immediate closing
121+
setTimeout(function () {
122+
$(document).on("click.profilePopup", handleDocumentClick);
123+
}, 0);
124+
}
125+
126+
/**
127+
* Shows the user profile popup when the user is logged in
128+
*/
129+
function showProfilePopup() {
130+
// If popup is already visible, just close it
131+
if (isPopupVisible) {
132+
closePopup();
133+
return;
134+
}
135+
136+
closePopup();
137+
$popup = $(profileTemplate);
138+
$("body").append($popup);
139+
isPopupVisible = true;
140+
positionPopup();
141+
142+
$popup.find("#phoenix-account-btn").on("click", function () {
143+
_handleAccountDetailsBtnClick();
144+
closePopup();
145+
});
146+
147+
$popup.find("#phoenix-support-btn").on("click", function () {
148+
_handleContactSupportBtnClick();
149+
closePopup();
150+
});
151+
152+
$popup.find("#phoenix-signout-btn").on("click", function () {
153+
_handleSignOutBtnClick();
154+
closePopup();
155+
});
156+
157+
// Set up global click handler to close popup when clicking outside
158+
// Delay attaching to avoid immediate closing
159+
setTimeout(function () {
160+
$(document).on("click.profilePopup", handleDocumentClick);
161+
}, 0);
162+
}
163+
164+
/**
165+
* Toggle the profile popup based on the user's login status
166+
* this function is called inside the src/extensionsIntegrated/Phoenix/main.js when user clicks on the profile icon
167+
*/
168+
function init() {
169+
// check if the popup is already visible or not. if visible close it
170+
if (isPopupVisible) {
171+
closePopup();
172+
return;
173+
}
174+
175+
if (isLoggedIn) {
176+
showProfilePopup();
177+
} else {
178+
showLoginPopup();
179+
}
180+
181+
// handle window resize to reposition popup
182+
$(window).on("resize.profilePopup", function () {
183+
if (isPopupVisible) {
184+
positionPopup();
185+
}
186+
});
187+
}
188+
189+
exports.init = init;
190+
});

src/styles/brackets.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
@import "Extn-TabBar.less";
4545
@import "Extn-DisplayShortcuts.less";
4646
@import "Extn-CSSColorPreview.less";
47+
@import "user-profile.less";
4748

4849
/* Overall layout */
4950

src/styles/user-profile.less

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.profile-popup {
2+
background-color: #2c2c2c;
3+
color: #ffffff;
4+
border-radius: 6px;
5+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
6+
width: 300px;
7+
overflow: hidden;
8+
position: absolute;
9+
z-index: 9999;
10+
11+
.popup-header {
12+
padding: 15px;
13+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
14+
}
15+
16+
.popup-body {
17+
padding: 15px;
18+
}
19+
20+
.popup-title {
21+
margin: 0;
22+
font-size: 18px;
23+
font-weight: normal;
24+
}
25+
}
26+
27+
.dark .profile-popup {
28+
background-color: #1d1f21;
29+
}

0 commit comments

Comments
 (0)