diff --git a/zubhub_backend/zubhub/creators/adapter.py b/zubhub_backend/zubhub/creators/adapter.py index 2b36bdfb4..55a916838 100644 --- a/zubhub_backend/zubhub/creators/adapter.py +++ b/zubhub_backend/zubhub/creators/adapter.py @@ -2,13 +2,13 @@ from .models import Location class CustomAccountAdapter(DefaultAccountAdapter): - + def save_user(self, request, user, form, commit=False): creator = super().save_user(request, user, form, commit) data = form.cleaned_data - location = Location.objects.get(name = data.get('location')) - + location = Location.objects.get(name=data.get('location')) + creator.dateOfBirth = data.get('dateOfBirth') creator.location = location creator.save() - return creator \ No newline at end of file + return creator diff --git a/zubhub_backend/zubhub/creators/models.py b/zubhub_backend/zubhub/creators/models.py index 745e81f3e..5017ac7f1 100644 --- a/zubhub_backend/zubhub/creators/models.py +++ b/zubhub_backend/zubhub/creators/models.py @@ -6,34 +6,33 @@ from math import floor - class Location(models.Model): - name = models.CharField(max_length = 100) - slug = models.SlugField(unique = True, max_length = 106) + name = models.CharField(max_length=100) + slug = models.SlugField(unique=True, max_length=106) - def save(self,*args,**kwargs): + def save(self, *args, **kwargs): if self.slug: pass else: uid = str(uuid.uuid4()) uid = uid[0: floor(len(uid)/6)] self.slug = slugify(self.name) + "-" + uid - super().save(*args,**kwargs) + super().save(*args, **kwargs) def __str__(self): return self.name - - class Creator(AbstractUser): - id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True) + id = models.UUIDField( + primary_key=True, default=uuid.uuid4, editable=False, unique=True) avatar = models.URLField(max_length=1000, blank=True, null=True) - phone = models.CharField(unique=True, max_length=17, blank=True, null = True) + phone = models.CharField(unique=True, max_length=17, blank=True, null=True) dateOfBirth = models.DateField(blank=True, null=True) - location = models.ForeignKey(Location, null=True, on_delete=models.SET_NULL) + location = models.ForeignKey( + Location, null=True, on_delete=models.SET_NULL) bio = models.CharField(max_length=255, blank=True, null=True) - def save(self,*args,**kwargs): + def save(self, *args, **kwargs): self.avatar = 'https://robohash.org/{0}'.format(self.username) - super().save(*args,**kwargs) \ No newline at end of file + super().save(*args, **kwargs) diff --git a/zubhub_backend/zubhub/creators/permissions.py b/zubhub_backend/zubhub/creators/permissions.py new file mode 100644 index 000000000..616d05bf6 --- /dev/null +++ b/zubhub_backend/zubhub/creators/permissions.py @@ -0,0 +1,6 @@ +from rest_framework.permissions import BasePermission + +class IsOwner(BasePermission): + message = "You must be the owner of this object to perform this function" + def has_object_permission(self, request, view, objects): + return objects.pk == request.user.pk \ No newline at end of file diff --git a/zubhub_backend/zubhub/creators/serializers.py b/zubhub_backend/zubhub/creators/serializers.py index bf3860086..f20535844 100644 --- a/zubhub_backend/zubhub/creators/serializers.py +++ b/zubhub_backend/zubhub/creators/serializers.py @@ -10,10 +10,14 @@ Creator = get_user_model() + class CreatorSerializer(serializers.ModelSerializer): + class Meta: model = Creator - fields = ('username','email',) + fields = ('username', 'email', 'avatar', + 'dateOfBirth', 'location', 'bio',) + class LocationSerializer(serializers.ModelSerializer): class Meta: @@ -23,7 +27,8 @@ class Meta: class CustomRegisterSerializer(RegisterSerializer): dateOfBirth = serializers.DateField() - location = serializers.SlugRelatedField(slug_field='name', queryset = Location.objects.all()) + location = serializers.SlugRelatedField( + slug_field='name', queryset=Location.objects.all()) # def validate_phone(self, phone): # if re.search(r'^\+\d{9,15}$', phone) == None: @@ -36,7 +41,8 @@ class CustomRegisterSerializer(RegisterSerializer): def validate_dateOfBirth(self, dateOfBirth): if((date.today() - dateOfBirth).days < 0): - raise serializers.ValidationError(_("Date of Birth must be less than today's date")) + raise serializers.ValidationError( + _("Date of Birth must be less than today's date")) return dateOfBirth def validate_location(self, location): @@ -48,5 +54,5 @@ def get_cleaned_data(self): data_dict = super().get_cleaned_data() data_dict['dateOfBirth'] = self.validated_data.get('dateOfBirth', '') data_dict['location'] = self.validated_data.get('location', '') - + return data_dict diff --git a/zubhub_backend/zubhub/creators/urls.py b/zubhub_backend/zubhub/creators/urls.py index c131a90d5..660b2cc6d 100644 --- a/zubhub_backend/zubhub/creators/urls.py +++ b/zubhub_backend/zubhub/creators/urls.py @@ -1,9 +1,12 @@ from django.urls import path -from .views import auth_user_api_view, LocationListAPIView +from .views import auth_user_api_view, UserProfileAPIView, LocationListAPIView, EditCreatorAPIView app_name = "creators" urlpatterns = [ - path('authUser/', auth_user_api_view, name = 'auth_user_detail'), - path('locations/', LocationListAPIView.as_view(), name = 'location_list') -] \ No newline at end of file + path('authUser/', auth_user_api_view, name='auth_user_detail'), + path('edit_creator/', EditCreatorAPIView.as_view(), name='edit_creator'), + path('locations/', LocationListAPIView.as_view(), name='location_list'), + path('/', UserProfileAPIView.as_view(), name='user_profile') +] + diff --git a/zubhub_backend/zubhub/creators/views.py b/zubhub_backend/zubhub/creators/views.py index 29809d769..bb4666c61 100644 --- a/zubhub_backend/zubhub/creators/views.py +++ b/zubhub_backend/zubhub/creators/views.py @@ -1,17 +1,42 @@ -from rest_framework.generics import ListAPIView -from rest_framework.permissions import AllowAny from rest_framework.decorators import api_view, permission_classes -from rest_framework.permissions import IsAuthenticated +from rest_framework.generics import UpdateAPIView, RetrieveAPIView, ListAPIView +from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.response import Response from .serializers import CreatorSerializer, LocationSerializer +from django.contrib.auth import get_user_model +from .permissions import IsOwner from .models import Location + +Creator = get_user_model() + + @api_view(['GET']) @permission_classes([IsAuthenticated]) def auth_user_api_view(request): return Response(CreatorSerializer(request.user).data) +class UserProfileAPIView(RetrieveAPIView): + queryset = Creator.objects.all() + serializer_class = CreatorSerializer + lookup_field = "username" + permission_classes = [AllowAny] + + +class EditCreatorAPIView(UpdateAPIView): + queryset = Creator.objects.all() + serializer_class = CreatorSerializer + permission_classes = [IsAuthenticated, IsOwner] + + def patch(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def get_object(self): + queryset = self.filter_queryset(self.get_queryset()) + obj = queryset.get(pk=self.request.user.pk) + self.check_object_permissions(self.request, obj) + return obj class LocationListAPIView(ListAPIView): queryset = Location.objects.all() diff --git a/zubhub_frontend/zubhub/src/App.js b/zubhub_frontend/zubhub/src/App.js index f93313777..e1a35976f 100644 --- a/zubhub_frontend/zubhub/src/App.js +++ b/zubhub_frontend/zubhub/src/App.js @@ -14,6 +14,8 @@ import Login from './components/pages/user_auth/Login'; import PasswordReset from './components/pages/user_auth/PasswordReset'; import PasswordResetConfirm from './components/pages/user_auth/PasswordResetConfirm'; import EmailConfirm from './components/pages/user_auth/EmailConfirm'; +import Profile from './components/pages/profile/Profile'; + // import Artists from './components/pages/artists/Artists'; // import Artist from './components/pages/artists/Artist'; // import Upcoming from './components/pages/upcoming/Upcoming'; @@ -26,16 +28,8 @@ import EmailConfirm from './components/pages/user_auth/EmailConfirm'; // import NewsDetails from './components/pages/news/NewsDetails'; // import Cart from './components/pages/cart/Cart'; -// import Profile from './components/pages/admin/Profile'; - class App extends Component { - constructor(props){ - super(props); - - } - - - + render(){ let apiProps = this.props; @@ -48,7 +42,6 @@ return( exact={true} path="/" render={props=>( - console.log(props), @@ -89,6 +82,19 @@ return( )}/> + ( + + + + )}/> + +( + + + + )}/> ); diff --git a/zubhub_frontend/zubhub/src/components/PageWrapper.jsx b/zubhub_frontend/zubhub/src/components/PageWrapper.jsx index 51443a9d2..6a677db28 100644 --- a/zubhub_frontend/zubhub/src/components/PageWrapper.jsx +++ b/zubhub_frontend/zubhub/src/components/PageWrapper.jsx @@ -7,8 +7,8 @@ import { withAPI } from './api'; import { ToastContainer, toast } from 'react-toastify'; -import * as AuthActions from '../store/actions/authActions'; -// import * as userActions from '../store/actions/userActions'; +import * as AuthActions from '../store/actions/authActions' + import unstructuredLogo from '../assets/images/logos/unstructured-logo.png'; import logo from '../assets/images/logos/logo.png'; @@ -16,11 +16,32 @@ import logo from '../assets/images/logos/logo.png'; class PageWrapper extends Component { + constructor(props){ + super(props); + + this.state = { + username: null + } + } + + componentDidMount(){ + if(this.props.auth.token){ + this.props.api.get_auth_user(this.props.auth.token) + .then(res=>{ + if(!res.username){ + throw new Error("an error occured while getting user profile, please try again later") + } + this.props.set_auth_user({...this.props.auth, username: res.username}) + }) + .catch(error=>toast.warning(error.message)) + } + } + logout=(e)=>{ // e.preventDefault(); this.props.api.logout(this.props.auth.token) .then(res=>{ - this.props.set_auth_user({token:null, username: null, email: null})}) + this.props.set_auth_user({token:null, username: null})}) .catch(error=>{ toast.warning("An error occured while signing you out. please try again") }) @@ -30,7 +51,6 @@ class PageWrapper extends Component { render(){ return ( -
@@ -43,7 +63,8 @@ return ( : <> - + + Logout } diff --git a/zubhub_frontend/zubhub/src/components/api/api.js b/zubhub_frontend/zubhub/src/components/api/api.js index 1e5fbad8d..330d47fcd 100644 --- a/zubhub_frontend/zubhub/src/components/api/api.js +++ b/zubhub_frontend/zubhub/src/components/api/api.js @@ -4,57 +4,57 @@ class API { } request=({url = '/', method = 'GET', token, body})=>{ - if(method === 'GET' && !token){ - return fetch(this.domain + url, { - method, - xsrfCookieName: 'csrftoken', - xsrfHeaderName: 'X-CSRFToken', - withCredentials:'true', - headers: new Headers({ - 'Content-Type': 'application/json' - }) - }) - } - else if(token && body){ - - return fetch(this.domain + url, { - method, - xsrfCookieName: 'csrftoken', - xsrfHeaderName: 'X-CSRFToken', - withCredentials:'true', - headers: new Headers({ - 'Authorization':`Token ${token}`, - 'Content-Type': 'application/json' - }), - body - }) - } - else if(token){ - return fetch(this.domain + url, { - method, - xsrfCookieName: 'csrftoken', - xsrfHeaderName: 'X-CSRFToken', - withCredentials:'true', - headers: new Headers({ - 'Authorization':`Token ${token}`, - 'Content-Type': 'application/json' - }) - }) - } - else if(body){ - return fetch(this.domain + url, { - method, - xsrfCookieName: 'csrftoken', - xsrfHeaderName: 'X-CSRFToken', - withCredentials:'true', - headers: new Headers({ - 'Content-Type': 'application/json' - }), - body, - }) - } - } + if(method === 'GET' && !token){ + return fetch(this.domain + url, { + method, + xsrfCookieName: 'csrftoken', + xsrfHeaderName: 'X-CSRFToken', + withCredentials:'true', + headers: new Headers({ + 'Content-Type': 'application/json' + }) + }) + } + else if(token && body){ + + return fetch(this.domain + url, { + method, + xsrfCookieName: 'csrftoken', + xsrfHeaderName: 'X-CSRFToken', + withCredentials:'true', + headers: new Headers({ + 'Authorization':`Token ${token}`, + 'Content-Type': 'application/json' + }), + body + }) + } + else if(token){ + return fetch(this.domain + url, { + method, + xsrfCookieName: 'csrftoken', + xsrfHeaderName: 'X-CSRFToken', + withCredentials:'true', + headers: new Headers({ + 'Authorization':`Token ${token}`, + 'Content-Type': 'application/json' + }) + }) + } + else if(body){ + return fetch(this.domain + url, { + method, + xsrfCookieName: 'csrftoken', + xsrfHeaderName: 'X-CSRFToken', + withCredentials:'true', + headers: new Headers({ + 'Content-Type': 'application/json' + }), + body, + }) + } + } /**********************login with email and password******************************/ login=({username, password})=>{ @@ -123,12 +123,41 @@ password_reset_confirm=({new_password1, new_password2, uid, token})=>{ /********************************************************************/ /************************** get authenticated user's details **************************/ -getAuthUser=(token)=>{ +get_auth_user=(token)=>{ + console.log(token); let url = "creators/authUser/"; return this.request({url, token}) - .then(res=> res.json()) + .then(res=>res.json()) } -/**********************************************************************/ +/********************************************************************/ + + +/************************** get user profile **************************/ +get_user_profile=({username, token})=>{ + + let url = `creators/${username}/`; + if(token){ + return this.request({url, token}) + .then(res=>res.json()) + } else { + return this.request({url}) + .then(res=>res.json()) + } +} + +/************************** edit user profile **************************/ +edit_user_profile=(profile)=>{ + let {username} = profile; + + let url = "creators/edit_creator/"; + let method = "PUT"; + let token = profile.token; + let body = JSON.stringify({ username }) + return this.request({url, method, token, body}) + .then(res=>res.json()) +} +/********************************************************************/ + /************************** get all locations **************************/ get_locations=()=>{ @@ -136,6 +165,58 @@ get_locations=()=>{ return this.request({url}) .then(res=> res.json()) } +/********************************************************************/ + +/************************** create project **************************/ +create_project=({token, title, description, video, materials_used})=>{ + let url = "projects/create/"; + let method = "POST"; + let body = JSON.stringify({ title, description, video, materials_used }) + return this.request({url, method, token, body}) + .then(res=>res.json()) +} + +/************************** get projects **************************/ +get_projects=(page)=>{ + let url = page ? `projects/?${page}` : `projects/`; + return this.request({url}) + .then(res=>res.json()) +} + +/************************** get project **************************/ +get_project=({id, token})=>{ + let url = `projects/${id}`; + if(token){ + return this.request({url, token}) + .then(res=>res.json()) + } + else { + return this.request({url}) + .then(res=>res.json()) + } +} + +/************************** like project **************************/ +toggle_like=({id, token})=>{ + let url = `projects/${id}/toggle_like/`; + + return this.request({url, token}) + .then(res=>res.json()) + + +} + +/************************** add comment **************************/ +add_comment=({id, text, token})=>{ + let url = `projects/${id}/add_comment/`; + let method = "POST"; + let body = JSON.stringify({text}) + + return this.request({url, method, body, token}) + .then(res=>res.json()) + +} + } diff --git a/zubhub_frontend/zubhub/src/components/pages/home/Home.jsx b/zubhub_frontend/zubhub/src/components/pages/home/Home.jsx index f8fbc3b14..5185e54e9 100644 --- a/zubhub_frontend/zubhub/src/components/pages/home/Home.jsx +++ b/zubhub_frontend/zubhub/src/components/pages/home/Home.jsx @@ -1,50 +1,18 @@ import React,{Component} from 'react'; import {connect} from 'react-redux'; -// import {withFirebase} from '../../api'; -// import events_data from '../../../assets/mock-api/events_data'; + class Home extends Component{ constructor(props){ super(props); - this.state={ - eventsData:[], - currentUser:{}, - } + this.state={} } - - // async componentDidMount() { - - // let response = await fetch("https://us-central1-tilllate-2cb9c.cloudfunctions.net/homePageEvents"); - - // response = await response.json(); - // //console.log(response) - - // this.props.firebase.get_all_categories().then(categories=>{ - // this.setState({ - // eventsData:response, - // categoryData:categories - // }) - // }) - // .catch(error=>console.log(error)) - // } - - render(){ - console.log(this.props); - if(Object.keys(this.state.eventsData).length !== 0){ - - return( -
-
- ) - - } - else{ return ( <> -
{this.props.auth && this.props.auth.username}, {this.props.auth && this.props.auth.email}
+ {this.props.auth.token ?
Welcome to ZubHub!! ๐Ÿ˜ƒ
:
You are not logged in, click on the login button to get started
}
@@ -56,9 +24,7 @@ class Home extends Component{
) - } - - } + } } diff --git a/zubhub_frontend/zubhub/src/components/pages/profile/Profile.jsx b/zubhub_frontend/zubhub/src/components/pages/profile/Profile.jsx new file mode 100644 index 000000000..0f926f432 --- /dev/null +++ b/zubhub_frontend/zubhub/src/components/pages/profile/Profile.jsx @@ -0,0 +1,99 @@ +import React,{Component} from 'react'; +import {connect} from 'react-redux'; +import { ToastContainer, toast } from 'react-toastify'; +import EditProfile from './profile_components/EditProfile'; +import * as AuthActions from '../../../store/actions/authActions'; + +class Profile extends Component{ + constructor(props){ + super(props); + this.state={ + profile: {}, + readOnly: true, + loading: true + } + } + + componentDidMount(){ + let username = this.props.match.params.username; + + if(!username){ + username = this.props.auth.username; + } + else if(this.props.auth.username === username) this.props.history.push("/profile"); + + this.props.api.get_user_profile({username, token:this.props.auth.token}) + .then(res=>{ + if(!res.username){ + throw new Error("an error occured while getting user profile, please try again later") + } + return this.setState({profile: res, loading: false}) + }) + .catch(error=>{toast.warning(error.message); this.setState({loading: false})}) + } + + setReadOnly=value=>this.setState({readOnly: value}) + + setProfile=value=>{ + this.setState({profile: value}); + this.props.set_auth_user({...this.props.auth, username: value.username}) + } + + render(){ + let {profile, loading, readOnly} = this.state; + + if(loading){ + return
+ fetching user profile........... +
+ } + else if(Object.keys(profile).length > 0) { + return <> + {this.props.auth.username === profile.username ? + readOnly ? + : + this.setProfile(value)} + setReadOnly={value=>this.setReadOnly(value)} {...this.props} /> + : + null + } + + profile + +
Username: {profile.username}
+ + +
{this.props.auth.username === profile.username ? `Email: ${profile.email}` : null}
+ +
{this.props.auth.username === profile.username ? `Date Of Birth: ${profile.dateOfBirth}` : null}
+ +
{this.props.auth.username === profile.username ? `Location: ${profile.location}` : null}
+ +
Bio: {profile.bio}
+ + } else { + return
+ Couldn't fetch profile, try again later +
+ } + } +} + +const mapStateToProps = state =>{ + return { + auth:state.auth, + } + } + + const mapDispatchToProps = dispatch =>{ + return { + set_auth_user:(auth_user)=>{ + dispatch(AuthActions.setAuthUser(auth_user)) + } + } + } + +export default connect( + mapStateToProps, + mapDispatchToProps + )(Profile); \ No newline at end of file diff --git a/zubhub_frontend/zubhub/src/components/pages/profile/profile_components/EditProfile.jsx b/zubhub_frontend/zubhub/src/components/pages/profile/profile_components/EditProfile.jsx new file mode 100644 index 000000000..b4207ca99 --- /dev/null +++ b/zubhub_frontend/zubhub/src/components/pages/profile/profile_components/EditProfile.jsx @@ -0,0 +1,48 @@ +import React,{Component} from 'react'; +import { toast } from 'react-toastify'; +import {withFormik} from 'formik'; + +class EditProfile extends Component{ + + updateProfile=(e)=>{ + e.preventDefault(); + this.props.api.edit_user_profile({token: this.props.auth.token, ...this.props.values}) + .then(res=>{ + if(res.username){ + this.props.setProfile(res); + this.props.setReadOnly(true); + } + else {throw new Error("An error occured while updating your profile, please try again later")} + }) + .catch(error=>toast.warning(error.message)) + } + + + render(){ + return ( + <> + + +
+ + + + + +
+ + ) + } +} + + + +export default withFormik({ + mapPropsToValue: ()=>({ + username: '' + }), + handleSubmit:(values,{setSubmitting}) =>{ + } + })(EditProfile); \ No newline at end of file diff --git a/zubhub_frontend/zubhub/src/components/pages/profile/profile_components/UserProjects.jsx b/zubhub_frontend/zubhub/src/components/pages/profile/profile_components/UserProjects.jsx new file mode 100644 index 000000000..e69de29bb diff --git a/zubhub_frontend/zubhub/src/components/pages/user_auth/Login.jsx b/zubhub_frontend/zubhub/src/components/pages/user_auth/Login.jsx index 3e531a706..523adb67d 100644 --- a/zubhub_frontend/zubhub/src/components/pages/user_auth/Login.jsx +++ b/zubhub_frontend/zubhub/src/components/pages/user_auth/Login.jsx @@ -26,9 +26,9 @@ class Login extends Component{ } return this.props.set_auth_user({token:res.key}) }) - .then(val=>this.props.api.getAuthUser(this.props.auth.token)) - .then(res=>this.props.set_auth_user({...this.props.auth, ...res})) - .then(val=>this.props.history.push("/")) + .then(val=>this.props.api.get_auth_user(this.props.auth.token)) + .then(res=>this.props.set_auth_user({...this.props.auth, username: res.username})) + .then(val=>this.props.history.push("/profile")) .catch(error=>this.setState({error:error.message})) } diff --git a/zubhub_frontend/zubhub/src/components/pages/user_auth/Signup.jsx b/zubhub_frontend/zubhub/src/components/pages/user_auth/Signup.jsx index b57aa2037..7504e1e8f 100644 --- a/zubhub_frontend/zubhub/src/components/pages/user_auth/Signup.jsx +++ b/zubhub_frontend/zubhub/src/components/pages/user_auth/Signup.jsx @@ -47,9 +47,9 @@ class Signup extends Component{ } return this.props.set_auth_user({token:res.key}) }) - .then(val=>this.props.api.getAuthUser(this.props.auth.token)) - .then(res=>this.props.set_auth_user({...this.props.auth, ...res})) - .then(val=>this.props.history.push("/")) + .then(val=>this.props.api.get_auth_user(this.props.auth.token)) + .then(res=>this.props.set_auth_user({...this.props.auth, username: res.username})) + .then(val=>this.props.history.push("/profile")) .catch(error=>this.setState({error:error.message})) }}; @@ -113,7 +113,7 @@ class Signup extends Component{ {this.props.errors['email']} }

- +
@@ -183,7 +183,7 @@ class Signup extends Component{ {this.props.errors['password1']} }

- +
diff --git a/zubhub_frontend/zubhub/src/index.css b/zubhub_frontend/zubhub/src/index.css index 56b807ef2..aba1483b9 100644 --- a/zubhub_frontend/zubhub/src/index.css +++ b/zubhub_frontend/zubhub/src/index.css @@ -12,13 +12,12 @@ code { monospace; } */ - /* App component style */ -@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;800&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;800&display=swap"); body { background-color: #ececec; - font-family: 'Montserrat', sans-serif; + font-family: "Montserrat", sans-serif; color: #282828; height: 100%; margin: 0; @@ -41,7 +40,7 @@ body { } .dropdown-menu { - background-color: #FFCC00; + background-color: #ffcc00; } .gallery-sub-nav { @@ -49,7 +48,7 @@ body { font-weight: 900; display: flex; justify-content: space-between; - background-color: #FFCC00; + background-color: #ffcc00; padding: 20px; } @@ -57,7 +56,7 @@ body { box-shadow: none; } -.sub-title{ +.sub-title { line-height: 2em; } @@ -79,7 +78,7 @@ body { } .App-header { - background-image: linear-gradient(#DC3545, #c73948); + background-image: linear-gradient(#dc3545, #c73948); min-height: 7vh; display: flex; flex-direction: row; @@ -97,6 +96,7 @@ body { .profile_image { width: 3em; height: 3em; + border: 2px solid black; border-radius: 50%; } @@ -129,7 +129,7 @@ body { margin: calc(10px + 3vh); background-color: #fc0; border: 10px solid #fc0; - box-shadow: 10px 10px #CDA500; + box-shadow: 10px 10px #cda500; } .video-item .row { @@ -138,13 +138,13 @@ body { } .video-item .col { -padding-left: unset; -padding-right: unset; + padding-left: unset; + padding-right: unset; } .video-item .container { -padding-left: unset; -padding-right: unset; + padding-left: unset; + padding-right: unset; } .video-title { @@ -174,7 +174,7 @@ padding-right: unset; .video-controls { padding: 10px; - background: #CDA500; + background: #cda500; margin: 10px -20px -20px -20px; padding-left: 0px; padding-bottom: 0px; @@ -203,17 +203,17 @@ padding-right: unset; } .video-info-box .tags { - background: #DC3545; + background: #dc3545; font-weight: 900; font-size: 2vmin; - color: #FFCC00; + color: #ffcc00; margin-right: 10px; border-radius: 20px; padding: 5px 15px 5px 15px; display: inline-block; margin-bottom: 25px; margin-top: 15px; - box-shadow: 4px 4px #CDA500; + box-shadow: 4px 4px #cda500; } .video-info-box .description { @@ -231,7 +231,7 @@ padding-right: unset; .video-sub-nav { margin: 0; padding: 20px; - background-color: #FFCC00; + background-color: #ffcc00; min-width: 100%; } @@ -262,7 +262,6 @@ padding-right: unset; .video-page-view { flex-direction: column; } - } @media only screen and (max-width: 768px) { @@ -280,13 +279,12 @@ padding-right: unset; width: unset; height: unset; margin: calc(10px + 3vh); - box-shadow: 10px 10px #CDA500; + box-shadow: 10px 10px #cda500; } .video-page-view { flex-direction: column; } - } @media only screen and (max-width: 500px) { @@ -299,12 +297,12 @@ padding-right: unset; flex-direction: column; flex-wrap: wrap; } - + .video-item { width: unset; height: unset; margin: calc(10px + 3vh); - box-shadow: 5px 5px #CDA500; + box-shadow: 5px 5px #cda500; } .App-logo { @@ -352,7 +350,7 @@ padding-right: unset; .submit-section { padding: 30px; - background-color: #DADADA; + background-color: #dadada; border-radius: 15px; margin-bottom: 20px; margin-top: 20px; @@ -378,7 +376,7 @@ padding-right: unset; .username-input { background-color: #fc0; - box-shadow: 5px 5px #CDA500; + box-shadow: 5px 5px #cda500; } .post-as-row input { @@ -397,7 +395,7 @@ padding-right: unset; .comment-input { background-color: #fc0; - box-shadow: 5px 5px #CDA500; + box-shadow: 5px 5px #cda500; } .comment-input textarea { @@ -452,7 +450,7 @@ padding-right: unset; background-color: #fc0; padding: 10px; width: 100%; - box-shadow: 5px 5px #CDA500; + box-shadow: 5px 5px #cda500; } .posted-ago { @@ -464,13 +462,10 @@ padding-right: unset; padding-top: 10px; } -.posted-ago p{ +.posted-ago p { margin-bottom: 0px; } - - - /* Footer Styles */ .footer-logo { @@ -479,7 +474,7 @@ padding-right: unset; } .footer-distributed { - background-color: #DC3545; + background-color: #dc3545; box-sizing: border-box; width: 100%; text-align: left; @@ -488,7 +483,7 @@ padding-right: unset; } .footer-distributed .footer-left p { - color: #FFCC00; + color: #ffcc00; font-size: 14px; margin: 0; } @@ -497,10 +492,10 @@ padding-right: unset; .footer-distributed p.footer-links { font-size: 18px; font-weight: bold; - color: #FFCC00; + color: #ffcc00; margin: 0 0 10px; padding: 0; - transition: ease .25s; + transition: ease 0.25s; } .footer-distributed p.footer-links a { @@ -508,14 +503,14 @@ padding-right: unset; line-height: 1.8; text-decoration: none; color: inherit; - transition: ease .25s; + transition: ease 0.25s; } .footer-distributed .footer-links a:before { content: "ยท"; font-size: 20px; left: 0; - color: #FFCC00; + color: #ffcc00; display: inline-block; padding-right: 5px; } @@ -537,21 +532,27 @@ padding-right: unset; background-color: #33383b; border-radius: 2px; font-size: 20px; - color: #FFCC00; + color: #ffcc00; text-align: center; line-height: 35px; margin-left: 3px; - transition:all .25s; + transition: all 0.25s; } -.footer-distributed .footer-right a:hover{transform:scale(1.1); -webkit-transform:scale(1.1);} +.footer-distributed .footer-right a:hover { + transform: scale(1.1); + -webkit-transform: scale(1.1); +} -.footer-distributed p.footer-links a:hover{text-decoration:underline;} +.footer-distributed p.footer-links a:hover { + text-decoration: underline; +} /* Media Queries */ @media (max-width: 600px) { - .footer-distributed .footer-left, .footer-distributed .footer-right { + .footer-distributed .footer-left, + .footer-distributed .footer-right { text-align: center; } .footer-distributed .footer-right { @@ -563,7 +564,6 @@ padding-right: unset; } } - .float-right { float: right; } @@ -579,9 +579,9 @@ padding-right: unset; } .btn-primary { - background-color: blue; + background-color: blue; } .btn-danger { -background-color: red; + background-color: red; } diff --git a/zubhub_frontend/zubhub/src/store/reducers/authReducer.js b/zubhub_frontend/zubhub/src/store/reducers/authReducer.js index 2d450594d..e92a97e38 100644 --- a/zubhub_frontend/zubhub/src/store/reducers/authReducer.js +++ b/zubhub_frontend/zubhub/src/store/reducers/authReducer.js @@ -1,4 +1,4 @@ -const defaultState = {token:null, username: null, email: null} +const defaultState = {token:null, username: null} const auth = (state=defaultState, action)=>{