Skip to content

Commit

Permalink
Added avatar support
Browse files Browse the repository at this point in the history
  • Loading branch information
johndavedecano committed Sep 16, 2018
1 parent 18ec654 commit be9cf3a
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 43 deletions.
8 changes: 5 additions & 3 deletions app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Session\TokenMismatchException;

class Handler extends ExceptionHandler
{
Expand All @@ -18,9 +20,9 @@ class Handler extends ExceptionHandler
* @var array
*/
protected $dontReport = [
\Symfony\Component\HttpKernel\Exception\HttpException::class,
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
\Illuminate\Session\TokenMismatchException::class,
HttpException::class,
ModelNotFoundException::class,
TokenMismatchException::class,
AuthenticationException::class,
ValidationException::class,
AuthorizationException::class,
Expand Down
13 changes: 9 additions & 4 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace App\Http;

use App\Http\Middleware\EncryptCookies;
use App\Http\Middleware\RedirectIfAuthenticated;
use App\Http\Middleware\UserAdmin;
use App\Http\Middleware\VerifyCsrfToken;
use Tymon\JWTAuth\Middleware\RefreshToken;
use Tymon\JWTAuth\Middleware\GetUserFromToken;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
Expand All @@ -11,7 +15,7 @@ class Kernel extends HttpKernel
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
* These middleware are run during every request to your apcplication.
*
* @var array
*/
Expand All @@ -27,11 +31,11 @@ class Kernel extends HttpKernel
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],

Expand All @@ -53,9 +57,10 @@ class Kernel extends HttpKernel
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'guest' => RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'jwt.auth' => GetUserFromToken::class,
'jwt.refresh' => RefreshToken::class,
'admin' => UserAdmin::class,
];
}
26 changes: 26 additions & 0 deletions app/Http/Middleware/UserAdmin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
/**
* Created by PhpStorm.
* User: Dave
* Date: 9/15/2018
* Time: 5:48 PM
*/

namespace App\Http\Middleware;


use Illuminate\Auth\Access\AuthorizationException;

class UserAdmin
{
public function handle($request, \Closure $next)
{
$user = auth()->guard()->user();

if (!$user->is_admin) {
throw new AuthorizationException("You are not allowed to access resource.");
}

return $next($request);
}
}
12 changes: 6 additions & 6 deletions config/imageupload.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@
'dimensions' => [
'square50' => [50, 50, true],
'square100' => [100, 100, true],
'square200' => [200, 200, true],
'square400' => [400, 400, true],
// 'square200' => [200, 200, true],
// 'square400' => [400, 400, true],

'size50' => [50, 50, false],
'size100' => [100, 100, false],
'size200' => [200, 200, false],
'size400' => [400, 400, false],
// 'size50' => [50, 50, false],
// 'size100' => [100, 100, false],
// 'size200' => [200, 200, false],
// 'size400' => [400, 400, false],
],

/*
Expand Down
Binary file added resources/apps/frontend/src/assets/avatar.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions resources/apps/frontend/src/components/Avatar/Avatar.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
:local(.small) {
width: 50px;
height: 50px;
border-radius: 50%;
}

:local(.medium) {
width: 100px;
height: 100px;
border-radius: 50%;
}
21 changes: 21 additions & 0 deletions resources/apps/frontend/src/components/Avatar/AvatarInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import Avatar from './';
import {Link} from 'react-router-dom';

export default class extends React.Component {
render() {
return (
<Link to={`/members/${this.props.id}`}>
<div className="float-left pr-2 d-flex align-items-center justify-content-end">
<Avatar src={this.props.avatar} />
</div>
<div className="float-left">
{this.props.name}
<div>
<span className="small text-muted">{this.props.email}</span>
</div>
</div>
</Link>
);
}
}
21 changes: 21 additions & 0 deletions resources/apps/frontend/src/components/Avatar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import avatar from './../../assets/avatar.jpg';
import styles from './Avatar.scss';

class Avatar extends React.Component {
static defaultProps = {
size: 'small',
src: '',
};

get src() {
if (!this.props.src) return avatar;
return this.props.src;
}

render() {
return <img src={this.src} alt="" className={styles[this.props.size]} />;
}
}

export default Avatar;
12 changes: 7 additions & 5 deletions resources/apps/frontend/src/pages/attendance/lists.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import {Card, CardBody, CardHeader} from 'reactstrap';
import {Link} from 'react-router-dom';
import {Table} from 'components/Table';
import TableActions from 'components/Table/TableActions';
import Confirm from 'components/Dialogs/Confirm';
Expand All @@ -12,6 +11,7 @@ import date from 'utils/date';
import getErrorMessage from 'utils/getErrorMessage';
import {loadAttendance, destroyAttendance} from 'requests/activities';
import Pagination from 'components/Pagination/PaginationWithFilter';
import AvatarInfo from 'components/Avatar/AvatarInfo';

class Component extends React.Component {
_isMounted = false;
Expand Down Expand Up @@ -106,10 +106,12 @@ class Component extends React.Component {
<tr key={item.id}>
<td>{item.id}</td>
<td>
<Link to={`/members/${item.user_id}`}>{item.name}</Link>
<div>
<span className="small text-muted">{item.email}</span>
</div>
<AvatarInfo
id={item.user_id}
avatar={item.avatar}
name={item.name}
email={item.email}
/>
</td>
<td className="align-center">{item.description}</td>
<td>{date(item.created_at)}</td>
Expand Down
15 changes: 8 additions & 7 deletions resources/apps/frontend/src/pages/dashboard/Attendance.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import {Link} from 'react-router-dom';
import {Table} from 'components/Table';
import notify from 'utils/notify';
import date from 'utils/date';
import getErrorMessage from 'utils/getErrorMessage';
import {loadAttendance} from 'requests/activities';
import AvatarInfo from 'components/Avatar/AvatarInfo';

class Component extends React.Component {
_isMounted = false;
Expand Down Expand Up @@ -43,18 +43,19 @@ class Component extends React.Component {
};

get headers() {
return ['ID', 'Name', 'Description', 'Date'];
return ['Name', 'Description', 'Date'];
}

renderItem = item => {
return (
<tr key={item.id}>
<td>{item.id}</td>
<td>
<Link to={`/members/${item.user_id}`}>{item.name}</Link>
<div>
<span className="small text-muted">{item.email}</span>
</div>
<AvatarInfo
id={item.user_id}
avatar={item.avatar}
name={item.name}
email={item.email}
/>
</td>
<td className="align-center">{item.description}</td>
<td>{date(item.created_at)}</td>
Expand Down
2 changes: 1 addition & 1 deletion resources/apps/frontend/src/pages/dashboard/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class Dashboard extends Component {
</Col>
<Col md={6}>
<Card className="mb-3">
<CardHeader>Login Member</CardHeader>
<CardHeader>New Attendance</CardHeader>
<CardBody>
<Form onSubmit={this.onSubmit}>
<Row>
Expand Down
64 changes: 63 additions & 1 deletion resources/apps/frontend/src/pages/members/form.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import React from 'react';
import get from 'lodash/get';
import serialize from 'form-serialize';
import {Form, FormGroup, Input, Label, Button, Row, Col} from 'reactstrap';
import {
Form,
FormGroup,
Input,
Label,
Button,
Row,
Col,
FormText,
} from 'reactstrap';

import BooleanSelect from 'components/Form/Select/BooleanSelect';
import getErrorMessage from 'utils/getErrorMessage';
import notify from 'utils/notify';
import Avatar from 'components/Avatar';
import {uploadAvatar} from 'requests/members';

export default class extends React.Component {
static defaultProps = {
Expand All @@ -15,6 +27,7 @@ export default class extends React.Component {

state = {
isSubmitting: false,
avatar: null,
};

onSubmit = async event => {
Expand All @@ -38,11 +51,60 @@ export default class extends React.Component {
}
};

get avatar() {
if (this.state.avatar) return this.state.avatar;
return this.props.avatar;
}

onChangeFile = async event => {
try {
const files = event.target.files;
if (files.length === 0) return;

const file = files[0];

this.setState({isSubmitting: true});

const data = new FormData();

data.append('file', file);

const response = await uploadAvatar(data);

const path = get(response, 'dimensions.square50.filedir');
const avatar = `${process.env.APP_API_URL}/${path.substring(1)}`;

this.setState({isSubmitting: false, avatar});
} catch (err) {
alert(err.message);
this.setState({isSubmitting: false});
}
};

render() {
return (
<Form onSubmit={this.onSubmit}>
<FormGroup>
<Row>
<div className="float-left pl-3 pr-3 d-flex align-items-center justify-content-end">
<Avatar src={this.avatar} />
</div>
<div className="float-left">
<Label for="exampleFile">Avatar</Label>
<Input
type="file"
name="file"
id="file"
onChange={this.onChangeFile}
accept="image/*"
/>
<FormText color="muted">You must select only images</FormText>
</div>
</Row>
</FormGroup>
<Row>
<Col md={6}>
<Input type="hidden" name="avatar" defaultValue={this.avatar} />
<FormGroup>
<Label for="name">Name</Label>
<Input
Expand Down
8 changes: 3 additions & 5 deletions resources/apps/frontend/src/pages/members/lists.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import {Card, CardBody, CardHeader} from 'reactstrap';
import {Link} from 'react-router-dom';
import {Table} from 'components/Table';

import TableActions from 'components/Table/TableActions';
import Confirm from 'components/Dialogs/Confirm';
import Loader from 'components/Loader';
Expand All @@ -12,6 +12,7 @@ import date from 'utils/date';
import getErrorMessage from 'utils/getErrorMessage';
import {loadMembers, destroyMember} from 'requests/members';
import Pagination from 'components/Pagination/PaginationWithFilter';
import AvatarInfo from 'components/Avatar/AvatarInfo';

class Component extends React.Component {
_isMounted = false;
Expand Down Expand Up @@ -105,10 +106,7 @@ class Component extends React.Component {
<tr key={item.id}>
<td>{item.id}</td>
<td>
<Link to={`/members/${item.id}`}>{item.name}</Link>
<div>
<span className="small text-muted">{item.email}</span>
</div>
<AvatarInfo {...item} />
</td>
<td className="align-center">{item.account_number}</td>
<td className="align-center text-center">
Expand Down
Loading

0 comments on commit be9cf3a

Please sign in to comment.