finish register special
This commit is contained in:
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
34
app/Http/Controllers/UserController.php
Normal file
34
app/Http/Controllers/UserController.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\User;
|
||||
use App\Http\Resources\User as UserResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function store()
|
||||
{
|
||||
$this->authorize('create', User::class);
|
||||
|
||||
request()['password'] = Hash::make(Str::random(30));
|
||||
$user = User::create($this->validateData());
|
||||
|
||||
return (new UserResource($user))
|
||||
->response()
|
||||
->setStatusCode(Response::HTTP_CREATED);
|
||||
}
|
||||
|
||||
private function validateData()
|
||||
{
|
||||
return request()->validate([
|
||||
'name' => 'required',
|
||||
'email' => 'required|email',
|
||||
'password' => 'required'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ class User extends JsonResource
|
||||
'user_id' => $this->id,
|
||||
'attributes' => [
|
||||
'name' => $this->name,
|
||||
'email' => $this->email,
|
||||
'is_admin' => $this->isAdmin(),
|
||||
],
|
||||
],
|
||||
'links' => [
|
||||
|
||||
93
app/Policies/UserPolicy.php
Normal file
93
app/Policies/UserPolicy.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function viewAny(User $user)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function view(User $user, User $model)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(User $user)
|
||||
{
|
||||
return $user->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(User $user, User $model)
|
||||
{
|
||||
return $user->isAdmin() || $user->id === auth()->user()->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete(User $user, User $model)
|
||||
{
|
||||
return $user->isAdmin() || $user->id === auth()->user()->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function restore(User $user, User $model)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceDelete(User $user, User $model)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Model' => 'App\Policies\ModelPolicy',
|
||||
'App\User' => 'App\Policies\UserPolicy',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,4 +37,9 @@ class User extends Authenticatable
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function isAdmin()
|
||||
{
|
||||
return $this->role === 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'locale' => 'en',
|
||||
'locale' => 'fr',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -17,6 +17,8 @@ class CreateUsersTable extends Migration
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->tinyInteger('role')->default(0);
|
||||
$table->string('photo')->nullable();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
|
||||
137
public/css/app.css
vendored
137
public/css/app.css
vendored
@@ -2,13 +2,34 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div,
|
||||
input,
|
||||
nav,
|
||||
aside {
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
}
|
||||
@@ -46,7 +67,7 @@ body {
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-end {
|
||||
@@ -73,6 +94,62 @@ body {
|
||||
padding-right: auto;
|
||||
}
|
||||
|
||||
.m-0 {
|
||||
margin: 0rem;
|
||||
}
|
||||
|
||||
.mx-0 {
|
||||
margin-left: 0rem;
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.my-0 {
|
||||
margin-top: 0rem;
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.mt-0 {
|
||||
margin-top: 0rem;
|
||||
}
|
||||
|
||||
.ml-0 {
|
||||
margin-left: 0rem;
|
||||
}
|
||||
|
||||
.mr-0 {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.mb-0 {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.p-0 {
|
||||
padding: 0rem;
|
||||
}
|
||||
|
||||
.px-0 {
|
||||
padding-left: 0rem;
|
||||
padding-right: 0rem;
|
||||
}
|
||||
|
||||
.py-0 {
|
||||
padding-top: 0rem;
|
||||
padding-bottom: 0rem;
|
||||
}
|
||||
|
||||
.pt-0 {
|
||||
padding-top: 0rem;
|
||||
}
|
||||
|
||||
.pl-0 {
|
||||
padding-left: 0rem;
|
||||
}
|
||||
|
||||
.pb-0 {
|
||||
padding-bottom: 0rem;
|
||||
}
|
||||
|
||||
.m-1 {
|
||||
margin: 1rem;
|
||||
}
|
||||
@@ -453,6 +530,56 @@ aside {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #1F2605;
|
||||
border-radius: 50%;
|
||||
color: #D6CE15;
|
||||
font-weight: bold;
|
||||
text-underline: none;
|
||||
}
|
||||
|
||||
.avatar-small {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.avatar-medium {
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
font-size: 3.3333333333rem;
|
||||
}
|
||||
|
||||
.avatar-large {
|
||||
width: 8rem;
|
||||
height: 8rem;
|
||||
font-size: 5.3333333333rem;
|
||||
}
|
||||
|
||||
.alert-box,
|
||||
.alert-error,
|
||||
.alert-success {
|
||||
border: 1px solid #53900F;
|
||||
color: #53900F;
|
||||
font-weight: bold;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
border-color: green;
|
||||
background-color: green;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
border-color: red;
|
||||
background-color: red;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.auth {
|
||||
max-width: 350px;
|
||||
width: 100%;
|
||||
|
||||
1477
public/js/app.js
vendored
1477
public/js/app.js
vendored
File diff suppressed because it is too large
Load Diff
10
resources/js/components/AlertBox.vue
Normal file
10
resources/js/components/AlertBox.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div v-bind:class="'alert-' + type" class="p-1">{{ message }}</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AlertBox",
|
||||
props: ['type', 'message']
|
||||
}
|
||||
</script>
|
||||
@@ -3,7 +3,9 @@
|
||||
<Nav />
|
||||
<div class="flex">
|
||||
<SideBar />
|
||||
<router-view class="main"></router-view>
|
||||
<main>
|
||||
<router-view class="main"></router-view>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
14
resources/js/components/Avatar.vue
Normal file
14
resources/js/components/Avatar.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<img v-if="avatar" src="avatar" alt="alt" class="avatar" v-bind:class="'avatar' + size">
|
||||
<span v-else class="avatar" v-bind:class="'avatar-' + size">{{ alt[0] }}</span>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Avatar",
|
||||
props: ['avatar', 'alt', 'size']
|
||||
}
|
||||
</script>
|
||||
53
resources/js/components/InputField.vue
Normal file
53
resources/js/components/InputField.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div class="relative">
|
||||
<label :for="name" class="pb-1">{{ label }}</label>
|
||||
<input :id="name" :type="type" :placeholder="placeholder" v-model="value" @input="updateField()" :class="errorClassObject()">
|
||||
<p class="text-alert" v-text="errorMessage()">Error Here</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "InputField",
|
||||
props: [
|
||||
'name', 'type', 'label', 'placeholder', 'errors', 'data',
|
||||
],
|
||||
data: function () {
|
||||
return {
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasError: function () {
|
||||
return this.errors && this.errors[this.name] && this.errors[this.name].length > 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateField: function () {
|
||||
this.clearErrors(this.name)
|
||||
this.$emit('update:field', this.value)
|
||||
},
|
||||
errorMessage: function () {
|
||||
if (this.hasError) {
|
||||
return this.errors[this.name][0]
|
||||
}
|
||||
},
|
||||
clearErrors: function () {
|
||||
if (this.hasError) {
|
||||
this.errors[this.name] = null
|
||||
}
|
||||
},
|
||||
errorClassObject: function () {
|
||||
return {
|
||||
'error-field': this.hasError
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: function (val) {
|
||||
this.value = val
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,32 +1,56 @@
|
||||
<template>
|
||||
<nav class="flex-between flex-center py-1 px-2">
|
||||
<router-link to="/">Logo</router-link>
|
||||
<router-link v-if="authUser" :to="'/users/' + authUser.data.user_id">Me</router-link>
|
||||
<router-link v-if="authUser" :to="'/profil'" class="flex-center">
|
||||
<Avatar :avatar="authUser.data.attributes.avatar" size="small" :alt="authUser.data.attributes.name" class="mr-1"/>
|
||||
{{ authUser.data.attributes.name }}
|
||||
</router-link>
|
||||
<form v-if="authUser">
|
||||
<input type="search" name="search" placeholder="Search">
|
||||
<input type="submit" value="S">
|
||||
</form>
|
||||
<router-link to="/connexion">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-current site-logo"><path d="M22.9 10.1c-.1-.1-.2-.2-.3-.2L20 9.5c-.1-.5-.3-.9-.6-1.4.2-.2.4-.6.8-1 .3-.4.6-.8.7-1 .1 0 .1-.2.1-.3 0-.1 0-.2-.1-.3-.3-.5-1.1-1.3-2.4-2.4-.1-.1-.2-.1-.4-.1-.1 0-.3 0-.3.1l-2 1.5c-.4-.2-.8-.4-1.3-.5l-.4-2.6c0-.1-.1-.2-.2-.3-.1-.2-.2-.2-.3-.2h-3.2c-.3 0-.4.1-.5.4-.1.5-.3 1.4-.4 2.7-.5.1-.9.3-1.3.5l-2-1.5c-.1-.1-.3-.2-.4-.2-.2 0-.7.3-1.4 1-.6.7-1.1 1.3-1.4 1.6-.1.1-.1.2-.1.3 0 .1 0 .2.1.3.6.8 1.2 1.4 1.5 2-.2.5-.3.9-.5 1.4l-2.6.4c-.1 0-.2.1-.3.2-.1.1-.1.2-.1.3v3.2c0 .1 0 .2.1.3.1.1.2.2.3.2l2.6.4c.1.5.3.9.6 1.4-.2.2-.4.6-.8 1-.3.4-.6.8-.7 1-.1.1-.1.2-.1.3 0 .1 0 .2.1.3.4.5 1.2 1.3 2.4 2.4.1.1.2.2.4.2.1 0 .3 0 .4-.1l2-1.5c.3.1.7.3 1.2.5l.4 2.6c0 .1.1.2.2.3.1.1.2.1.4.1h3.2c.3 0 .4-.1.5-.4.1-.5.3-1.4.4-2.7.4-.1.9-.3 1.3-.5l2 1.5c.1.1.3.1.4.1.2 0 .7-.3 1.3-1 .7-.7 1.2-1.2 1.4-1.5.1-.1.1-.2.1-.3 0-.1 0-.2-.1-.4-.7-.8-1.2-1.5-1.5-2 .2-.4.4-.8.6-1.3l2.7-.4c.1 0 .2-.1.3-.2.1-.1.1-.2.1-.3v-3.2c-.2-.1-.2-.2-.3-.3zm-8.3 4.5c-.7.7-1.6 1.1-2.6 1.1s-1.9-.4-2.6-1.1c-.7-.7-1.1-1.6-1.1-2.6s.4-1.9 1.1-2.6c.7-.7 1.6-1.1 2.6-1.1s1.9.4 2.6 1.1c.7.7 1.1 1.6 1.1 2.6s-.4 1.9-1.1 2.6z"/></svg>
|
||||
</router-link>
|
||||
<div>
|
||||
<router-link to="/dashboard">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-current site-logo">
|
||||
<title>Paramètres</title>
|
||||
<path d="M22.9 10.1c-.1-.1-.2-.2-.3-.2L20 9.5c-.1-.5-.3-.9-.6-1.4.2-.2.4-.6.8-1 .3-.4.6-.8.7-1 .1 0 .1-.2.1-.3 0-.1 0-.2-.1-.3-.3-.5-1.1-1.3-2.4-2.4-.1-.1-.2-.1-.4-.1-.1 0-.3 0-.3.1l-2 1.5c-.4-.2-.8-.4-1.3-.5l-.4-2.6c0-.1-.1-.2-.2-.3-.1-.2-.2-.2-.3-.2h-3.2c-.3 0-.4.1-.5.4-.1.5-.3 1.4-.4 2.7-.5.1-.9.3-1.3.5l-2-1.5c-.1-.1-.3-.2-.4-.2-.2 0-.7.3-1.4 1-.6.7-1.1 1.3-1.4 1.6-.1.1-.1.2-.1.3 0 .1 0 .2.1.3.6.8 1.2 1.4 1.5 2-.2.5-.3.9-.5 1.4l-2.6.4c-.1 0-.2.1-.3.2-.1.1-.1.2-.1.3v3.2c0 .1 0 .2.1.3.1.1.2.2.3.2l2.6.4c.1.5.3.9.6 1.4-.2.2-.4.6-.8 1-.3.4-.6.8-.7 1-.1.1-.1.2-.1.3 0 .1 0 .2.1.3.4.5 1.2 1.3 2.4 2.4.1.1.2.2.4.2.1 0 .3 0 .4-.1l2-1.5c.3.1.7.3 1.2.5l.4 2.6c0 .1.1.2.2.3.1.1.2.1.4.1h3.2c.3 0 .4-.1.5-.4.1-.5.3-1.4.4-2.7.4-.1.9-.3 1.3-.5l2 1.5c.1.1.3.1.4.1.2 0 .7-.3 1.3-1 .7-.7 1.2-1.2 1.4-1.5.1-.1.1-.2.1-.3 0-.1 0-.2-.1-.4-.7-.8-1.2-1.5-1.5-2 .2-.4.4-.8.6-1.3l2.7-.4c.1 0 .2-.1.3-.2.1-.1.1-.2.1-.3v-3.2c-.2-.1-.2-.2-.3-.3zm-8.3 4.5c-.7.7-1.6 1.1-2.6 1.1s-1.9-.4-2.6-1.1c-.7-.7-1.1-1.6-1.1-2.6s.4-1.9 1.1-2.6c.7-.7 1.6-1.1 2.6-1.1s1.9.4 2.6 1.1c.7.7 1.1 1.6 1.1 2.6s-.4 1.9-1.1 2.6z"/>
|
||||
</svg>
|
||||
</router-link>
|
||||
<a href="#" @click.prevent="logout" class="nav-link">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-current site-logo">
|
||||
<title>Déconnexion</title>
|
||||
<path d="M21 3h-3.8c-.7 0-1.3-.6-1.3-1.3S16.5.4 17.2.4h5.1c.7 0 1.3.6 1.3 1.3v20.5c0 .7-.6 1.3-1.3 1.3h-5.1c-.7 0-1.3-.6-1.3-1.3 0-.7.6-1.3 1.3-1.3H21V3zm-6.9 7.7L8.6 5.2c-.5-.5-.6-1.3-.1-1.8s1.3-.5 1.8 0l7.7 7.7c.8.8.2 2.2-.9 2.2H1.8c-.7 0-1.3-.6-1.3-1.3 0-.7.6-1.3 1.3-1.3h12.3zm-1.6 4.8c.5-.5 1.3-.4 1.8.1s.4 1.3-.1 1.8l-3.8 3.2c-.5.5-1.3.4-1.8-.1-.6-.5-.5-1.3 0-1.7l3.9-3.3z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import Avatar from "./Avatar";
|
||||
|
||||
export default {
|
||||
name: "Nav",
|
||||
components: {
|
||||
Avatar
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
authUser: 'authUser'
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
// axios.get('/api/auth-user')
|
||||
// .then(res => {
|
||||
// this.user = res.data
|
||||
// })
|
||||
methods: {
|
||||
logout: function () {
|
||||
axios.post('logout')
|
||||
.then(res => {
|
||||
if(res.status ===302 || 401) {
|
||||
window.location.href = '/login'
|
||||
}
|
||||
}).catch(error => {
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
17
resources/js/router.js
vendored
17
resources/js/router.js
vendored
@@ -1,7 +1,9 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import Home from "./views/Home"
|
||||
// import UserShow from "./views/Users/Show"
|
||||
import Profil from "./views/User/UserProfil";
|
||||
import DashBoard from "./views/DashBoard";
|
||||
import CssTesteur from "./views/CssTesteur";
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
@@ -13,5 +15,18 @@ export default new VueRouter({
|
||||
path: '/', name: 'home', component: Home,
|
||||
meta: { title: 'Home'}
|
||||
},
|
||||
{
|
||||
path: '/profil', name: 'profil', component: Profil,
|
||||
meta: { title: 'Profil'}
|
||||
},
|
||||
{
|
||||
path: '/dashboard', name: 'dashboard', component: DashBoard,
|
||||
meta: { title: 'Dashboard'}
|
||||
},
|
||||
|
||||
{
|
||||
path: '/css-testeur', name: 'css-testeur', component: CssTesteur,
|
||||
meta: { title: 'css-testeur'}
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
42
resources/js/views/CssTesteur.vue
Normal file
42
resources/js/views/CssTesteur.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="m-2">
|
||||
<h1>testeur CSS</h1>
|
||||
<h2>testeur CSS</h2>
|
||||
<h3>testeur CSS</h3>
|
||||
<h4>testeur CSS</h4>
|
||||
<h5>testeur CSS</h5>
|
||||
<h6>testeur CSS</h6>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
|
||||
<p>Lorem ipsum dolor sit amet, <strong>consectetur adipiscing elit</strong>, sed do <italic>eiusmod tempor incididunt</italic> ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
|
||||
<div class="py-1">
|
||||
<a href="#" class="btn">Boutton</a>
|
||||
<a href="#" class="btn-primary">Boutton primary</a>
|
||||
<a href="#" class="btn-secondary">Boutton secondary</a>
|
||||
<a href="#" class="btn-alert">Boutton alert</a>
|
||||
</div>
|
||||
<div class="py-1">
|
||||
<a href="#" class="btn">X</a>
|
||||
<a href="#" class="btn-primary">X</a>
|
||||
<a href="#" class="btn-secondary">X</a>
|
||||
<a href="#" class="btn-alert">X</a>
|
||||
</div>
|
||||
<form>
|
||||
<label>Test label</label>
|
||||
<input type="text" placeholder="Test placeholder">
|
||||
<input type="number">
|
||||
<input type="checkbox">
|
||||
<select>
|
||||
<option>test 1</option>
|
||||
<option>test 2</option>
|
||||
<option>test 3</option>
|
||||
</select>
|
||||
<input type="submit">
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "CssTesteur"
|
||||
}
|
||||
</script>
|
||||
20
resources/js/views/DashBoard.vue
Normal file
20
resources/js/views/DashBoard.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div class="m-2">
|
||||
<div class="flex-between">
|
||||
<h1 class="mb-3">Administration</h1>
|
||||
<router-link to="/logout">Déconnexion</router-link>
|
||||
</div>
|
||||
<UserAdmin />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserAdmin from "./User/UserAdmin";
|
||||
|
||||
export default {
|
||||
name: "DashBoard",
|
||||
components: {
|
||||
UserAdmin
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<h1>Home</h1>
|
||||
<div>
|
||||
<h1>Home</h1>
|
||||
<router-link to="/css-testeur">Css Testeur</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
76
resources/js/views/User/UserAdmin.vue
Normal file
76
resources/js/views/User/UserAdmin.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex mb-4">
|
||||
<div class="avatar mr-2">
|
||||
<Avatar :avatar="authUser.data.attributes.avatar" size="large" :alt="authUser.data.attributes.name" />
|
||||
</div>
|
||||
<div class="flex-col flex-center">
|
||||
<div><strong>{{ authUser.data.attributes.name }}</strong></div>
|
||||
<div><strong>{{ authUser.data.attributes.email }}</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="authUser.data.attributes.is_admin">
|
||||
<h2 class="mb-1">Ajouter un membre</h2>
|
||||
<AlertBox v-if="alertType" :type="alertType" :message="alertMessage" class="mb-1" />
|
||||
<form @submit.prevent="addMember">
|
||||
<InputField name="name" type="text" label="Nom du nouveau membre" placeholder="Nom" @update:field="form.name = $event" :errors="errors" />
|
||||
<InputField name="email" type="email" label="Adresse email du nouveau membre" placeholder="E-mail" @update:field="form.email = $event" :errors="errors" />
|
||||
<button>Ajouter</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import Avatar from "../../components/Avatar";
|
||||
import AlertBox from "../../components/AlertBox";
|
||||
import InputField from "../../components/InputField";
|
||||
|
||||
export default {
|
||||
name: "UserAdmin",
|
||||
components: {
|
||||
Avatar, AlertBox, InputField,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
email: '',
|
||||
},
|
||||
alertType: '',
|
||||
alertMessage: '',
|
||||
errors: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
authUser: 'authUser',
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
addMember: function () {
|
||||
console.log('addMember')
|
||||
if(this.form.name.length <= 4 && this.form.name.email <= 12) {
|
||||
axios.post('/api/users', {name: this.form.name, email: this.form.email})
|
||||
.then(res => {
|
||||
console.log(res)
|
||||
this.form.name = ''
|
||||
this.form.email = ''
|
||||
this.alertType = 'success'
|
||||
this.alertMessage = `${res.data.data.attributes.name} a bien été créé`
|
||||
})
|
||||
.catch(errors => {
|
||||
console.log(errors)
|
||||
this.alertType = 'error'
|
||||
this.alertMessage = `L'utilisateur n'a pas été créé`
|
||||
})
|
||||
} else {
|
||||
this.alertType = 'error'
|
||||
this.alertMessage = `Le formulaire n'est pas correctement renseigné.`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
18
resources/js/views/User/UserProfil.vue
Normal file
18
resources/js/views/User/UserProfil.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>{{ authUser.data.attributes.name }}</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "Profil",
|
||||
computed: {
|
||||
...mapGetters({
|
||||
authUser: 'authUser',
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
13
resources/lang/fr/auth.php
Normal file
13
resources/lang/fr/auth.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'failed' => 'Ces informations d\'identification ne correspondent pas à nos dossier',
|
||||
'throttle' => 'Trop de tentatives de connexion. Merci de réessayer dans :seconds secondes.',
|
||||
'Login' => 'Connexion',
|
||||
'E-Mail' => 'E-Mail',
|
||||
'Password' => 'Mot de passe',
|
||||
'Remember Me' => 'Se souvenir de moi',
|
||||
'Forgot Your Password?' => 'Mot de passe oublié ?',
|
||||
|
||||
];
|
||||
9
resources/lang/fr/passwords.php
Normal file
9
resources/lang/fr/passwords.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'reset' => 'Votre mot de passe à été mis à jour!',
|
||||
'sent' => 'Nous vous avons envoyé un email content un lien pour changer de mote de passe!',
|
||||
'throttled' => 'Attendez avec d\' essayer à nouveau.',
|
||||
'token' => 'Ce token de mot de passe est invalide.',
|
||||
'user' => "Nous n'avons pas trouvé un utilisateur avec cette adresse email.",
|
||||
];
|
||||
7
resources/lang/fr/validation.php
Normal file
7
resources/lang/fr/validation.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'exists' => 'La sélection :attribute est invalide.',
|
||||
'file' => 'Le :attribute doit être un fichier.',
|
||||
];
|
||||
2
resources/sass/app.scss
vendored
2
resources/sass/app.scss
vendored
@@ -11,5 +11,7 @@
|
||||
@import "components/main";
|
||||
@import "components/nav";
|
||||
@import "components/sidebar";
|
||||
@import "components/avatar";
|
||||
@import "components/alert_box";
|
||||
|
||||
@import "pages/auth";
|
||||
|
||||
21
resources/sass/components/alert_box.scss
vendored
Normal file
21
resources/sass/components/alert_box.scss
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
.alert-box {
|
||||
border: 1px solid $medium;
|
||||
color: $medium;
|
||||
font-weight: bold;
|
||||
border-radius: 3px;
|
||||
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
@extend .alert-box;
|
||||
border-color: $success;
|
||||
background-color: $success;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
@extend .alert-box;
|
||||
border-color: $error;
|
||||
background-color: $error;
|
||||
color: $white;
|
||||
}
|
||||
31
resources/sass/components/avatar.scss
vendored
Normal file
31
resources/sass/components/avatar.scss
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
.avatar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: $dark;
|
||||
border-radius: 50%;
|
||||
color: $light;
|
||||
font-weight: bold;
|
||||
text-underline: none;
|
||||
|
||||
&-small {
|
||||
$size: 3rem;
|
||||
width: $size;
|
||||
height: $size;
|
||||
font-size: $size *2/3;
|
||||
}
|
||||
|
||||
&-medium {
|
||||
$size: 5rem;
|
||||
width: $size;
|
||||
height: $size;
|
||||
font-size: $size *2/3;
|
||||
}
|
||||
|
||||
&-large {
|
||||
$size: 8rem;
|
||||
width: $size;
|
||||
height: $size;
|
||||
font-size: $size *2/3;
|
||||
}
|
||||
}
|
||||
3
resources/sass/setup/_colors.scss
vendored
3
resources/sass/setup/_colors.scss
vendored
@@ -17,7 +17,8 @@ $light: #D6CE15;
|
||||
$primary: $mediumDark;
|
||||
$secondary: #000;
|
||||
$interactive: #000;
|
||||
$error: #000;
|
||||
$success: green;
|
||||
$error: red;
|
||||
$disabled: #000;
|
||||
|
||||
$font: $black;
|
||||
|
||||
4
resources/sass/setup/_positions.scss
vendored
4
resources/sass/setup/_positions.scss
vendored
@@ -29,7 +29,7 @@ $base: 1rem;
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-end {
|
||||
@@ -56,7 +56,7 @@ $base: 1rem;
|
||||
padding-right: auto;
|
||||
}
|
||||
|
||||
@for $i from 1 through 5 {
|
||||
@for $i from 0 through 5 {
|
||||
.m-#{$i} {
|
||||
margin: $i * $base;
|
||||
}
|
||||
|
||||
10
resources/sass/setup/_reset.scss
vendored
10
resources/sass/setup/_reset.scss
vendored
@@ -4,10 +4,12 @@ body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div,
|
||||
input,
|
||||
nav,
|
||||
aside {
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@for $i from 1 through 6 {
|
||||
h#{$i} {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +1,51 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Login') }}</div>
|
||||
<div class="auth p-2">
|
||||
<div class="title-page mb-2">{{ __('Login') }}</div>
|
||||
<form method="POST" action="{{ route('login') }}">
|
||||
@csrf
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('login') }}">
|
||||
@csrf
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
|
||||
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||
|
||||
<label class="form-check-label" for="remember">
|
||||
{{ __('Remember Me') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ __('Login') }}
|
||||
</button>
|
||||
|
||||
@if (Route::has('password.request'))
|
||||
<a class="btn btn-link" href="{{ route('password.request') }}">
|
||||
{{ __('Forgot Your Password?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<label for="email" class="mb-1">{{ __('E-Mail') }}</label>
|
||||
<div class="mb-2">
|
||||
<input id="email" type="email" class="@error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="password" class="mb-1">{{ __('Password') }}</label>
|
||||
<div class="mb-2">
|
||||
<input id="password" type="password" class="@error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
|
||||
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<input type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||
|
||||
<label for="remember" class="inline">
|
||||
{{ __('Remember Me') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="flex-between">
|
||||
<button type="submit" class="btn-primary px-3">
|
||||
{{ __('Login') }}
|
||||
</button>
|
||||
@if (Route::has('password.request'))
|
||||
<a class="btn-secondary" href="{{ route('password.request') }}">
|
||||
{{ __('Forgot Your Password?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -17,4 +17,11 @@ use Illuminate\Support\Facades\Route;
|
||||
Route::middleware('auth:api')->group(function () {
|
||||
|
||||
Route::get('auth-user', 'AuthUserController@show');
|
||||
|
||||
Route::apiResources([
|
||||
// '/posts' => 'PostController',
|
||||
'/users' => 'UserController',
|
||||
// '/users/{user}/posts' => 'UserPostController',
|
||||
// '/friend-request' => 'FriendRequestController',
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Auth::routes();
|
||||
Auth::routes(['register' => false]);
|
||||
|
||||
Route::get('{any}', 'AppController@index')
|
||||
->where('any', '.*')
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Tests\Feature;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UserAuthTest extends TestCase
|
||||
@@ -19,7 +20,7 @@ class UserAuthTest extends TestCase
|
||||
|
||||
$response = $this->get('/api/auth-user');
|
||||
|
||||
$response->assertStatus(200)
|
||||
$response->assertStatus(Response::HTTP_OK)
|
||||
->assertJson([
|
||||
'data' => [
|
||||
'user_id' => $user->id,
|
||||
@@ -32,4 +33,30 @@ class UserAuthTest extends TestCase
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function an_admin_can_add_member()
|
||||
{
|
||||
$this->actingAs($user = factory(User::class)->create(['role' => 2]), 'api');
|
||||
|
||||
$response = $this->post('/api/users', [
|
||||
'name' => 'TestName',
|
||||
'email' => 'test@test.fr',
|
||||
])->assertStatus(Response::HTTP_CREATED);
|
||||
|
||||
$this->assertCount(2, User::all());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function a_non_admin_cant_add_member()
|
||||
{
|
||||
$this->actingAs($user = factory(User::class)->create(), 'api');
|
||||
|
||||
$response = $this->post('/api/users', [
|
||||
'name' => 'TestName',
|
||||
'email' => 'test@test.fr',
|
||||
])->assertStatus(Response::HTTP_FORBIDDEN);
|
||||
|
||||
$this->assertCount(1, User::all());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user