Skip to content

Commit ec9adcf

Browse files
authored
Revert "Revert "Theme changes (#716)" (#772)" (#800)
This reverts commit e8cf60b.
1 parent b9731f0 commit ec9adcf

File tree

65 files changed

+645
-411
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+645
-411
lines changed

zubhub_backend/zubhub/APIS/urls.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.urls import path, include
22
from zubhub.views import (UploadFileAPIView, DeleteFileAPIView,
33
HeroAPIView, HelpAPIView, ChallengeAPIView, PrivacyAPIView, FAQAPIView, AmbassadorsAPIView,
4-
SigGenAPIView, UploadFileToLocalAPIView)
4+
SigGenAPIView, UploadFileToLocalAPIView, ThemeAPIView)
55

66

77
urlpatterns = [
@@ -23,5 +23,6 @@
2323
path('ambassadors/', AmbassadorsAPIView.as_view(), name="ambassadors"),
2424
path('challenge/', ChallengeAPIView.as_view(), name="challenge"),
2525
path('signature/', SigGenAPIView,
26-
name="signature_generator_api")
26+
name="signature_generator_api"),
27+
path('theme/', ThemeAPIView.as_view(), name="theme"),
2728
]

zubhub_backend/zubhub/zubhub/admin.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
from enum import Enum
12
from django.contrib import admin
2-
from .models import AdminSettings, Hero, Privacy, FAQ, Help, Challenge, Ambassadors
3+
from .models import AdminSettings, Hero, Privacy, FAQ, Help, Challenge, Ambassadors, Theme
34

45
## these models are imported to be unregsitered
56
from django_summernote.models import Attachment
@@ -44,6 +45,24 @@ class ChallengeAdmin(SummernoteModelAdmin):
4445

4546
class Media:
4647
js = ('https://code.jquery.com/jquery-3.1.1.js', 'js/main.js',)
48+
49+
50+
class StatusEnum(Enum):
51+
INACTIVE = 0
52+
ACTIVE = 1
53+
54+
class ThemeAdmin(admin.ModelAdmin):
55+
list_display = ['Theme_Name', 'status']
56+
actions = ['make_selected_active']
57+
58+
def make_selected_active(self, request, queryset):
59+
queryset.update(status=StatusEnum.INACTIVE.value)
60+
selected_themes = queryset.first()
61+
selected_themes.status = StatusEnum.ACTIVE.value
62+
selected_themes.save()
63+
64+
make_selected_active.short_description = "Select and make active"
65+
4766

4867
class FAQAdmin(SummernoteModelAdmin):
4968
summernote_fields = ('answer',)
@@ -68,6 +87,7 @@ class Media:
6887
admin.site.register(Challenge, ChallengeAdmin)
6988
admin.site.register(FAQ, FAQAdmin)
7089
admin.site.register(Ambassadors, AmbassadorsAdmin)
90+
admin.site.register(Theme, ThemeAdmin)
7191

7292
## Unregister some default and third-party models
7393
admin.site.unregister(Attachment)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Generated by Django 3.2 on 2023-10-02 22:55
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('zubhub', '0009_challenge'),
10+
]
11+
12+
operations = [
13+
migrations.CreateModel(
14+
name='Theme',
15+
fields=[
16+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
17+
('Theme_Name', models.CharField(max_length=20)),
18+
('Primary_Color1', models.CharField(default='#DC3545', help_text='Enter hexcode to replace color red', max_length=16)),
19+
('Primary_Color2', models.CharField(default='#FDCB00', help_text='Enter hexcode to replace color yellow', max_length=16)),
20+
('Primary_Color3', models.CharField(default='#00B8C4', help_text='Enter hexcode to replace color cyan', max_length=16)),
21+
('Secondary_Color1', models.CharField(default='#FFCDD2', help_text='Enter hexcode to replace color light red', max_length=16)),
22+
('Secondary_Color2', models.CharField(default='#A94442', help_text='Enter hexcode to replace color dark red', max_length=16)),
23+
('Secondary_Color3', models.CharField(default='#FFF7D4', help_text='Enter hexcode to replace color light yellow', max_length=16)),
24+
('Secondary_Color4', models.CharField(default='#9F861E', help_text='Enter hexcode to replace color dark yellow', max_length=16)),
25+
('Secondary_Color5', models.CharField(default='#E0F6F4', help_text='Enter hexcode to replace color light cyan', max_length=16)),
26+
('Secondary_Color6', models.CharField(default='#03848C', help_text='Enter hexcode to replace color dark cyan', max_length=16)),
27+
('Text_Color1', models.CharField(default='#212121', help_text='Enter hexcode to replace color black', max_length=16)),
28+
('Text_Color2', models.CharField(default='#757474', help_text='Enter hexcode to replace color dark gray', max_length=16)),
29+
('Text_Color3', models.CharField(default='#E4E4E4', help_text='Enter hexcode to replace color light gray', max_length=16)),
30+
('status', models.PositiveSmallIntegerField(choices=[(0, 'Inactive'), (1, 'Active')], default=0)),
31+
],
32+
options={
33+
'verbose_name': 'Theme',
34+
'verbose_name_plural': 'Themes',
35+
},
36+
),
37+
]

zubhub_backend/zubhub/zubhub/models.py

+29-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from django.utils.text import slugify
88
from .utils import MediaStorage, get_upload_path, clean_summernote_html
99
from projects.models import Project
10-
10+
from django.utils.html import strip_tags
1111

1212
class AdminSettings(models.Model):
1313
PUBLIC = 1
@@ -151,3 +151,31 @@ def __str__(self):
151151
def save(self, *args, **kwargs):
152152
self.edited_on = timezone.now()
153153
super().save(*args, **kwargs)
154+
155+
class Theme(models.Model):
156+
Theme_Name = models.CharField(max_length=20)
157+
Primary_Color1 = models.CharField(max_length=16, help_text="Enter hexcode to replace color red", default="#DC3545")
158+
Primary_Color2 = models.CharField(max_length=16, help_text="Enter hexcode to replace color yellow", default="#FDCB00")
159+
Primary_Color3 = models.CharField(max_length=16, help_text="Enter hexcode to replace color cyan", default="#00B8C4")
160+
Secondary_Color1 = models.CharField(max_length=16, help_text="Enter hexcode to replace color light red", default="#FFCDD2")
161+
Secondary_Color2 = models.CharField(max_length=16, help_text="Enter hexcode to replace color dark red", default="#A94442")
162+
Secondary_Color3 = models.CharField(max_length=16, help_text="Enter hexcode to replace color light yellow", default="#FFF7D4")
163+
Secondary_Color4 = models.CharField(max_length=16, help_text="Enter hexcode to replace color dark yellow", default="#9F861E")
164+
Secondary_Color5 = models.CharField(max_length=16, help_text="Enter hexcode to replace color light cyan", default="#E0F6F4")
165+
Secondary_Color6 = models.CharField(max_length=16, help_text="Enter hexcode to replace color dark cyan", default="#03848C")
166+
Text_Color1 = models.CharField(max_length=16, help_text="Enter hexcode to replace color black", default="#212121")
167+
Text_Color2 = models.CharField(max_length=16, help_text="Enter hexcode to replace color dark gray", default="#757474")
168+
Text_Color3 = models.CharField(max_length=16, help_text="Enter hexcode to replace color light gray", default="#E4E4E4")
169+
status = models.PositiveSmallIntegerField(choices=((0, 'Inactive'), (1, 'Active')), default=0)
170+
171+
class Meta:
172+
verbose_name = "Theme"
173+
verbose_name_plural = "Themes"
174+
175+
def save(self, *args, **kwargs):
176+
if self.status == 1:
177+
Theme.objects.exclude(pk=self.pk).update(status=0)
178+
super().save(*args, **kwargs)
179+
180+
def __str__(self):
181+
return self.Theme_Name

zubhub_backend/zubhub/zubhub/serializers.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from rest_framework import serializers
2-
from .models import Hero, FAQ, Help, Challenge, Privacy, Ambassadors
2+
from .models import Hero, FAQ, Help, Challenge, Privacy, Ambassadors, Theme
33
from projects.pagination import ProjectNumberPagination
44
from projects.utils import get_published_projects_for_user
55
from projects.serializers import ProjectSerializer
@@ -98,4 +98,10 @@ def paginated_projects(self, obj):
9898
else:
9999
next_page = None
100100

101-
return {"results": serializer.data, "prev": prev_page, "next": next_page, "count": count}
101+
return {"results": serializer.data, "prev": prev_page, "next": next_page, "count": count}
102+
103+
class ThemeSerializer(serializers.ModelSerializer):
104+
105+
class Meta:
106+
model = Theme
107+
fields = '__all__'

zubhub_backend/zubhub/zubhub/urls.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
from zubhub.views import (UploadFileAPIView, DeleteFileAPIView,
4747
HeroAPIView, HelpAPIView, ChallengeAPIView, PrivacyAPIView,
4848
FAQAPIView, AmbassadorsAPIView, SigGenAPIView, UploadFileToLocalAPIView,
49-
MarkdownToHtmlAPIView, MediaSchemaAPIView, WebSchemaAPIView)
49+
MarkdownToHtmlAPIView, MediaSchemaAPIView, WebSchemaAPIView, ThemeAPIView)
5050

5151
schema_url_patterns = [
5252
path('api/rest-auth/login/', LoginView.as_view()),
@@ -67,7 +67,8 @@
6767
path('api/privacy/', PrivacyAPIView.as_view()),
6868
path('api/faqs/', FAQAPIView.as_view()),
6969
path('api/ambassadors/', AmbassadorsAPIView.as_view()),
70-
path('api/signature/', SigGenAPIView)
70+
path('api/signature/', SigGenAPIView),
71+
path('api/theme/', ThemeAPIView.as_view())
7172
]
7273

7374
urlpatterns = urlpatterns + [

zubhub_backend/zubhub/zubhub/views.py

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from math import floor
22
import uuid
3-
from .serializers import HeroSerializer, FAQListSerializer, HelpSerializer, ChallengeSerializer, PrivacySerializer, AmbassadorsSerializer
4-
from .models import Hero, FAQ, Privacy, Help, Challenge, Ambassadors, AdminSettings
3+
from django.shortcuts import get_object_or_404
4+
from django.utils.html import format_html
5+
from .serializers import HeroSerializer, FAQListSerializer, HelpSerializer, ChallengeSerializer, PrivacySerializer, AmbassadorsSerializer, ThemeSerializer
6+
from .models import Hero, FAQ, Privacy, Help, Challenge, Ambassadors, AdminSettings, Theme
57
from .utils import delete_file_from_media_server, upload_file_to_media_server, get_sig
68
from projects.permissions import PostUserRateThrottle, GetUserRateThrottle, SustainedRateThrottle
79
from rest_framework.permissions import IsAuthenticated
@@ -341,4 +343,17 @@ def MediaSchemaAPIView(request):
341343

342344
from .utils import get_media_schema
343345
res = get_media_schema()
344-
return Response(res.json())
346+
return Response(res.json())
347+
348+
class ThemeAPIView(RetrieveAPIView):
349+
"""
350+
Get "Theme Zubhub".
351+
"""
352+
353+
queryset = Theme.objects.all()
354+
serializer_class = ThemeSerializer
355+
permission_classes = [AllowAny]
356+
throttle_classes = [GetUserRateThrottle, SustainedRateThrottle]
357+
358+
def get_object(self):
359+
return get_object_or_404(Theme, status=1)

zubhub_frontend/zubhub/src/App.js

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import React from 'react';
1+
import React, { useContext } from 'react';
22
import { withTranslation } from 'react-i18next';
33
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
4-
import CreateActivity from './views/create_activity/CreateActivity';
5-
4+
import CreateActivity from './views/create_activity/create_activity';
5+
import { useEffect, useState } from "react";
66
import LoadingPage from './views/loading/LoadingPage';
77
import PageWrapper from './views/PageWrapper';
8+
import ZubhubAPI from '../src/api/api';
9+
import { updateTheme } from './theme';
810
import ScrollToTop from './ScrollToTop';
911

1012
const SearchResults = React.lazy(() =>
@@ -97,6 +99,7 @@ const About = React.lazy(() => import('./views/about/About'));
9799
const Challenge = React.lazy(() => import('./views/challenge/Challenge'));
98100
const FAQs = React.lazy(() => import('./views/faqs/FAQs'));
99101
const NotFound = React.lazy(() => import('./views/not_found/NotFound'));
102+
const API = new ZubhubAPI();
100103
const Settings = React.lazy(() => import('./views/settings/Settings'));
101104

102105

@@ -109,8 +112,28 @@ const LazyImport = props => {
109112
);
110113
};
111114

115+
const ThemeContext = React.createContext();
116+
112117
function App(props) {
118+
119+
const theme = useContext(ThemeContext);
120+
121+
useEffect(() => {
122+
handleThemeChange();
123+
}, []);
124+
125+
const handleThemeChange = async () => {
126+
try {
127+
const data = await API.theme();
128+
129+
updateTheme(data);
130+
} catch (error) {
131+
console.error(error);
132+
}
133+
};
134+
113135
return (
136+
<ThemeContext.Provider value={theme}>
114137
<Router>
115138
<ScrollToTop />
116139
<Switch>
@@ -699,6 +722,7 @@ function App(props) {
699722
/>
700723
</Switch>
701724
</Router>
725+
</ThemeContext.Provider>
702726
);
703727
}
704728

zubhub_frontend/zubhub/src/api/api.js

+14
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@ class API {
103103
return this.request({ url, method, body }).then(res => res.json());
104104
};
105105

106+
/**
107+
* @method theme - get the latest theme from the backend
108+
* @author Hemant Kumar Singh <[email protected]>
109+
*
110+
* @todo - describe method's signature
111+
*/
112+
theme = () => {
113+
const url = 'theme/';
114+
const method = 'GET';
115+
// const body = JSON.stringify({ username, password });
116+
117+
return this.request({ url, method }).then(res => res.json());
118+
};
119+
106120
/**
107121
* @method logout - logout a user with the user's token
108122
* @author Raymond Ndibe <[email protected]>

0 commit comments

Comments
 (0)