mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-08-07 14:15:18 +02:00
feat: add measurement system field to CustomUser model and update related serializers, migrations, and UI components
This commit is contained in:
parent
2af78e0a53
commit
31630de4fd
9 changed files with 76 additions and 21 deletions
|
@ -82,11 +82,11 @@ from users.models import CustomUser
|
|||
|
||||
class CustomUserAdmin(UserAdmin):
|
||||
model = CustomUser
|
||||
list_display = ['username', 'is_staff', 'is_active', 'image_display']
|
||||
list_display = ['username', 'is_staff', 'is_active', 'image_display', 'measurement_system']
|
||||
readonly_fields = ('uuid',)
|
||||
search_fields = ('username',)
|
||||
fieldsets = UserAdmin.fieldsets + (
|
||||
(None, {'fields': ('profile_pic', 'uuid', 'public_profile', 'disable_password')}),
|
||||
(None, {'fields': ('profile_pic', 'uuid', 'public_profile', 'disable_password', 'measurement_system')}),
|
||||
)
|
||||
def image_display(self, obj):
|
||||
if obj.profile_pic:
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 5.2.2 on 2025-08-05 15:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0004_customuser_disable_password'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='customuser',
|
||||
name='measurement_system',
|
||||
field=models.CharField(choices=[('metric', 'Metric'), ('imperial', 'Imperial')], default='metric', max_length=10),
|
||||
),
|
||||
]
|
|
@ -9,6 +9,7 @@ class CustomUser(AbstractUser):
|
|||
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
|
||||
public_profile = models.BooleanField(default=False)
|
||||
disable_password = models.BooleanField(default=False)
|
||||
measurement_system = models.CharField(max_length=10, choices=[('metric', 'Metric'), ('imperial', 'Imperial')], default='metric')
|
||||
|
||||
def __str__(self):
|
||||
return self.username
|
|
@ -50,7 +50,7 @@ class UserDetailsSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = CustomUser
|
||||
extra_fields = ['profile_pic', 'uuid', 'public_profile']
|
||||
extra_fields = ['profile_pic', 'uuid', 'public_profile', 'measurement_system']
|
||||
|
||||
if hasattr(UserModel, 'USERNAME_FIELD'):
|
||||
extra_fields.append(UserModel.USERNAME_FIELD)
|
||||
|
@ -66,6 +66,8 @@ class UserDetailsSerializer(serializers.ModelSerializer):
|
|||
extra_fields.append('is_staff')
|
||||
if hasattr(UserModel, 'disable_password'):
|
||||
extra_fields.append('disable_password')
|
||||
if hasattr(UserModel, 'measurement_system'):
|
||||
extra_fields.append('measurement_system')
|
||||
|
||||
fields = ['pk', *extra_fields]
|
||||
read_only_fields = ('email', 'date_joined', 'is_staff', 'is_superuser', 'is_active', 'pk', 'disable_password')
|
||||
|
@ -96,7 +98,7 @@ class CustomUserDetailsSerializer(UserDetailsSerializer):
|
|||
|
||||
class Meta(UserDetailsSerializer.Meta):
|
||||
model = CustomUser
|
||||
fields = UserDetailsSerializer.Meta.fields + ['profile_pic', 'uuid', 'public_profile', 'has_password', 'disable_password']
|
||||
fields = UserDetailsSerializer.Meta.fields + ['profile_pic', 'uuid', 'public_profile', 'has_password', 'disable_password', 'measurement_system']
|
||||
read_only_fields = UserDetailsSerializer.Meta.read_only_fields + ('uuid', 'has_password', 'disable_password')
|
||||
|
||||
@staticmethod
|
||||
|
|
1
frontend/src/app.d.ts
vendored
1
frontend/src/app.d.ts
vendored
|
@ -17,6 +17,7 @@ declare global {
|
|||
public_profile: boolean;
|
||||
has_password: boolean;
|
||||
disable_password: boolean;
|
||||
measurement_system: 'metric' | 'imperial';
|
||||
} | null;
|
||||
locale: string;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ export type User = {
|
|||
public_profile: boolean;
|
||||
has_password: boolean;
|
||||
disable_password: boolean;
|
||||
measurement_system: 'metric' | 'imperial';
|
||||
};
|
||||
|
||||
export type ContentImage = {
|
||||
|
|
|
@ -542,7 +542,9 @@
|
|||
"data_override_warning_desc": "Restoring data will completely replace all existing data (that is included \t\t\t\t\t\t\t\t\t\t\t\tin the backup) in your account. This action cannot be undone.",
|
||||
"select_backup_file": "Select backup file",
|
||||
"data_override_acknowledge": "I acknowledge that this will override all my existing data",
|
||||
"data_override_acknowledge_desc": "This action is irreversible and will replace all locations, collections, \t\t\t\t\t\t\t\t\t\t\t\t\t\tand visits in your account."
|
||||
"data_override_acknowledge_desc": "This action is irreversible and will replace all locations, collections, \t\t\t\t\t\t\t\t\t\t\t\t\t\tand visits in your account.",
|
||||
"use_imperial": "Use Imperial Units",
|
||||
"use_imperial_desc": "Use imperial units (feet, inches, pounds) instead of metric units"
|
||||
},
|
||||
"collection": {
|
||||
"collection_created": "Collection created successfully!",
|
||||
|
|
|
@ -129,6 +129,7 @@ export const actions: Actions = {
|
|||
let last_name = formData.get('last_name') as string | null | undefined;
|
||||
let profile_pic = formData.get('profile_pic') as File | null | undefined;
|
||||
let public_profile = formData.get('public_profile') as string | null | undefined | boolean;
|
||||
let measurement_system = formData.get('measurement_system') as string | null | undefined;
|
||||
|
||||
const resCurrent = await fetch(`${endpoint}/auth/user-metadata/`, {
|
||||
headers: {
|
||||
|
@ -148,6 +149,13 @@ export const actions: Actions = {
|
|||
public_profile = false;
|
||||
}
|
||||
|
||||
// Gets the boolean value of the measurement_system input checked means imperial
|
||||
if (measurement_system === 'on') {
|
||||
measurement_system = 'imperial';
|
||||
} else {
|
||||
measurement_system = 'metric';
|
||||
}
|
||||
|
||||
let currentUser = (await resCurrent.json()) as User;
|
||||
|
||||
if (username === currentUser.username || !username) {
|
||||
|
@ -178,6 +186,7 @@ export const actions: Actions = {
|
|||
formDataToSend.append('profile_pic', profile_pic);
|
||||
}
|
||||
formDataToSend.append('public_profile', public_profile.toString());
|
||||
formDataToSend.append('measurement_system', measurement_system.toString());
|
||||
|
||||
let csrfToken = await fetchCSRFToken();
|
||||
|
||||
|
|
|
@ -515,23 +515,44 @@
|
|||
accept="image/*"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-start gap-4">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={user.public_profile}
|
||||
name="public_profile"
|
||||
class="toggle toggle-primary"
|
||||
/>
|
||||
<div>
|
||||
<span class="label-text font-medium">{$t('auth.public_profile')}</span>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{$t('settings.public_profile_desc')}
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-start gap-4">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={user.public_profile}
|
||||
name="public_profile"
|
||||
class="toggle toggle-primary"
|
||||
/>
|
||||
<div>
|
||||
<span class="label-text font-medium">{$t('auth.public_profile')}</span>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{$t('settings.public_profile_desc')}
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- metric or imperal toggle -->
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-start gap-4">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={user.measurement_system === 'imperial'}
|
||||
name="measurement_system"
|
||||
class="toggle toggle-primary"
|
||||
on:change={() =>
|
||||
(user.measurement_system =
|
||||
user.measurement_system === 'metric' ? 'imperial' : 'metric')}
|
||||
/>
|
||||
<div>
|
||||
<span class="label-text font-medium">{$t('settings.use_imperial')}</span>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{$t('settings.use_imperial_desc')}
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-wide">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue