-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #88 from spline2hg/profilepage
Profilepage
- Loading branch information
Showing
22 changed files
with
1,251 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ __pycache__ | |
django.log | ||
.env | ||
.ruff_cache | ||
cardie/media/profile_images |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
from django.contrib import admin | ||
from .models import Profile | ||
|
||
# Register your models here. | ||
|
||
admin.site.register(Profile) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from django import forms | ||
from .models import Profile, User | ||
|
||
|
||
|
||
class UserUpdateForm(forms.ModelForm): | ||
class Meta: | ||
model = User | ||
fields = ['username', 'email'] | ||
|
||
|
||
class ProfileUpdateForm(forms.ModelForm): | ||
profile_image = forms.ImageField( | ||
widget=forms.FileInput(attrs={'class': 'hidden'}), | ||
required=False | ||
) | ||
class Meta: | ||
model = Profile | ||
fields = ['profile_image', 'bio'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Generated by Django 5.0.3 on 2024-10-08 13:24 | ||
|
||
import django.db.models.deletion | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('authentication', '0003_user_wallet'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Profile', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('profile_image', models.ImageField(default='default_images/default_profile.jpg', upload_to='profile_images/')), | ||
('bio', models.CharField(blank=True, max_length=256)), | ||
('created_at', models.DateTimeField(auto_now_add=True)), | ||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='authentication.user')), | ||
], | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
{% load static %} | ||
|
||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Cardie | Profile</title> | ||
|
||
<!-- External Scripts --> | ||
<script src="https://unpkg.com/@phosphor-icons/web"></script> | ||
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script> | ||
|
||
<!-- CSS Links --> | ||
<link rel="stylesheet" type="text/css" href="{% static '/main/variables.css' %}"> | ||
<link rel="stylesheet" type="text/css" href="{% static '/main/ui.css' %}"> | ||
<link rel="stylesheet" type="text/css" href="{% static '/main/notifications.css' %}"> | ||
<link rel="stylesheet" type="text/css" href="{% static '/main/home.css' %}"> | ||
<link rel="stylesheet" type="text/css" href="{% static '/main/profile.css' %}"> | ||
<link rel="shortcut icon" type="image/png" href="{% static '/main/images/favicon_light.ico' %}"/> | ||
</head> | ||
|
||
<body> | ||
<div id="home-top"> | ||
<a href="{% url 'index' %}"> | ||
<div id="home-top-logo"> | ||
<img id="home-top-image" src="{% static '/main/images/logo_light.png' %}"> | ||
</div> | ||
</a> | ||
|
||
<div id="home-top-profile" x-data="{ open: false }" @click.away="open = false"> | ||
<button id="home-top-username" class="ui_button_small" @click="open = !open"> | ||
{{ profile.user.username }} <i class="ph-bold ph-caret-down"></i> | ||
</button> | ||
|
||
<div id="home-top-profile-dropdown" x-show="open" x-transition> | ||
<div class="dropdown-content"> | ||
<a href="{% url 'home' %}" > | ||
<button class="ui_button_small view-profile-btn"> | ||
<i class="ph-bold ph-user"></i> Home | ||
</button> | ||
</a> | ||
<button class="ui_button_small logout-btn" @click="log_out()"> | ||
<i class="ph-bold ph-sign-out"></i> Log Out | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<form method="POST" enctype="multipart/form-data" x-ref="profileForm"> | ||
{% csrf_token %} | ||
<div id="profile-container" x-data="{ | ||
editMode: false, | ||
toggleEdit() { | ||
this.editMode = !this.editMode; | ||
}, | ||
triggerFileInput() { | ||
this.$refs.fileInput.click(); | ||
}, | ||
handleFileChange(event) { | ||
const file = event.target.files[0]; | ||
if (file) { | ||
const reader = new FileReader(); | ||
reader.onload = (e) => { | ||
document.querySelector('.profile-image').src = e.target.result; | ||
}; | ||
reader.readAsDataURL(file); | ||
} | ||
} | ||
}"> | ||
<div id="profile-details"> | ||
<div class="detail-card"> | ||
<h2 class="ui_text_subheader_left">Account Details</h2> | ||
<div class="info-item ui_text_body"> | ||
<i class="ph-bold ph-user"></i> | ||
<template x-if="!editMode"> | ||
<span>{{ profile.user.username }}</span> | ||
</template> | ||
<template x-if="editMode"> | ||
{{ u_form.username }} | ||
</template> | ||
</div> | ||
<div class="info-item ui_text_body"> | ||
<i class="ph-bold ph-envelope"></i> | ||
<template x-if="!editMode"> | ||
<span>{{ profile.user.email }}</span> | ||
</template> | ||
<template x-if="editMode"> | ||
{{ u_form.email }} | ||
</template> | ||
</div> | ||
<div class="info-item ui_text_body"> | ||
<i class="ph-bold ph-file-text"></i> | ||
<template x-if="!editMode"> | ||
{% if profile.bio %} | ||
|
||
<span>{{ profile.bio }}</span> | ||
{% else %} | ||
<p class="ui_text_body">No bio available.</p> | ||
{% endif %} | ||
</template> | ||
<template x-if="editMode"> | ||
{{ p_form.bio }} | ||
</template> | ||
</div> | ||
<div class="info-item ui_text_body"> | ||
<i class="ph-bold ph-calendar"></i> | ||
<span>Created: {{ profile.created_at }}</span> | ||
</div> | ||
</div> | ||
|
||
<div class="detail-card"> | ||
<h2 class="ui_text_subheader_left">Account Actions</h2> | ||
<div class="action-buttons"> | ||
<template x-if="!editMode"> | ||
<button type="button" class="ui_button_grid" @click="toggleEdit()"> | ||
<i class="ph-bold ph-pencil"></i> | ||
<span>Edit Profile</span> | ||
</button> | ||
</template> | ||
<template x-if="editMode"> | ||
<button type="submit" class="ui_button_grid" @click="$refs.profileForm.submit()"> | ||
<i class="ph-bold ph-check"></i> | ||
<span>Save Changes</span> | ||
</button> | ||
</template> | ||
<template x-if="editMode"> | ||
<button type="button" class="ui_button_grid" @click="toggleEdit()"> | ||
<i class="ph-bold ph-x"></i> | ||
<span>Cancel</span> | ||
</button> | ||
</template> | ||
<button type="button" class="ui_button_grid" @click="openSettingsModal()"> | ||
<i class="ph-bold ph-gear"></i> | ||
<span>Settings</span> | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div id="profile-image-section"> | ||
<div class="profile-image-container" @click="editMode && triggerFileInput()"> | ||
<img class="profile-image" src="{{ profile.profile_image.url }}" alt="Profile Image"> | ||
<template x-if="editMode"> | ||
<div class="profile-image-overlay"> | ||
<i class="ph-bold ph-camera" style="font-size: 24px;"></i> | ||
</div> | ||
</template> | ||
</div> | ||
<input | ||
type="file" | ||
name="profile_image" | ||
x-ref="fileInput" | ||
@change="handleFileChange" | ||
accept="image/*" | ||
style="display: none;"> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
<!-- Settings Modal --> | ||
<div class="modal-backdrop" id="settingsModal" style="display: none;"> | ||
<div class="settings-modal"> | ||
<div class="modal-sidebar"> | ||
<div class="sidebar-item active" data-section="general"> | ||
<i class="ph-bold ph-gear"></i> | ||
General | ||
</div> | ||
<div class="sidebar-item" data-section="security"> | ||
<i class="ph-bold ph-shield"></i> | ||
Security | ||
</div> | ||
<div class="sidebar-item" data-section="notifications"> | ||
<i class="ph-bold ph-bell"></i> | ||
Notifications | ||
</div> | ||
</div> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<h2 class="ui_text_subheader_left">Settings</h2> | ||
<button class="close-button" onclick="closeSettingsModal()">×</button> | ||
</div> | ||
|
||
<div class="content-section active" id="general"> | ||
<h3 class="ui_text_smallersubheader">General Settings</h3> | ||
<!-- Add general settings content here --> | ||
</div> | ||
|
||
<div class="content-section" id="security"> | ||
<h3 class="ui_text_smallersubheader">Security Settings</h3> | ||
<div class="form-group"> | ||
<button class="ui_button_small" onclick="togglePasswordFields()">Change Password</button> | ||
<div id="passwordFields" style="display: none; margin-top: 20px;"> | ||
<div class="form-group"> | ||
<label class="ui_text_body" for="currentPassword">Current Password</label> | ||
<input class="ui_input_generic" type="password" id="currentPassword"> | ||
</div> | ||
<div class="form-group"> | ||
<label class="ui_text_body" for="newPassword">New Password</label> | ||
<input class="ui_input_generic" type="password" id="newPassword"> | ||
</div> | ||
<div class="form-group"> | ||
<label class="ui_text_body" for="confirmPassword">Confirm New Password</label> | ||
<input class="ui_input_generic" type="password" id="confirmPassword"> | ||
</div> | ||
<button class="ui_button_small" onclick="updatePassword()">Update Password</button> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="content-section" id="notifications"> | ||
<h3 class="ui_text_smallersubheader">Notification Settings</h3> | ||
<!-- Add notification settings content here --> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<script> | ||
var server_ip = "{{ server_ip }}"; | ||
var production = "{{ production }}"; | ||
var username = "{{ username }}" | ||
</script> | ||
|
||
<!-- Script tags --> | ||
<script src="{% static '/main/scripts/profile/profile.js' %}"></script> | ||
<script src="{% static '/main/scripts/home/home.js' %}"></script> | ||
<script src="{% static '/main/scripts/global/favicon.js' %}"></script> | ||
<script src="{% static '/main/scripts/global/notifications.js' %}"></script> | ||
<script src="{% static '/main/scripts/global/logging.js' %}"></script> | ||
<script src="{% static '/main/scripts/global/background_blur.js' %}"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.