micro-users 1.6.2__py3-none-any.whl → 1.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of micro-users might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: micro-users
3
- Version: 1.6.2
3
+ Version: 1.7.0
4
4
  Summary: Arabic Django user management app with abstract user, permissions, and activity logging
5
5
  Home-page: https://github.com/debeski/micro-users
6
6
  Author: DeBeski
@@ -208,3 +208,5 @@ MICRO_USERS_THEME = {
208
208
  | v1.6.0 | • **Automated Activity Logging**: dynamic logging for all CREATE/UPDATE/DELETE actions via Middleware & Signals<br> • **Refactor**: Renamed `Department` model to `Scope` (Scope Management)<br> • Removed manual logging requirement<br> • **Architecture**: Decoupled models, forms, and tables using dynamic imports and `apps.get_model` <br> • **Soft Delete**: Users are now marked as inactive with a timestamp instead of being permanently deleted<br> • **Activity Log**: Deleted users appear with a strikethrough<br> • **CSS Refactor**: Extracted and cleaned up styling with CSS variables<br> • **Login**: Refactored login page with separated JS/CSS and a new modern default logo |
209
209
  | v1.6.1 | • **Theme Configuration**: Added `MICRO_USERS_THEME` setting for easy color customization <br> • **Bug Fixes**: Explicitly excluded unwanted columns (id, ip_address, user_agent) from Activity Log table <br> • **UI**: Improved Scope Manager button visibility |
210
210
  | v1.6.2 | • **UI**: Improved some tooltips for buttons and descriptions |
211
+ | v1.6.3 | • **Bug Fixes**: Fixed a crash with a table tooltip |
212
+ | v1.7.0 | • **New Theme**: Complete visual overhaul with modern, consistent styling <br> • **Refactor**: Updated Login, Profile, and Detail templates for better UX <br> • **Feature**: Added Scope filter to Activity Logs (superuser only) <br> • **UX**: Clear button in filters now preserves current sort order |
@@ -1,12 +1,12 @@
1
1
  users/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  users/admin.py,sha256=CRS5muWUSXUC2pQteSCgUgpFjPtGnx1b5z1daODjUMM,1359
3
3
  users/apps.py,sha256=rX3NqBsz2zC_spZbHJ_tbhNwkEFaspPjpS19qil9WBo,1162
4
- users/filters.py,sha256=TwB47ffslp_H2ZEm8JBOKNktGgix23XDiQdy-HWG7yE,4798
4
+ users/filters.py,sha256=_uvi1qLEE7aLqKLwjIpv6dflKlyFd0t0Muv6IXBfIxw,6094
5
5
  users/forms.py,sha256=4poq6wlFysX_r0KFxUd9I2K9eXhOHV36iSTjncRYHyc,16531
6
6
  users/middleware.py,sha256=CgzmKb6_4TUkwMZ0h7UgQd80DKUXsmzKvsc3V2JIujY,976
7
7
  users/models.py,sha256=XyA4UaRp4DufvgBJKtAGyal3Ci3fZxevyd1fIPqrpEw,2679
8
8
  users/signals.py,sha256=blAx8nHsfmn89hMyRBR0Jf706Z07N81ObQMY_MHaBv8,4543
9
- users/tables.py,sha256=wCno7TZM6nqBHwCzkHduPSAvMRd4t349lHRMwXD4AlQ,2997
9
+ users/tables.py,sha256=6zsQBhlEA74BYsSzzmYeFE0Ll7vZmT8aKMsqRUw_l-k,2968
10
10
  users/urls.py,sha256=hg4fiVkWcQlbZ82SZ_HjeFPQUkmK1Y7c1ho_lWBFDRg,1491
11
11
  users/views.py,sha256=HGa0x8tVY4ltSelOxHdknjsft9fMKfQTKoXvMaMPlbg,14246
12
12
  users/migrations/0001_initial.py,sha256=lx9sSKS-lxHhI6gelVH52NOkwqEMJ32TvOJUn9zaOXM,4709
@@ -15,24 +15,26 @@ users/migrations/0003_scope_alter_customuser_options_and_more.py,sha256=sp3c_NFC
15
15
  users/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  users/static/img/default_profile.webp,sha256=BKUoQHo4z_fZnmc6z6I-KFvLEHahDr98U9LnDQKHLAM,3018
17
17
  users/static/img/login_logo.webp,sha256=LdLMqrBlBczctcJVfLk-oxasjqcOgYnvHZ17ZMusVNE,27570
18
- users/static/users/css/login.css,sha256=4HaGq7P6oPxP9Jayr4fC9TtYwUEuhhtQOum7mjrOxB4,2549
19
- users/static/users/css/style.css,sha256=RITpRciSynpYwjC7jpPumPA5BAB993RFyuKN9oDp_Y8,4817
18
+ users/static/users/css/detail.css,sha256=YB1XMBmEQluk0WcM3AZ3XKNK4z6f2tFXurz-2igQH7c,1102
19
+ users/static/users/css/login.css,sha256=9TdAt3Cfro4GCWrYK8W9-c-6zr3DbuwsbiFwZ4uBtZM,4171
20
+ users/static/users/css/profile.css,sha256=AZVDK0gFwGo0vgPrmZ0BJVAxax8Icf2h8WFVNbt1UeU,2908
21
+ users/static/users/css/style.css,sha256=rlLk1P4uxw9TKwsFTmXR77gYy0bVptwjzO_m3VGlYDo,1789
20
22
  users/static/users/js/anime.min.js,sha256=pD9KZEZQimTLQOMTT99lBhGT7AXyMPz3g92G1iyd470,17179
21
23
  users/static/users/js/login.js,sha256=ayXC8B5caDNNKL2UDwnDC2BA3lcNHkJu4PPXLDsviDw,1379
22
- users/templates/registration/login.html,sha256=2kkQR0TLsZM9gSzMY7J5y3dR7r2al6o_qgc_pGAEENs,3759
24
+ users/templates/registration/login.html,sha256=D5BXzY5E3_Bh4iP5qZsekleRIqt559KpPRpNtWZX9ME,2862
23
25
  users/templates/users/manage_users.html,sha256=tIPkdFxm9lC_R184WQlm0UHV7sUS_xNo6f8AjgW18S8,6359
24
- users/templates/users/user_activity_log.html,sha256=Ns79XPbNegk_lyLRDZ2yZ0PZD32DFOM_6Qvt2qHlSEY,565
25
- users/templates/users/user_detail.html,sha256=yPiuOGF96rV8t2H1Fl2hhIq78N1588ZFbh5gbAezaxw,2053
26
+ users/templates/users/user_activity_log.html,sha256=nKVOvmkbVjGWZZyYNJahs7drWQFh_hvyUDWuauwJV6U,571
27
+ users/templates/users/user_detail.html,sha256=a_LqslwZOb15yFf1OItxrIWRbeoxK6Tp58ajjlodYc8,5290
26
28
  users/templates/users/user_form.html,sha256=jcyI7OQZOY4ue4DajPtfjAt2SmAYO5ZgHNOqTp2-FO0,1352
27
29
  users/templates/users/partials/scope_actions.html,sha256=pAcxNMmUHgeZ6baR9pHhy8HUU35emFEb8PDBPnqBSNo,273
28
30
  users/templates/users/partials/scope_form.html,sha256=XSUeEoRM-wzDZNFv7AJQBH5TFgaPF1FmwfrKRZ8fpdI,741
29
31
  users/templates/users/partials/scope_manager.html,sha256=mqhSg2NA2U_Dc5bIf3OUasTdPqdEfxvxGh5tOjBJ59Y,393
30
32
  users/templates/users/partials/user_actions.html,sha256=J44-sn0fMbLUWjdtlcf5YhgT5OYRykr1mFkeVXoI1ew,1543
31
- users/templates/users/profile/profile.html,sha256=Ir8zvYUgDm89BlwVuuCsPJIVvTPa_2wH3HAaitPc4s8,2911
32
- users/templates/users/profile/profile_edit.html,sha256=L9DUHlQHG-PmxwxBbSjgPk1dEmy0spPi6wXzT4hQe-U,4218
33
+ users/templates/users/profile/profile.html,sha256=HXxOWsGEAZb731iF-nY00dzbFcgVh60oF0C1X8AySb4,5377
34
+ users/templates/users/profile/profile_edit.html,sha256=hhltTIdl62NNX290nFNZcQwbW1idXEU_DYlrAp07MWk,5242
33
35
  users/templates/users/widgets/grouped_permissions.html,sha256=VE7Trm1xBdpMmCMLc--YAbjGxDQj6TxDVwpphe8WuQE,9950
34
- micro_users-1.6.2.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
35
- micro_users-1.6.2.dist-info/METADATA,sha256=L8Kxga1f4BEUCvCb_l74JjoYe4v3fzbZN4LFD0xIKP8,9539
36
- micro_users-1.6.2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
37
- micro_users-1.6.2.dist-info/top_level.txt,sha256=tWT24ZcWau2wrlbpU_h3mP2jRukyLaVYiyHBuOezpLQ,6
38
- micro_users-1.6.2.dist-info/RECORD,,
36
+ micro_users-1.7.0.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
37
+ micro_users-1.7.0.dist-info/METADATA,sha256=YHzBlmAidK9fcF5jWjfxVuuKsOvxA5CZM2312U8IAfI,9930
38
+ micro_users-1.7.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
39
+ micro_users-1.7.0.dist-info/top_level.txt,sha256=tWT24ZcWau2wrlbpU_h3mP2jRukyLaVYiyHBuOezpLQ,6
40
+ micro_users-1.7.0.dist-info/RECORD,,
users/filters.py CHANGED
@@ -3,7 +3,7 @@
3
3
  import django_filters
4
4
  from django.contrib.auth import get_user_model
5
5
  from crispy_forms.helper import FormHelper
6
- from crispy_forms.layout import Layout, Row, Column, Field, HTML
6
+ from crispy_forms.layout import Layout, Row, Column, Field, HTML, Hidden
7
7
  from django.db.models import Q
8
8
  from django.apps import apps # Import apps
9
9
 
@@ -23,11 +23,19 @@ class UserFilter(django_filters.FilterSet):
23
23
  self.form.helper.form_method = 'GET'
24
24
  self.form.helper.form_class = 'form-inline'
25
25
  self.form.helper.form_show_labels = False
26
- self.form.helper.layout = Layout(
26
+ self.form.helper.layout = Layout()
27
+ if 'sort' in self.data:
28
+ self.form.helper.layout.append(Hidden('sort', self.data['sort']))
29
+ # Prepare clear button URL with sort parameter if exists
30
+ clear_url = '{% url "manage_users" %}'
31
+ if 'sort' in self.data:
32
+ clear_url += f"?sort={self.data['sort']}"
33
+
34
+ self.form.helper.layout.append(
27
35
  Row(
28
36
  Column(Field('keyword', placeholder="البحث"), css_class='form-group col-auto flex-fill'),
29
37
  Column(HTML('<button type="submit" class="btn btn-secondary w-100"><i class="bi bi-search bi-font text-light me-2"></i>بحـــث</button>'), css_class='col-auto text-center'),
30
- Column(HTML('{% if request.GET and request.GET.keys|length > 1 %} <a href="{% url "manage_users" %}" class="btn btn-warning bi-font">clear</a> {% endif %}'), css_class='form-group col-auto text-center'),
38
+ Column(HTML(f'{{% if request.GET and request.GET.keys|length > 1 %}} <a href="{clear_url}" class="btn btn-warning bi-font">clear</a> {{% endif %}}'), css_class='form-group col-auto text-center'),
31
39
  css_class='form-row'
32
40
  ),
33
41
  )
@@ -56,6 +64,13 @@ class UserActivityLogFilter(django_filters.FilterSet):
56
64
  choices=[],
57
65
  empty_label="السنة",
58
66
  )
67
+ scope = django_filters.ModelChoiceFilter(
68
+ queryset=apps.get_model('users', 'Scope').objects.all(),
69
+ field_name='user__scope',
70
+ label="النطاق",
71
+ empty_label="الكل",
72
+ required=False
73
+ )
59
74
  class Meta:
60
75
  model = apps.get_model('users', 'UserActivityLog')
61
76
  fields = {
@@ -70,27 +85,48 @@ class UserActivityLogFilter(django_filters.FilterSet):
70
85
  self.filters['year'].field.widget.attrs.update({
71
86
  'onchange': 'this.form.submit();'
72
87
  })
88
+ self.filters['scope'].field.widget.attrs.update({
89
+ 'onchange': 'this.form.submit();'
90
+ })
91
+
92
+ if self.request and self.request.user.scope:
93
+ del self.filters['scope']
94
+
73
95
  self.form.helper = FormHelper()
74
96
  self.form.helper.form_method = 'GET'
75
97
  self.form.helper.form_class = 'form-inline'
76
98
  self.form.helper.form_show_labels = False
77
99
 
78
- self.form.helper.layout = Layout(
79
- Row(
80
- Column(Field('keyword', placeholder="البحث"), css_class='form-group col-auto flex-fill'),
81
- Column(Field('year', placeholder="السنة", dir="rtl"), css_class='form-group col-auto'),
82
- Column(
83
- Row(
84
- Column(Field('timestamp__gte', css_class='flatpickr', placeholder="من "), css_class='col-6'),
85
- Column(Field('timestamp__lte', css_class='flatpickr', placeholder="إلى "), css_class='col-6'),
86
- ),
87
- css_class='col-auto flex-fill'
88
- ),
89
- Column(HTML('<button type="submit" class="btn btn-secondary w-100"><i class="bi bi-search bi-font text-light me-2"></i>بحـــث</button>'), css_class='col-auto text-center'),
90
- Column(HTML('{% if request.GET and request.GET.keys|length > 1 %} <a href="{% url "user_activity_log" %}" class="btn btn-warning bi-font">clear</a> {% endif %}'), css_class='form-group col-auto text-center'),
91
- css_class='form-row'
100
+ self.form.helper.layout = Layout()
101
+ if 'sort' in self.data:
102
+ self.form.helper.layout.append(Hidden('sort', self.data['sort']))
103
+
104
+ row_fields = [
105
+ Column(Field('keyword', placeholder="البحث"), css_class='form-group col-auto flex-fill'),
106
+ ]
107
+
108
+ if not (self.request and self.request.user.scope):
109
+ row_fields.append(Column(Field('scope', placeholder="النطاق", dir="rtl"), css_class='form-group col-auto'))
110
+
111
+ # Prepare clear button URL with sort parameter if exists
112
+ clear_url = '{% url "user_activity_log" %}'
113
+ if 'sort' in self.data:
114
+ clear_url += f"?sort={self.data['sort']}"
115
+
116
+ row_fields.extend([
117
+ Column(Field('year', placeholder="السنة", dir="rtl"), css_class='form-group col-auto'),
118
+ Column(
119
+ Row(
120
+ Column(Field('timestamp__gte', css_class='flatpickr', placeholder="من "), css_class='col-6'),
121
+ Column(Field('timestamp__lte', css_class='flatpickr', placeholder="إلى "), css_class='col-6'),
122
+ ),
123
+ css_class='col-auto flex-fill'
92
124
  ),
93
- )
125
+ Column(HTML('<button type="submit" class="btn btn-secondary w-100"><i class="bi bi-search bi-font text-light me-2"></i>بحـــث</button>'), css_class='col-auto text-center'),
126
+ Column(HTML(f'{{% if request.GET and request.GET.keys|length > 1 %}} <a href="{clear_url}" class="btn btn-warning bi-font">clear</a> {{% endif %}}'), css_class='form-group col-auto text-center'),
127
+ ])
128
+
129
+ self.form.helper.layout.append(Row(*row_fields, css_class='form-row'))
94
130
  def filter_keyword(self, queryset, name, value):
95
131
  """
96
132
  Filter the queryset by matching the keyword in username, email, phone, and occupation.
@@ -102,7 +138,6 @@ class UserActivityLogFilter(django_filters.FilterSet):
102
138
  Q(action__icontains=value) |
103
139
  Q(model_name__icontains=value) |
104
140
  Q(number__icontains=value) |
105
- Q(scope__name__icontains=value) |
106
141
  Q(ip_address__icontains=value)
107
142
  )
108
143
 
@@ -0,0 +1,47 @@
1
+ .glass-detail {
2
+ background: rgba(255, 255, 255, 0.9); /* Increased opacity */
3
+ backdrop-filter: none !important; /* Explicitly disabled */
4
+ -webkit-backdrop-filter: none !important;
5
+ border: 1px solid rgba(255, 255, 255, 0.4);
6
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.1);
7
+ border-radius: 16px;
8
+ padding: 2rem;
9
+ margin-top: 1rem;
10
+ }
11
+ .info-group {
12
+ margin-bottom: 1.5rem;
13
+ }
14
+ .info-label-sm {
15
+ font-size: 0.85rem;
16
+ color: #6c757d;
17
+ font-weight: 600;
18
+ margin-bottom: 0.25rem;
19
+ }
20
+ .info-value-lg {
21
+ font-size: 1.1rem;
22
+ font-weight: 700;
23
+ color: var(--title);
24
+ }
25
+ .status-badge {
26
+ display: inline-flex;
27
+ align-items: center;
28
+ gap: 6px;
29
+ padding: 6px 12px;
30
+ border-radius: 20px;
31
+ font-size: 0.9rem;
32
+ font-weight: 600;
33
+ }
34
+ .status-active {
35
+ background-color: rgba(25, 135, 84, 0.15);
36
+ color: #198754;
37
+ }
38
+ .status-inactive {
39
+ background-color: rgba(220, 53, 69, 0.15);
40
+ color: #dc3545;
41
+ }
42
+ .section-header {
43
+ color: var(--primal_dark);
44
+ border-bottom: 2px solid rgba(0,0,0,0.05);
45
+ padding-bottom: 10px;
46
+ font-weight: 800;
47
+ }
@@ -1,141 +1,184 @@
1
1
  :root {
2
2
  --selection-bg: #dbdbdb;
3
3
  --selection-moz-bg: #dbdbdb;
4
- --left-bg: white;
5
- --left-shadow: rgba(0,0,0,0.03);
6
- --right-bg: #474745;
7
- --right-shadow: rgba(0,0,0,0.07);
4
+ --bg-gradient: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
5
+ --left-bg: rgba(255, 255, 255, 0.85); /* Glassmorphism */
6
+ --left-shadow: rgba(0,0,0,0.05); /* Softer shadow */
7
+ --right-bg: #2b3035; /* Darker accent */
8
+ --right-shadow: rgba(0,0,0,0.1);
8
9
  --right-text: #F1F1F2;
9
- --label-color: #c2c2c5;
10
- --input-text: #000000;
10
+ --label-color: #5a6474;
11
+ --input-text: #2c3e50;
11
12
  --submit-color: #707075;
12
13
  --submit-focus: #575757;
13
14
  --submit-active: #4d4d4d;
14
- --gradient-start: #474745;
15
- --gradient-end: #a2a2a7;
15
+ --primary-color: #2363c3;
16
16
  }
17
17
 
18
18
  ::selection { background: var(--selection-bg); }
19
19
  ::-webkit-selection { background: var(--selection-bg); }
20
20
  ::-moz-selection { background: var(--selection-moz-bg); }
21
21
 
22
+ /* REMOVED body styles that break titlebar layout (display: flex, center, etc) */
23
+ /* Instead, we style the page container to center content inside the main content area */
22
24
  .page {
23
25
  display: flex;
24
26
  flex-direction: column;
25
- height: calc(100% - 15vh);
26
- position: absolute;
27
- place-content: center;
28
- width: calc(100% - 40px);
27
+ height: 100%;
28
+ width: 100%;
29
+ align-items: center;
30
+ justify-content: center;
31
+ min-height: calc(100vh - 100px); /* Ensure vertical centering within available space */
29
32
  }
30
33
 
31
- @media (max-width: 767px) {
32
- .page {
33
- height: auto;
34
- margin-bottom: 20px;
35
- padding-bottom: 20px;
36
- }
34
+ /* Gradient background applied to body via style.css or separate logic,
35
+ but since this login.css is likely scoped or loaded on login page,
36
+ we can set background on .page or keep it on body if safe.
37
+ To be safe and avoid breaking layout, we set background on body
38
+ but NOT layout properties. */
39
+ body {
40
+ background: var(--bg-gradient);
41
+ /* No display:flex here to avoid squishing the titlebar */
37
42
  }
38
43
 
39
44
  .container {
40
- height: 320px;
45
+ height: 480px; /* Increased height */
41
46
  margin: 0 auto;
42
- width: 640px;
47
+ width: 800px; /* Increased width */
48
+ display: flex;
49
+ background: transparent;
50
+ align-items: center;
51
+ justify-content: center;
52
+ position: relative;
43
53
  }
44
54
 
45
55
  @media (max-width: 767px) {
46
56
  .container {
47
57
  flex-direction: column;
48
- height: 630px;
49
- width: 320px;
58
+ height: auto;
59
+ width: 90%;
50
60
  }
51
61
  }
52
62
 
53
63
  .left {
54
64
  background: var(--left-bg);
55
- height: calc(100% - 40px);
56
- top: 20px;
57
- position: relative;
58
- width: 60%;
59
- box-shadow: 0px 0px 10px 4px var(--left-shadow);
65
+ height: 380px;
66
+ position: absolute;
67
+ left: 50px; /* Overlap effect */
68
+ width: 400px;
69
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.07);
70
+ backdrop-filter: blur(8px);
71
+ -webkit-backdrop-filter: blur(8px);
72
+ border-radius: 20px;
73
+ border: 1px solid rgba(255, 255, 255, 0.18);
74
+ z-index: 2;
75
+ display: flex;
76
+ flex-direction: column;
77
+ justify-content: center;
60
78
  }
61
79
 
62
80
  @media (max-width: 767px) {
63
81
  .left {
64
- height: 100%;
65
- left: 5%;
66
- width: 110%;
67
- max-height: 270px;
82
+ position: relative;
83
+ width: 100%;
84
+ left: 0;
85
+ margin-bottom: 20px;
86
+ height: auto;
87
+ padding: 40px 0;
68
88
  }
69
89
  }
70
90
 
71
91
  .right {
72
92
  background: var(--right-bg);
73
- box-shadow: 0px 0px 20px 8px var(--right-shadow);
93
+ box-shadow: 0 8px 32px 0 var(--right-shadow);
74
94
  color: var(--right-text);
75
- position: relative;
76
- width: 58%;
95
+ position: absolute;
96
+ right: 50px;
97
+ width: 350px;
98
+ height: 480px;
99
+ border-radius: 20px;
100
+ z-index: 1;
101
+ display: flex;
102
+ align-items: center;
103
+ justify-content: center;
77
104
  }
78
105
 
79
106
  @media (max-width: 767px) {
80
107
  .right {
81
- flex-shrink: 0;
82
- height: 100%;
108
+ position: relative;
83
109
  width: 100%;
84
- max-height: 350px;
110
+ right: 0;
111
+ height: 250px;
85
112
  }
86
113
  }
87
114
 
88
- svg {
89
- position: absolute;
90
- width: 320px;
91
- }
92
-
93
- path {
94
- fill: none;
95
- stroke: url(#linearGradient);
96
- stroke-width: 3;
97
- stroke-dasharray: 240 1386;
98
- }
99
-
100
115
  .form {
101
- margin: 35px 35px 35px 20px;
102
- position: absolute;
116
+ margin: 40px;
117
+ text-align: right; /* RTL */
118
+ width: calc(100% - 80px);
103
119
  }
104
120
 
105
121
  label {
106
122
  color: var(--label-color);
107
123
  display: block;
108
124
  font-size: 14px;
109
- height: 16px;
125
+ font-weight: 600;
110
126
  margin-top: 20px;
111
- margin-bottom: 5px;
127
+ margin-bottom: 8px;
112
128
  }
113
129
 
114
130
  input {
115
- background: transparent;
116
- border: 0;
131
+ background: rgba(255, 255, 255, 0.5);
132
+ border: 1px solid #e1e8ed;
133
+ border-radius: 8px;
117
134
  color: var(--input-text);
118
- font-size: 20px;
119
- height: 30px;
120
- line-height: 30px;
135
+ font-size: 16px;
136
+ height: 45px;
137
+ line-height: 45px;
121
138
  outline: none !important;
122
139
  width: 100%;
123
- margin-top: 30px;
124
- margin-bottom: 10px;
140
+ padding: 0 15px; /* Add padding */
141
+ margin-top: 5px; /* Reduced top margin since we use padding */
142
+ margin-bottom: 15px;
143
+ transition: all 0.3s ease;
144
+ }
145
+
146
+ input:focus {
147
+ border-color: var(--primary-color);
148
+ background: white;
149
+ box-shadow: 0 0 0 3px rgba(35, 99, 195, 0.1);
125
150
  }
126
151
 
127
152
  input::-moz-focus-inner { border: 0; }
128
153
 
129
154
  #submit {
130
- color: var(--submit-color);
131
- margin-top: 40px;
132
- transition: color 300ms;
155
+ color: white;
156
+ margin-top: 30px;
157
+ transition: all 0.3s;
158
+ background-color: var(--primary-color);
159
+ border: none;
160
+ cursor: pointer;
161
+ font-weight: 700;
162
+ letter-spacing: 0.5px;
163
+ box-shadow: 0 4px 15px rgba(35, 99, 195, 0.3);
133
164
  }
134
165
 
135
- #submit:focus { color: var(--submit-focus); }
136
- #submit:active { color: var(--submit-active); }
166
+ #submit:hover {
167
+ background-color: #1e4f99;
168
+ transform: translateY(-2px);
169
+ }
170
+
171
+ #submit:active { transform: translateY(0); }
137
172
 
138
173
  /* New Utility Classes for specific elements */
139
- .login-input { font-size: 28px !important; }
140
- .login-submit { font-size: 25px !important; }
141
- .logo-img { width: 100%; }
174
+ .login-input {
175
+ font-size: 18px !important;
176
+ }
177
+ .login-submit {
178
+ font-size: 18px !important;
179
+ }
180
+ .logo-img {
181
+ width: 80%;
182
+ max-width: 200px;
183
+ opacity: 0.9;
184
+ }
@@ -0,0 +1,123 @@
1
+ /* Profile View Styles */
2
+ .glass-profile {
3
+ background: rgba(255, 255, 255, 0.65);
4
+ backdrop-filter: blur(12px);
5
+ -webkit-backdrop-filter: blur(12px);
6
+ border: 1px solid rgba(255, 255, 255, 0.4);
7
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.1);
8
+ border-radius: 16px;
9
+ padding: 2rem;
10
+ }
11
+ .profile-img-container {
12
+ position: relative;
13
+ overflow: hidden;
14
+ border-radius: 50%;
15
+ width: 200px;
16
+ height: 200px;
17
+ margin: 0 auto;
18
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
19
+ border: 4px solid rgba(255, 255, 255, 0.8);
20
+ }
21
+ .profile-img-container img {
22
+ width: 100%;
23
+ height: 100%;
24
+ object-fit: cover;
25
+ }
26
+ .info-label {
27
+ font-size: 0.9rem;
28
+ color: #6c757d;
29
+ margin-bottom: 0.2rem;
30
+ }
31
+ .info-value {
32
+ font-size: 1.25rem;
33
+ font-weight: 600;
34
+ color: var(--title);
35
+ margin-bottom: 1.5rem;
36
+ }
37
+
38
+ /* Scoped Action Button for View Profile */
39
+ .glass-profile .action-btn {
40
+ transition: all 0.3s ease;
41
+ border-radius: 12px;
42
+ padding: 10px 20px;
43
+ font-weight: 500;
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ gap: 8px;
48
+ }
49
+ .glass-profile .action-btn:hover {
50
+ transform: translateY(-2px);
51
+ box-shadow: 0 5px 15px rgba(0,0,0,0.1);
52
+ }
53
+
54
+ .glass-profile .page-title {
55
+ color: var(--primal_dark);
56
+ font-weight: 800;
57
+ margin-bottom: 2rem;
58
+ text-shadow: 0 2px 4px rgba(0,0,0,0.05);
59
+ }
60
+
61
+ /* Profile Edit Styles */
62
+ .glass-card {
63
+ background: rgba(255, 255, 255, 0.65);
64
+ backdrop-filter: blur(12px);
65
+ -webkit-backdrop-filter: blur(12px);
66
+ border: 1px solid rgba(255, 255, 255, 0.4);
67
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.1);
68
+ border-radius: 16px;
69
+ padding: 2rem;
70
+ }
71
+
72
+ .glass-card .page-title {
73
+ color: var(--primal_dark);
74
+ font-weight: 800;
75
+ margin-bottom: 1.5rem;
76
+ text-shadow: 0 2px 4px rgba(0,0,0,0.05);
77
+ }
78
+ .form-label-custom {
79
+ font-weight: 600;
80
+ color: #495057;
81
+ margin-bottom: 0.5rem;
82
+ display: block;
83
+ }
84
+ .form-control-glass {
85
+ background: rgba(255, 255, 255, 0.5);
86
+ border: 1px solid rgba(0, 0, 0, 0.1);
87
+ border-radius: 8px;
88
+ padding: 0.6rem 1rem;
89
+ transition: all 0.3s ease;
90
+ }
91
+ .form-control-glass:focus {
92
+ background: rgba(255, 255, 255, 0.9);
93
+ box-shadow: 0 0 0 4px rgba(35, 99, 195, 0.15);
94
+ border-color: var(--primal);
95
+ }
96
+ .profile-preview-container {
97
+ position: sticky;
98
+ top: 20px;
99
+ text-align: center;
100
+ }
101
+ .preview-img {
102
+ border-radius: 50%;
103
+ box-shadow: 0 8px 20px rgba(0,0,0,0.15);
104
+ border: 5px solid rgba(255, 255, 255, 0.8);
105
+ transition: transform 0.3s ease;
106
+ }
107
+ .preview-img:hover {
108
+ transform: scale(1.02);
109
+ }
110
+
111
+ /* Scoped Action Button for Edit Profile */
112
+ .glass-card .action-btn {
113
+ border-radius: 10px;
114
+ padding: 10px 25px;
115
+ font-weight: 600;
116
+ display: inline-flex;
117
+ align-items: center;
118
+ gap: 8px;
119
+ transition: all 0.2s;
120
+ }
121
+ .glass-card .action-btn:hover {
122
+ transform: translateY(-2px);
123
+ }