mirror of
https://github.com/brunofontes/shareit.git
synced 2025-04-04 11:20:53 +00:00
Compare commits
No commits in common. "v0.1" and "master" have entirely different histories.
7
.gitignore
vendored
7
.gitignore
vendored
@ -5,13 +5,8 @@
|
||||
/vendor
|
||||
/.idea
|
||||
/.vscode
|
||||
/.vagrant
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
.env
|
||||
.phpunit.result.cache
|
||||
mergeAndDeploy.sh
|
||||
start_vagrant.sh
|
||||
ssh_homestead.sh
|
||||
tags
|
||||
|
53
app/Events/RefreshPage.php
Normal file
53
app/Events/RefreshPage.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use \App\Item;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class RefreshPage implements ShouldBroadcastNow
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Item
|
||||
*
|
||||
* @var Item
|
||||
*/
|
||||
public $item;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Item $item)
|
||||
{
|
||||
$this->item = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return ['touchedItem'];
|
||||
}
|
||||
|
||||
public function broadcastAs()
|
||||
{
|
||||
return 'RefreshPage';
|
||||
}
|
||||
|
||||
}
|
50
app/Events/ReturnItem.php
Normal file
50
app/Events/ReturnItem.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use \App\Item;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ReturnItem
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
|
||||
/**
|
||||
* Item
|
||||
*
|
||||
* @var Item
|
||||
*/
|
||||
public $item;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param Item $item The returned item.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Item $item)
|
||||
{
|
||||
$this->item = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('touchedItem');
|
||||
}
|
||||
|
||||
public function broadcastAs()
|
||||
{
|
||||
return 'ReturnItem';
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
@ -32,7 +33,7 @@ class Handler extends ExceptionHandler
|
||||
* @param \Exception $exception
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
parent::report($exception);
|
||||
}
|
||||
@ -44,7 +45,7 @@ class Handler extends ExceptionHandler
|
||||
* @param \Exception $exception
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
|
11
app/FlashMessage.php
Normal file
11
app/FlashMessage.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FlashMessage extends Model
|
||||
{
|
||||
const PRIMARY = 'primary';
|
||||
const DANGER = 'danger';
|
||||
}
|
@ -2,24 +2,46 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use \App\User;
|
||||
use \App\Mail\UserWaiting;
|
||||
use \App\User;
|
||||
use App\FlashMessage;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Mail;
|
||||
|
||||
class AlertController extends Controller
|
||||
{
|
||||
/**
|
||||
* Store the waiting_user_id on db
|
||||
* so the user can be alerted when
|
||||
* the item is free
|
||||
*
|
||||
* @param Request $request Form data
|
||||
*
|
||||
* @return redirect to home
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$item = User::loggedIn()->items()->find(request('item'));
|
||||
$item->waiting_user_id = \Auth::id();
|
||||
$item->timestamps = false;
|
||||
$item->save();
|
||||
if (!$item->used_by) {
|
||||
session()->flash(
|
||||
FlashMessage::PRIMARY,
|
||||
__('Oh! This item has just being returned. Take it before anyone else!')
|
||||
);
|
||||
return redirect('home');
|
||||
}
|
||||
|
||||
$loggedUser = \Auth::user()->name;
|
||||
if ($item->used_by == Auth::id()) {
|
||||
return redirect('home');
|
||||
}
|
||||
|
||||
$item->storeAlert();
|
||||
|
||||
$loggedUser = Auth::user()->name;
|
||||
$userWithItem = User::find($item->used_by);
|
||||
\Mail::to($userWithItem)->send(
|
||||
new UserWaiting($loggedUser, $userWithItem->name, $item)
|
||||
);
|
||||
Mail::to($userWithItem)
|
||||
->locale($userWithItem->language)
|
||||
->send(new UserWaiting($loggedUser, $userWithItem->name, $item));
|
||||
|
||||
return redirect('home');
|
||||
}
|
||||
@ -27,10 +49,12 @@ class AlertController extends Controller
|
||||
public function delete(Request $request)
|
||||
{
|
||||
$item = User::loggedIn()->items()->find(request('item'));
|
||||
$item->waiting_user_id = null;
|
||||
$item->timestamps = false;
|
||||
$item->save();
|
||||
|
||||
if ($item->waiting_user_id != Auth::id()) {
|
||||
return redirect('home');
|
||||
}
|
||||
|
||||
$item->removeAlert();
|
||||
return redirect('home');
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\User;
|
||||
use App\Mail\Welcome;
|
||||
use App\FlashMessage;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Mail\Welcome;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Mail;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
@ -70,7 +72,15 @@ class RegisterController extends Controller
|
||||
'password' => Hash::make($data['password']),
|
||||
]);
|
||||
|
||||
\Mail::to($user)->send(new Welcome($user));
|
||||
Mail::to($user)->send(new Welcome($user));
|
||||
|
||||
$text = "Share it! New user: {$user->name} ($user->email)";
|
||||
Mail::raw($text, function ($message) use ($text) {
|
||||
$message->to('brunofontes.shareit@mailnull.com');
|
||||
$message->subject($text);
|
||||
});
|
||||
|
||||
session()->flash(FlashMessage::PRIMARY, __('Thanks for registering. Please, do not forget to validate your e-mail address.'));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class VerificationController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
|
@ -3,10 +3,11 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use \App\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
protected $activeUsers = [];
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
@ -17,12 +18,56 @@ class HomeController extends Controller
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$items = User::loggedIn()->items()->with('users')->get();
|
||||
|
||||
$numberOfUsedItems = 0;
|
||||
foreach ($items as $item) {
|
||||
if (isset($item->used_by)) {
|
||||
$numberOfUsedItems++;
|
||||
}
|
||||
$this->getUsername($item->users, $item->used_by);
|
||||
$this->getUsername($item->users, $item->waiting_user_id);
|
||||
}
|
||||
|
||||
$products = $items
|
||||
->sortBy('product.name', SORT_NATURAL | SORT_FLAG_CASE)
|
||||
->groupBy('product.name');
|
||||
|
||||
return view(
|
||||
'home',
|
||||
['products' => $products, 'users' => $this->activeUsers, 'usedItems' => $numberOfUsedItems]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the username from an specified user id.
|
||||
*
|
||||
* @param object $itemUsers Array with IDs and usernames
|
||||
* @param int $id The user id to search for
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function getUsername(\Illuminate\Database\Eloquent\Collection $itemUsers, ?int $id)
|
||||
{
|
||||
if ($id && !isset($this->activeUsers[$id])) {
|
||||
$this->activeUsers[$id] = $this->findName($itemUsers, $id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a name from a specific id in a array
|
||||
*
|
||||
*
|
||||
* @param array $array The array of objects with ID and Names
|
||||
* @param int $id The ID of the user
|
||||
*
|
||||
*
|
||||
* @return string The username of the specified id
|
||||
*/
|
||||
protected function findName($array, $id)
|
||||
@ -33,26 +78,4 @@ class HomeController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$users = [];
|
||||
$items = User::loggedIn()->items()->with('users')->get();
|
||||
|
||||
foreach ($items as $item) {
|
||||
if ($item->used_by && !isset($users[$item->used_by])) {
|
||||
$users[$item->used_by] = $this->findName($item->users, $item->used_by);
|
||||
}
|
||||
|
||||
if ($item->waiting_user_id && !isset($users[$item->waiting_user_id])) {
|
||||
$users[$item->waiting_user_id] = $this->findName($item->users, $item->waiting_user_id);
|
||||
}
|
||||
}
|
||||
return view('home', compact('items', 'users'));
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use \App\Item;
|
||||
use \App\User;
|
||||
use App\FlashMessage as flash;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ItemController extends Controller
|
||||
@ -11,7 +12,15 @@ class ItemController extends Controller
|
||||
public function show($id)
|
||||
{
|
||||
$item = Item::find($id);
|
||||
if (!$item || $item->product->user_id != \Auth::id()) return back();
|
||||
if (!$item || $item->product->user_id != \Auth::id()) {
|
||||
session()->flash(
|
||||
flash::DANGER,
|
||||
\Lang::getFromJson(
|
||||
"The item doesn't exist."
|
||||
)
|
||||
);
|
||||
return back();
|
||||
}
|
||||
$users = $item->users()->get();
|
||||
|
||||
$otherItems = Item::where([['product_id', $item->product_id], ['id', '!=', $id]])->get();
|
||||
@ -28,7 +37,7 @@ class ItemController extends Controller
|
||||
* Stores the included item into database
|
||||
* As the items are included on the Product view,
|
||||
* it must return to there after inclusion
|
||||
*
|
||||
*
|
||||
* @return (view) The product view
|
||||
*/
|
||||
public function store(Request $request)
|
||||
@ -43,7 +52,7 @@ class ItemController extends Controller
|
||||
$authUser = User::loggedIn();
|
||||
$authUser->items()->create(['name' => request('item'), 'product_id' => request('product_id')]);
|
||||
|
||||
return redirect('product/'.request('product_id'));
|
||||
return redirect('product/' . request('product_id'));
|
||||
}
|
||||
|
||||
public function patch(Request $request)
|
||||
@ -52,7 +61,7 @@ class ItemController extends Controller
|
||||
$item = User::loggedIn()->items()->find(request('item'));
|
||||
$item->name = request('name');
|
||||
$item->save();
|
||||
return redirect('item/'.request('item'));
|
||||
return redirect('item/' . request('item'));
|
||||
}
|
||||
|
||||
public function delete(Request $request)
|
||||
@ -65,4 +74,4 @@ class ItemController extends Controller
|
||||
Item::deleteAndDetach($item);
|
||||
return redirect('product/' . $product);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
90
app/Http/Controllers/LanguageController.php
Normal file
90
app/Http/Controllers/LanguageController.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App;
|
||||
use App\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LanguageController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param int $locale
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update($locale)
|
||||
{
|
||||
App::setLocale($locale);
|
||||
User::setLanguage($locale);
|
||||
|
||||
session(['lang' => $locale]);
|
||||
session()->save();
|
||||
return back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
@ -3,8 +3,9 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use \App\Item;
|
||||
use \App\User;
|
||||
use \App\Product;
|
||||
use \App\User;
|
||||
use App\FlashMessage as flash;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ProductController extends Controller
|
||||
@ -17,7 +18,7 @@ class ProductController extends Controller
|
||||
|
||||
/**
|
||||
* Stores the included product into database
|
||||
*
|
||||
*
|
||||
* @return (view) The product view
|
||||
*/
|
||||
public function store(Request $request)
|
||||
@ -29,7 +30,7 @@ class ProductController extends Controller
|
||||
|
||||
/**
|
||||
* Delete a specified Product
|
||||
*
|
||||
*
|
||||
* @param (int) $id The product id
|
||||
*/
|
||||
public function delete(Request $request)
|
||||
@ -55,14 +56,14 @@ class ProductController extends Controller
|
||||
$product->name = request('name');
|
||||
$product->url = request('url');
|
||||
$product->save();
|
||||
return redirect('product/'.request('product'));
|
||||
return redirect('product/' . request('product'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a specified Product
|
||||
*
|
||||
*
|
||||
* @param (int) $id The product id
|
||||
*
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
@ -70,8 +71,13 @@ class ProductController extends Controller
|
||||
$product = Product::fromAuthUser()->find($id);
|
||||
|
||||
if (!$product) {
|
||||
return back();
|
||||
|
||||
session()->flash(
|
||||
flash::DANGER,
|
||||
\Lang::getFromJson(
|
||||
"The product doesn't exist or doesn't belongs to you."
|
||||
)
|
||||
);
|
||||
return redirect('/product');
|
||||
}
|
||||
return view('product.show', compact('product'));
|
||||
}
|
||||
|
@ -2,40 +2,63 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use \App\Item;
|
||||
use \App\User;
|
||||
use App\Mail\ItemAvailable;
|
||||
use App\Events\RefreshPage;
|
||||
use App\Events\ReturnItem;
|
||||
use App\Item;
|
||||
use App\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Lang;
|
||||
|
||||
/**
|
||||
* Responsible to Take and Return an Item.
|
||||
*/
|
||||
class TakeController extends Controller
|
||||
{
|
||||
/**
|
||||
* The user take an item
|
||||
*
|
||||
* @param Request $request The form data
|
||||
*
|
||||
* @return home view
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$item = User::loggedIn()->items()->find(request('item'));
|
||||
if ($item->used_by) {
|
||||
return back()->withErrors("This item is already taken");
|
||||
}
|
||||
$item->used_by = \Auth::id();
|
||||
$item->save();
|
||||
return redirect('home');
|
||||
}
|
||||
|
||||
public function delete(Request $request)
|
||||
{
|
||||
$item = User::loggedIn()->items()->find(request('item'));
|
||||
$waiting_id = $item->waiting_user_id;
|
||||
$item->used_by = null;
|
||||
$item->waiting_user_id = null;
|
||||
$item->save();
|
||||
|
||||
//Send e-mail to waiting user
|
||||
if ($waiting_id) {
|
||||
$user = User::find($waiting_id);
|
||||
\Mail::to($user)->send(
|
||||
new ItemAvailable($user->name, $item)
|
||||
try {
|
||||
$item->takeItem();
|
||||
} catch (\Exception $e) {
|
||||
return back()->withErrors(
|
||||
Lang::getFromJson('This item is already taken')
|
||||
);
|
||||
}
|
||||
|
||||
RefreshPage::dispatch($item);
|
||||
return redirect('home');
|
||||
}
|
||||
|
||||
/**
|
||||
* User return an item
|
||||
* Trigger an event: ReturnItem
|
||||
*
|
||||
* @param Request $request Form data
|
||||
*
|
||||
* @return View home
|
||||
*/
|
||||
public function delete(Request $request)
|
||||
{
|
||||
$item = User::loggedIn()->items()->find(request('item'));
|
||||
|
||||
try {
|
||||
$item->returnItem();
|
||||
} catch (\Exception $e) {
|
||||
return back()->withErrors(
|
||||
Lang::getFromJson("You cannot return an item that is not with you")
|
||||
);
|
||||
}
|
||||
|
||||
RefreshPage::dispatch($item);
|
||||
ReturnItem::dispatch($item);
|
||||
return redirect('home');
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use \App\User;
|
||||
use \App\Item;
|
||||
use \App\Product;
|
||||
use \App\User;
|
||||
use \Lang;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UserController extends Controller
|
||||
@ -42,14 +42,22 @@ class UserController extends Controller
|
||||
$userArray = User::where('email', request('email'))->get();
|
||||
|
||||
if (count($userArray) == 0) {
|
||||
return back()->withErrors("The e-mail address is not registered yet.");
|
||||
return back()->withErrors(
|
||||
Lang::getFromJson("The e-mail address is not registered yet.")
|
||||
);
|
||||
}
|
||||
|
||||
$item = Item::findOrFail(request('item_id'));
|
||||
if ($item->product->user_id == \Auth::id()) {
|
||||
User::findOrFail($userArray[0]->id)->items()->syncWithoutDetaching([request('item_id')]);
|
||||
User::findOrFail($userArray[0]->id)
|
||||
->items()
|
||||
->syncWithoutDetaching([request('item_id')]);
|
||||
} else {
|
||||
return back()->withErrors("You cannot add a user to a product that is not yourse.");
|
||||
return back()->withErrors(
|
||||
Lang::getFromJson(
|
||||
"You cannot add a user to a product that is not yourse."
|
||||
)
|
||||
);
|
||||
}
|
||||
return back();
|
||||
}
|
||||
@ -67,12 +75,20 @@ class UserController extends Controller
|
||||
$item = Item::findOrFail(request('item_id'));
|
||||
|
||||
if ($item->product->user_id == \Auth::id()) {
|
||||
$returnItem = User::findOrFail(request('user_id'))->items()->findOrFail(request('item_id'));
|
||||
$returnItem = User::findOrFail(request('user_id'))
|
||||
->items()
|
||||
->findOrFail(request('item_id'));
|
||||
$returnItem->used_by = null;
|
||||
$returnItem->save();
|
||||
User::findOrFail(request('user_id'))->items()->detach([request('item_id')]);
|
||||
User::findOrFail(request('user_id'))
|
||||
->items()
|
||||
->detach([request('item_id')]);
|
||||
} else {
|
||||
return back()->withErrors("You cannot remove a user from a product that is not yourse.");
|
||||
return back()->withErrors(
|
||||
Lang::getFromJson(
|
||||
"You cannot remove a user from a product that is not yourse."
|
||||
)
|
||||
);
|
||||
}
|
||||
return back();
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ class Kernel extends HttpKernel
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\Locale::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
@ -50,7 +51,7 @@ class Kernel extends HttpKernel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
|
22
app/Http/Middleware/Locale.php
Normal file
22
app/Http/Middleware/Locale.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App;
|
||||
use Closure;
|
||||
|
||||
class Locale
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
App::setLocale(session('lang'));
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
@ -19,5 +19,10 @@ class TrustProxies extends Middleware
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
|
61
app/Item.php
61
app/Item.php
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App;
|
||||
|
||||
use Auth;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Item extends Model
|
||||
@ -31,11 +33,66 @@ class Item extends Model
|
||||
|
||||
/**
|
||||
* Return the items from logged in user
|
||||
*
|
||||
*
|
||||
* @return \App\Item
|
||||
*/
|
||||
public static function fromAuthUser()
|
||||
{
|
||||
return (new static)->where('user_id', \Auth::id());
|
||||
return (new static)->where('user_id', Auth::id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a specified item
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function takeItem()
|
||||
{
|
||||
if (isset($this->used_by)) {
|
||||
throw new Exception("Trying to take an Item that is in use", 1);
|
||||
}
|
||||
|
||||
$this->used_by = Auth::id();
|
||||
$this->waiting_user_id = null;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a specified item
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function returnItem()
|
||||
{
|
||||
if ($this->used_by != Auth::id()) {
|
||||
throw new Exception("Trying to return an empty Item or from other user", 1);
|
||||
}
|
||||
|
||||
$this->used_by = null;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a waiting user to the item
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function storeAlert()
|
||||
{
|
||||
$this->waiting_user_id = Auth::id();
|
||||
$this->timestamps = false;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a waiting user to the item
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeAlert()
|
||||
{
|
||||
$this->waiting_user_id = null;
|
||||
$this->timestamps = false;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
39
app/Listeners/AlertReturnedItem.php
Normal file
39
app/Listeners/AlertReturnedItem.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Events\ReturnItem;
|
||||
use App\Mail\ItemAvailable;
|
||||
use App\User;
|
||||
use Mail;
|
||||
|
||||
class AlertReturnedItem
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email to the user that
|
||||
* is waiting for the item
|
||||
*
|
||||
* @param ReturnItem $event The return event that contains an item
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(ReturnItem $event)
|
||||
{
|
||||
if ($event->item->waiting_user_id) {
|
||||
$user = User::find($event->item->waiting_user_id);
|
||||
Mail::to($user)
|
||||
->locale($user->language)
|
||||
->send(new ItemAvailable($user->name, $event->item));
|
||||
}
|
||||
}
|
||||
}
|
32
app/Listeners/SetLanguage.php
Normal file
32
app/Listeners/SetLanguage.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\User;
|
||||
use Illuminate\Auth\Events\Login;
|
||||
use IlluminateAuthEventsLogin;
|
||||
|
||||
class SetLanguage
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param IlluminateAuthEventsLogin $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Login $event)
|
||||
{
|
||||
session(['lang' => User::loggedIn()->language]);
|
||||
session()->save();
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ use \App\Item;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class ItemAvailable extends Mailable
|
||||
{
|
||||
@ -32,7 +31,11 @@ class ItemAvailable extends Mailable
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->subject($this->item->name . ' is available!')
|
||||
->markdown('emails.itemAvailable');
|
||||
return $this->subject(
|
||||
\Lang::get(
|
||||
':itemname is available!',
|
||||
['itemname' => $this->item->name]
|
||||
)
|
||||
)->markdown('emails.itemAvailable');
|
||||
}
|
||||
}
|
||||
|
@ -6,13 +6,13 @@ use \App\Item;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Lang;
|
||||
|
||||
class UserWaiting extends Mailable
|
||||
{
|
||||
public $item;
|
||||
public $waitingUser;
|
||||
public $userWithItem;
|
||||
public $userWithItem;
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
@ -34,7 +34,14 @@ class UserWaiting extends Mailable
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->subject($this->waitingUser . ' wants to use ' . $this->item->name)
|
||||
->markdown('emails.userWaiting');
|
||||
return $this->subject(
|
||||
Lang::get(
|
||||
':waitinguser wants to use :itemname',
|
||||
[
|
||||
'waitinguser' => $this->waitingUser,
|
||||
'itemname' => $this->item->name
|
||||
]
|
||||
)
|
||||
)->markdown('emails.userWaiting');
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@
|
||||
namespace App\Mail;
|
||||
|
||||
use \App\User;
|
||||
use \Lang;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class Welcome extends Mailable
|
||||
{
|
||||
@ -30,6 +30,6 @@ class Welcome extends Mailable
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->markdown('emails.welcome');
|
||||
return $this->subject(Lang::get('Welcome'))->markdown('emails.welcome');
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class Product extends Model
|
||||
|
||||
/**
|
||||
* Return the products from logged in user
|
||||
*
|
||||
*
|
||||
* @return \App\Product
|
||||
*/
|
||||
public static function fromAuthUser()
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@ -14,7 +14,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Schema::defaultStringLength(191); //Solved by increasing StringLength
|
||||
Schema::defaultStringLength(191); //Solved by increasing StringLength
|
||||
//
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
@ -23,7 +22,6 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
//
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
@ -2,10 +2,13 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use App\Events\ReturnItem;
|
||||
use App\Listeners\AlertReturnedItem;
|
||||
use App\Listeners\SetLanguage;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
@ -18,6 +21,14 @@ class EventServiceProvider extends ServiceProvider
|
||||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
],
|
||||
|
||||
ReturnItem::class => [
|
||||
AlertReturnedItem::class,
|
||||
],
|
||||
|
||||
'Illuminate\Auth\Events\Login' => [
|
||||
SetLanguage::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
25
app/User.php
25
app/User.php
@ -2,10 +2,10 @@
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Auth;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable implements MustVerifyEmail
|
||||
{
|
||||
@ -41,11 +41,28 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
|
||||
/**
|
||||
* Return the logged in user
|
||||
*
|
||||
*
|
||||
* @return \App\User
|
||||
*/
|
||||
public static function loggedIn()
|
||||
{
|
||||
return (new static)->findOrFail(\Auth::id());
|
||||
return (new static)->findOrFail(Auth::id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default website language
|
||||
* for the acual user
|
||||
*
|
||||
* @param string $language The language code
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setLanguage(string $language)
|
||||
{
|
||||
if (Auth::check()) {
|
||||
$user = self::loggedIn();
|
||||
$user->language = $language;
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
check.sh
Normal file
2
check.sh
Normal file
@ -0,0 +1,2 @@
|
||||
./vendor/bin/phpstan analyse --memory-limit=2G
|
||||
php artisan insights
|
@ -5,18 +5,24 @@
|
||||
"license": "MIT",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"laravel/framework": "5.7.*",
|
||||
"laravel/tinker": "^1.0"
|
||||
"php": "^8.0.2",
|
||||
"inertiajs/inertia-laravel": "^0.6.11",
|
||||
"laravel/framework": "^10.0",
|
||||
"laravel/ui": "^4.0",
|
||||
"laravel/helpers": "^1.4",
|
||||
"laravel/tinker": "^2.4.1",
|
||||
"pusher/pusher-php-server": "^7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"beyondcode/laravel-dump-server": "^1.0",
|
||||
"filp/whoops": "^2.0",
|
||||
"fzaninotto/faker": "^1.4",
|
||||
"mockery/mockery": "^1.0",
|
||||
"nunomaduro/collision": "^2.0",
|
||||
"phpunit/phpunit": "^7.0"
|
||||
"nunomaduro/collision": "^7.0",
|
||||
"nunomaduro/larastan": "^2.9.5",
|
||||
"nunomaduro/phpinsights": "*",
|
||||
"phpstan/phpstan": "^1.10.66",
|
||||
"phpunit/phpunit": "^10.0"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
@ -53,8 +59,11 @@
|
||||
"config": {
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true,
|
||||
"optimize-autoloader": true
|
||||
"optimize-autoloader": true,
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
}
|
||||
|
9410
composer.lock
generated
9410
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -156,7 +156,7 @@ return [
|
||||
*/
|
||||
App\Providers\AppServiceProvider::class,
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
// App\Providers\BroadcastServiceProvider::class,
|
||||
App\Providers\BroadcastServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
|
||||
|
113
config/insights.php
Normal file
113
config/insights.php
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenDefineFunctions;
|
||||
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenFinalClasses;
|
||||
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenNormalClasses;
|
||||
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenPrivateMethods;
|
||||
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenTraits;
|
||||
use NunoMaduro\PhpInsights\Domain\Metrics\Architecture\Classes;
|
||||
use SlevomatCodingStandard\Sniffs\Commenting\UselessFunctionDocCommentSniff;
|
||||
use SlevomatCodingStandard\Sniffs\Namespaces\AlphabeticallySortedUsesSniff;
|
||||
use SlevomatCodingStandard\Sniffs\TypeHints\DeclareStrictTypesSniff;
|
||||
use SlevomatCodingStandard\Sniffs\TypeHints\DisallowMixedTypeHintSniff;
|
||||
use SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSniff;
|
||||
use SlevomatCodingStandard\Sniffs\TypeHints\PropertyTypeHintSniff;
|
||||
use SlevomatCodingStandard\Sniffs\TypeHints\ReturnTypeHintSniff;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Preset
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default preset that will be used by PHP Insights
|
||||
| to make your code reliable, simple, and clean. However, you can always
|
||||
| adjust the `Metrics` and `Insights` below in this configuration file.
|
||||
|
|
||||
| Supported: "default", "laravel", "symfony", "magento2", "drupal"
|
||||
|
|
||||
*/
|
||||
|
||||
'preset' => 'laravel',
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| IDE
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This options allow to add hyperlinks in your terminal to quickly open
|
||||
| files in your favorite IDE while browsing your PhpInsights report.
|
||||
|
|
||||
| Supported: "textmate", "macvim", "emacs", "sublime", "phpstorm",
|
||||
| "atom", "vscode".
|
||||
|
|
||||
| If you have another IDE that is not in this list but which provide an
|
||||
| url-handler, you could fill this config with a pattern like this:
|
||||
|
|
||||
| myide://open?url=file://%f&line=%l
|
||||
|
|
||||
*/
|
||||
|
||||
'ide' => null,
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may adjust all the various `Insights` that will be used by PHP
|
||||
| Insights. You can either add, remove or configure `Insights`. Keep in
|
||||
| mind that all added `Insights` must belong to a specific `Metric`.
|
||||
|
|
||||
*/
|
||||
|
||||
'exclude' => [
|
||||
// 'path/to/directory-or-file'
|
||||
],
|
||||
|
||||
'add' => [
|
||||
Classes::class => [
|
||||
ForbiddenFinalClasses::class,
|
||||
],
|
||||
],
|
||||
|
||||
'remove' => [
|
||||
AlphabeticallySortedUsesSniff::class,
|
||||
DeclareStrictTypesSniff::class,
|
||||
DisallowMixedTypeHintSniff::class,
|
||||
ForbiddenDefineFunctions::class,
|
||||
ForbiddenNormalClasses::class,
|
||||
ForbiddenTraits::class,
|
||||
ParameterTypeHintSniff::class,
|
||||
PropertyTypeHintSniff::class,
|
||||
ReturnTypeHintSniff::class,
|
||||
UselessFunctionDocCommentSniff::class,
|
||||
],
|
||||
|
||||
'config' => [
|
||||
ForbiddenPrivateMethods::class => [
|
||||
'title' => 'The usage of private methods is not idiomatic in Laravel.',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Requirements
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define a level you want to reach per `Insights` category.
|
||||
| When a score is lower than the minimum level defined, then an error
|
||||
| code will be returned. This is optional and individually defined.
|
||||
|
|
||||
*/
|
||||
|
||||
'requirements' => [
|
||||
// 'min-quality' => 0,
|
||||
// 'min-complexity' => 0,
|
||||
// 'min-architecture' => 0,
|
||||
// 'min-style' => 0,
|
||||
// 'disable-security-check' => false,
|
||||
],
|
||||
|
||||
];
|
@ -164,7 +164,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'secure' => env('SESSION_SECURE_COOKIE', false),
|
||||
'secure' => env('SESSION_SECURE_COOKIE', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -30,4 +30,4 @@ $factory->define(App\Product::class, function (Faker $faker) {
|
||||
return factory(App\User::class)->create()->id;
|
||||
},
|
||||
];
|
||||
});
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateUsersTable extends Migration
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreatePasswordResetsTable extends Migration
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProductsTable extends Migration
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateItemsTable extends Migration
|
||||
{
|
||||
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddLocationToUsers extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string('language')->after('email_verified_at')->default('en');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('language');
|
||||
});
|
||||
}
|
||||
}
|
36
database/migrations/2022_11_13_183613_create_jobs_table.php
Normal file
36
database/migrations/2022_11_13_183613_create_jobs_table.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
}
|
||||
};
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
|
2
deploy.sh
Normal file
2
deploy.sh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
git checkout production && git merge master && git checkout - && git push origin production && ssh -A contabo -t "cd /var/www/shareit.brunofontes.net; git fetch --all; git checkout --force production; git pull origin production --force; ~/composer.phar install -n --optimize-autoloader --no-dev; npm install"
|
73
lang/en/help.php
Normal file
73
lang/en/help.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* Strings from the Help page
|
||||
* They are separeted by help group
|
||||
*/
|
||||
|
||||
return [
|
||||
'helpTitle' => 'Help...',
|
||||
/**
|
||||
* What is it?
|
||||
*/
|
||||
'whatIsIt' => 'What is it?',
|
||||
'siteHelpOthers' => '<p><strong>Share It!</strong> is a site dedicated to help you sharing items with others.</p>
|
||||
<p>But before sharing anything, you just need to understand 2 basic ideas:</p>',
|
||||
'product_item' => '<li><strong>Product</strong> - The category that has some similar items</li>
|
||||
<li><strong>Item</strong> - The item that will be shared. Every item belongs to a <strong>Product</strong></li>',
|
||||
'examples' => "<strong><em>Examples:</em></strong> You can create the following Categories/Items</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Books -> Don Quixote, The Hitchhiker's Guide to the Galaxy</li>
|
||||
<li>Matrix Movies -> Matrix 1, Matrix 2, Matrix 3</li>
|
||||
<li>Website Y -> <em>YourAccount</em>*</li>
|
||||
</ul>
|
||||
<p><em>* Please note that many websites does not allow sharing your account. Read the site EULA before include it here.</em></p>",
|
||||
|
||||
/**
|
||||
* Step-by-step
|
||||
*/
|
||||
'step_title' => 'Step-by-step',
|
||||
'step_sharing_subtitle' => 'Sharing a product/item',
|
||||
'step_sharing_steps' => '<li>Go to the <strong><a href="/product">Products</a></strong> page;</li>
|
||||
<li>Include the Product and click on it;</li>
|
||||
<li>Include an Item that belongs to that Product and click on it;</li>
|
||||
<li>Add other people with their subscribed e-mail address.</li>',
|
||||
|
||||
'step_sharedItem_subtitle' => 'Using a shared item',
|
||||
'step_sharedItem_steps' => '<li>Go to the <strong><a href="/home">Home</a></strong> page (tip: add this page as a bookmark);</li>
|
||||
<li>Click on <strong>Take</strong> to take the item you want to use;</li>
|
||||
<li>When you finish using it, click on <strong>Return</strong> button.</li>',
|
||||
|
||||
'step_getAlerted_subtitle' => 'Getting alerted when an item is available',
|
||||
'step_getAlerted_steps' => '<li>Go to the <strong><a href="/home">Home</a></strong> page (tip: add this page as a bookmark);</li>
|
||||
<li>Click on <strong>Alert me</strong> next the taken item;</li>
|
||||
<li>The active user will be alerted you want to use it later. When the person return it, you will be notified.</li>',
|
||||
|
||||
/**
|
||||
* Screens
|
||||
*/
|
||||
'screens_title' => 'Screens',
|
||||
|
||||
/**
|
||||
* Home
|
||||
*/
|
||||
'home_title' => 'Home',
|
||||
'home_body' => '<p>The <strong>Home</strong> is the main screen where you will going to <strong>Take</strong>
|
||||
and <strong>Return</strong> items.</p>
|
||||
<p>It shows all items that were shared with you or that you are sharing, unless you remove yourself from there.</p>
|
||||
<p>If the item has a website, the items name will become a link, so you can just click on it to open.</p>
|
||||
<p>When the item you want is already taken, you are going to see who got it and for how long.
|
||||
So you can identify if the person is still using it or if someone just forgot to return it.</p>
|
||||
<p>You can also ask to be alerted when the item is available. This will notify the active
|
||||
user that you want to use that item. So the person can return it as soon as they finish using it.</p>',
|
||||
|
||||
/**
|
||||
* Products
|
||||
*/
|
||||
'products_title' => 'Products',
|
||||
'products_body' => '<p>The <strong>Products</strong> is the screen to include Products and Items.</p>
|
||||
<p>You can also <strong>add users</strong> to your items from this screen.
|
||||
To be able to do that you just need to select the item.</p>
|
||||
<p class="mb-4">When adding a Product, you can specify a webpage (this is optional).</p>',
|
||||
|
||||
];
|
12
lang/en/home.php
Normal file
12
lang/en/home.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
// /resources/views/home.blade.php
|
||||
|
||||
return [
|
||||
'no_messages' => 'There are no items shared with you yet.',
|
||||
'share_item' => 'Share an item!',
|
||||
'return' => 'Return It',
|
||||
'cancel_alert' => 'Cancel Alert',
|
||||
'alert_me' => 'Alert me',
|
||||
'take' => 'Take It'
|
||||
];
|
40
lang/en/item.php
Normal file
40
lang/en/item.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/**
|
||||
* Strings from Item Delete button menu
|
||||
*/
|
||||
'confirmation' => 'Confirmation...',
|
||||
'confirmDeletion' => 'Would you like to delete the item <strong>:itemname</strong>?',
|
||||
'notAbleRestore' => 'You will not be able to restore it after deletion.',
|
||||
'close' => 'Close',
|
||||
'delete' => 'Delete',
|
||||
|
||||
/**
|
||||
* Strings from Item Edit button menu
|
||||
*/
|
||||
'edit' => 'Edit',
|
||||
'edititem' => 'Edit item',
|
||||
'newname' => 'New name:',
|
||||
|
||||
/**
|
||||
* Strings from the Users box on Item page
|
||||
*/
|
||||
'users' => 'Users:',
|
||||
'noItems' => 'There are no items yet. Include one with the form above.',
|
||||
'addUser' => 'Add user',
|
||||
'email' => 'E-mail: ',
|
||||
'nameDomain' => 'name@domain.com',
|
||||
'insert' => 'Insert',
|
||||
|
||||
/**
|
||||
* String from otherItems.blade.php - Other items box from item page
|
||||
*/
|
||||
'otherItems' => 'Other items from the same product',
|
||||
|
||||
/**
|
||||
* String from item.blade.php
|
||||
*/
|
||||
'back' => 'BACK',
|
||||
|
||||
];
|
63
lang/en/product.php
Normal file
63
lang/en/product.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Strings from the product pages
|
||||
* They are separeted by the file that calls them.
|
||||
* Sometimes, a string is used on another file,
|
||||
* so it will stay at the common segment.
|
||||
*/
|
||||
|
||||
return [
|
||||
/**
|
||||
* COMMON
|
||||
*/
|
||||
'insert' => 'Insert',
|
||||
'close' => 'Close',
|
||||
'' => '',
|
||||
'' => '',
|
||||
|
||||
/**
|
||||
* addItemForm.blade.php
|
||||
*/
|
||||
'item' => 'Item:',
|
||||
'100yearsSolitude' => 'One Hundred Years of Solitude',
|
||||
|
||||
/**
|
||||
* addProductForm.blade.php
|
||||
*/
|
||||
'name' => 'Name:',
|
||||
'book' => 'Book',
|
||||
'url' => 'URL:',
|
||||
'optionalUrlExample' => '(Optional) http://bookwebsite.com',
|
||||
|
||||
/**
|
||||
* deleteButton.blade.php
|
||||
*/
|
||||
'delete' => 'Delete',
|
||||
'confirmation' => 'Confirmation...',
|
||||
'wannaDelete' => "Would you like to delete the product <strong>:productname</strong> and it's items?",
|
||||
'notAbleRestore' => 'You will not be able to restore it after deletion.',
|
||||
|
||||
/**
|
||||
* editButton.blade.php
|
||||
*/
|
||||
'edit' => 'Edit',
|
||||
'editProduct' => 'Edit product',
|
||||
'newName' => 'New name:',
|
||||
'newUrl' => 'New url:',
|
||||
|
||||
/**
|
||||
* index.blade.php
|
||||
*/
|
||||
'products' => 'Products',
|
||||
'noProductsYet' => 'There are no products yet. Include one with the form above.',
|
||||
'addProduct' => 'Add product',
|
||||
'yourItems' => 'Your items',
|
||||
|
||||
/**
|
||||
* show.blade.php
|
||||
*/
|
||||
'items' => 'Items:',
|
||||
'noItemsYet' => 'There are no items yet. Include one with the form above.',
|
||||
'addItem' => 'Add item',
|
||||
'back' => 'BACK',
|
||||
];
|
15
lang/en/test.php
Normal file
15
lang/en/test.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
];
|
10
lang/en/welcome.php
Normal file
10
lang/en/welcome.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
return [
|
||||
'Home' => 'Home',
|
||||
'Login' => 'Login',
|
||||
'Register' => 'Register',
|
||||
'Products' => 'Products',
|
||||
'Help' => 'Help',
|
||||
'copyright' => '© 2018 Bruno Fontes All Rights Reserved',
|
||||
'byAuthor' => 'By Bruno Fontes',
|
||||
];
|
52
lang/pt-br.json
Normal file
52
lang/pt-br.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"Reset Password": "Redefinir senha",
|
||||
"E-Mail Address" : "E-mail",
|
||||
"Send Password Reset Link" : "Redefinir senha",
|
||||
"Password" : "Senha",
|
||||
"Confirm Password" : "Confirmar senha",
|
||||
"Login" : "Entrar",
|
||||
"Remember Me" : "Manter conectado",
|
||||
"Forgot Your Password?" : "Esqueceu sua senha?",
|
||||
"Register" : "Cadastrar",
|
||||
"Name" : "Nome",
|
||||
"Logout" : "Desconectar",
|
||||
"Verify Your Email Address" : "Confirme seu e-mail",
|
||||
"A fresh verification link has been sent to your email address." : "Enviamos outro link de confirmação para o seu e-mail.",
|
||||
"Before proceeding, please check your email for a verification link." : "Antes de continuar, use o link de confirmação que enviamos para o seu e-mail.",
|
||||
"If you did not receive the email" : "Se você não recebeu o e-mail",
|
||||
"click here to request another" : "clique aqui para enviar novamente",
|
||||
"Thanks for registering. Please, do not forget to validate your e-mail address." : "Obrigado por se cadastrar. Não esqueça de validar seu e-mail.",
|
||||
|
||||
"Welcome": "Bem-vindo!",
|
||||
"Welcome, :username,": "Bem-vindo, :username,",
|
||||
"Thank's for registering at **Share It!**" : "Obrigado por se registrar no **Share It!**",
|
||||
"Your account was created, but you still need to activate it. We've sent you another e-mail and we are ready to go!" : "Sua conta foi criada, mas você ainda precisa confirmar o seu e-mail para usá-la. Enviamos um outro e-mail com a confirmação.",
|
||||
"And you? Are you ready to Share It with your friends?" : "E você? Está pronto para compartilhar?",
|
||||
|
||||
":waitinguser wants to use :itemname": ":waitinguser quer usar :itemname",
|
||||
"Hello!": "Olá!",
|
||||
"Verify Email Address" : "Confirme o seu e-mail",
|
||||
"Please click the button below to verify your email address." : "Clique no botão abaixo para confirmar o seu e-mail.",
|
||||
"If you did not create an account, no further action is required." : "Se você não criou uma conta, basta ignorar este e-mail.",
|
||||
"Regards": "Obrigado",
|
||||
|
||||
":itemname is available!": ":itemname está disponível!",
|
||||
"Hi, :username,": "Olá, :username,",
|
||||
"Good news: :itemname is available!": "Boa notícia: :itemname está disponível!",
|
||||
"The item <em>:itemname (:productname)</em> is now available on **Share It**.": "O item <em>:itemname (:productname)</em> já está disponível no **Share It**.",
|
||||
"**Take It** before anyone else at the website:": "Entre no nosso site para usar o item antes de todo mundo.",
|
||||
|
||||
"Are you still using :itemname?": "Você ainda está usando o item :itemname?",
|
||||
"We just want to let you know that :waitinguser asked us to be alerted when this item were available.": "A gente apenas queria dizer que :waitinguser nos pediu para avisar quando esse item estivesse disponível.",
|
||||
"So, if you are not using it anymore, please **Return It** at the website:": "Então, se você não estiver mais usando, por favor, **Devolva** no nosso site:",
|
||||
|
||||
"The e-mail address is not registered yet.": "Esse usuário ainda não está cadastrado.",
|
||||
"You cannot add a user to a product that is not yourse.": "Você não pode adicionar um usuário a um produto que não é seu.",
|
||||
"You cannot remove a user from a product that is not yourse.": "Você não pode remover um usuário de um produto que não é seu.",
|
||||
|
||||
"The item doesn't exist.": "O item não existe.",
|
||||
"The product doesn't exist or doesn't belongs to you.": "O produto não existe ou não é seu.",
|
||||
"This item is already taken": "Esse item já está sendo usado.",
|
||||
"You cannot return an item that is not with you": "Você não pode devolver um item que não está com você.",
|
||||
"Oh! This item has just being returned. Take it before anyone else!": "Opa! Esse item acabou de ser devolvido. Aproveite!"
|
||||
}
|
19
lang/pt-br/auth.php
Normal file
19
lang/pt-br/auth.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'Login ou senha inválidos.',
|
||||
'throttle' => 'Limite tentativas excedido. Você pode tentar novamente após :seconds segundos.',
|
||||
|
||||
];
|
74
lang/pt-br/help.php
Normal file
74
lang/pt-br/help.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Strings from the Help page
|
||||
* They are separeted by help group
|
||||
*/
|
||||
|
||||
return [
|
||||
'helpTitle' => 'Ajuda...',
|
||||
/**
|
||||
* What is it?
|
||||
*/
|
||||
'whatIsIt' => 'O que é?',
|
||||
'siteHelpOthers' => '<p><strong>Share It!</strong> é um site que te ajudar a compartilhar seus items com seus amigos.</p>
|
||||
<p>Mas antes de qualquer coisa, você precisa entender duas ideias básicas:</p>',
|
||||
'product_item' => '<li><strong>Produto</strong> - Um grupo que contém itens similares</li>
|
||||
<li><strong>Item</strong> - O item que será compartilhado. Cada item pertence a um <strong>Produto</strong></li>',
|
||||
'examples' => "<strong><em>Exemplos:</em></strong> Você pode criar os seguintes Produtos/Itens:</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Livros -> Don Quixote, O guia do mochileiro das galáxias</li>
|
||||
<li>Filmes Matrix -> Matrix 1, Matrix 2, Matrix 3</li>
|
||||
<li>Site Y -> <em>SuaConta</em>*</li>
|
||||
</ul>
|
||||
<p><em>* Observe que muitos sites não permitem compartilhar sua conta. Leia atentamente o contrato do serviço antes de incluí-lo aqui.</em></p>",
|
||||
|
||||
/**
|
||||
* Step-by-step
|
||||
*/
|
||||
'step_title' => 'Passo a passo',
|
||||
'step_sharing_subtitle' => 'Compartilhando um produto/item',
|
||||
'step_sharing_steps' => '<li>Vá para a página <strong><a href="/product">Produtos</a></strong>;</li>
|
||||
<li>Inclua o Produto e clique nele;</li>
|
||||
<li>Inclua um item que pertence ao produto cadastrado e clique nele;</li>
|
||||
<li>Adicione outras pessoas pelo e-mail que elas se cadastram.</li>',
|
||||
|
||||
'step_sharedItem_subtitle' => 'Usando um item compartilhado',
|
||||
'step_sharedItem_steps' => '<li>Vá até a página <strong><a href="/home">Início</a></strong> (dica: adicione essa página aos seus favoritos);</li>
|
||||
<li>Clique em <strong>Usar</strong> para usar o item que deseja;</li>
|
||||
<li>Ao terminar de usar, clique no botão <strong>Devolver</strong>.</li>',
|
||||
|
||||
'step_getAlerted_subtitle' => 'Sendo avisado quando um item está disponível',
|
||||
'step_getAlerted_steps' => '<li>Vá até a página <strong><a href="/home">Início</a></strong> (dica: adicione essa página aos seus favoritos);</li>
|
||||
<li>Clique no botão <strong>Alertar</strong> próximo ao item que está em uso;</li>
|
||||
<li>O atual usuário será avisado que você quer usar o item. Quando a pessoa devolver, você será notificado.</li>',
|
||||
|
||||
/**
|
||||
* Screens
|
||||
*/
|
||||
'screens_title' => 'Páginas',
|
||||
|
||||
/**
|
||||
* Home
|
||||
*/
|
||||
'home_title' => 'Início',
|
||||
'home_body' => '<p>A tela <strong>Início</strong> é a sua página principal. Lá você vai <strong>Usar</strong>
|
||||
e <strong>Devolver</strong> itens.</p>
|
||||
<p>Ela exibe todos os itens que estão sendo compartilhados com você ou que você está compartilhando
|
||||
a menos que você se remova de lá.</p>
|
||||
<p>Se um item tiver um site cadastrado, ele aparecerá como um link. Então você pode clicar nele para abrir a página.</p>
|
||||
<p>Quanto o item que você quiser já estiver em uso, você vai ver quem o está usando e por quanto tempo.
|
||||
Então você pode identificar se a pessoa ainda está usando ou se aparentemente ela esqueceu de retorná-lo.</p>
|
||||
<p>Você também pode pedir para ser avisado quando o item estiver disponível. Isso vai avisar o usuário ativo
|
||||
que você está esperando por ele. Então a pessoa pode devolvê-lo assim que ela terminar de usar.</p>',
|
||||
|
||||
/**
|
||||
* Products
|
||||
*/
|
||||
'products_title' => 'Produtos',
|
||||
'products_body' => '<p>A página <strong>Produtos</strong> é a tela usada para incluir Produtos e Itens.</p>
|
||||
<p>Você também pode <strong>incluir usuários</strong> aos seus items nessa tela.
|
||||
Para fazer isso, você só precisa clicar no item que deseja compartilhar e incluir outras pessoas.</p>
|
||||
<p class="mb-4">Ao adicionar um produto, você pode especificar um site (opcional).</p>',
|
||||
|
||||
];
|
12
lang/pt-br/home.php
Normal file
12
lang/pt-br/home.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
// /resources/views/home.blade.php
|
||||
|
||||
return [
|
||||
'no_messages' => 'Ainda não há itens compartilhados com você.',
|
||||
'share_item' => 'Compartilhe um item!',
|
||||
'return' => 'Devolver',
|
||||
'cancel_alert' => 'Cancelar alerta',
|
||||
'alert_me' => 'Alertar',
|
||||
'take' => 'Usar'
|
||||
];
|
39
lang/pt-br/item.php
Normal file
39
lang/pt-br/item.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/**
|
||||
* Strings from Item Delete button menu
|
||||
*/
|
||||
'confirmation' => 'Confirmação...',
|
||||
'confirmDeletion' => 'Você gostaria de apagar o item <strong>:itemname</strong>?',
|
||||
'notAbleRestore' => 'Não será possível restaurá-lo posteriormente.',
|
||||
'close' => 'Fechar',
|
||||
'delete' => 'Apagar',
|
||||
|
||||
/**
|
||||
* Strings from Item Edit button menu
|
||||
*/
|
||||
'edit' => 'Editar',
|
||||
'edititem' => 'Editar item',
|
||||
'newname' => 'Novo nome:',
|
||||
|
||||
/**
|
||||
* Strings from the Users box on Item page
|
||||
*/
|
||||
'users' => 'Usuários:',
|
||||
'noItems' => 'Não há itens cadastrados. Adicione um no formulário acima.',
|
||||
'addUser' => 'Adicionar usuário',
|
||||
'email' => 'E-mail: ',
|
||||
'nameDomain' => 'nome@dominio.com.br',
|
||||
'insert' => 'Inserir',
|
||||
|
||||
/**
|
||||
* String from otherItems.blade.php - Other items box from item page
|
||||
*/
|
||||
'otherItems' => 'Outros items do mesmo produto',
|
||||
|
||||
/**
|
||||
* String from item.blade.php
|
||||
*/
|
||||
'back' => 'VOLTAR',
|
||||
];
|
19
lang/pt-br/pagination.php
Normal file
19
lang/pt-br/pagination.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Anterior',
|
||||
'next' => 'Próxima »',
|
||||
|
||||
];
|
22
lang/pt-br/passwords.php
Normal file
22
lang/pt-br/passwords.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| has failed, such as for an invalid token or invalid new password.
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => 'As senhas precisam ter pelo menos 6 caracteres e serem iguais a confirmação.',
|
||||
'reset' => 'Sua senha foi redefinida!',
|
||||
'sent' => 'O link para redefinir sua senha foi enviado por e-mail!',
|
||||
'token' => 'O token de redefinição de senha é inválido.',
|
||||
'user' => "Não foi possível encontrar um usuário com o e-mail digitado.",
|
||||
|
||||
];
|
61
lang/pt-br/product.php
Normal file
61
lang/pt-br/product.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Strings from the product pages
|
||||
* They are separeted by the file that calls them.
|
||||
* Sometimes, a string is used on another file,
|
||||
* so it will stay at the common segment.
|
||||
*/
|
||||
|
||||
return [
|
||||
/**
|
||||
* COMMON
|
||||
*/
|
||||
'insert' => 'Inserir',
|
||||
'close' => 'Fechar',
|
||||
|
||||
/**
|
||||
* addItemForm.blade.php
|
||||
*/
|
||||
'item' => 'Item:',
|
||||
'100yearsSolitude' => 'Cem anos de solidão',
|
||||
|
||||
/**
|
||||
* addProductForm.blade.php
|
||||
*/
|
||||
'name' => 'Nome:',
|
||||
'book' => 'Livro',
|
||||
'url' => 'URL:',
|
||||
'optionalUrlExample' => '(Opcional) http://sitedolivro.com.br',
|
||||
|
||||
/**
|
||||
* deleteButton.blade.php
|
||||
*/
|
||||
'delete' => 'Apagar',
|
||||
'confirmation' => 'Confirmação...',
|
||||
'wannaDelete' => "Você gostaria de apagar o produto <strong>:productname</strong> e seus items?",
|
||||
'notAbleRestore' => 'Não será possível recuperá-los depois.',
|
||||
|
||||
/**
|
||||
* editButton.blade.php
|
||||
*/
|
||||
'edit' => 'Editar',
|
||||
'editProduct' => 'Editar produto',
|
||||
'newName' => 'Novo nome:',
|
||||
'newUrl' => 'Nova url:',
|
||||
|
||||
/**
|
||||
* index.blade.php
|
||||
*/
|
||||
'products' => 'Produtos',
|
||||
'noProductsYet' => 'Ainda não há produtos cadastrados. Inclua um no formulário acima.',
|
||||
'addProduct' => 'Incluir produto',
|
||||
'yourItems' => 'Seus items',
|
||||
|
||||
/**
|
||||
* show.blade.php
|
||||
*/
|
||||
'items' => 'Items:',
|
||||
'noItemsYet' => 'Ainda não há itens cadastrados. Inclua um no formulário acima.',
|
||||
'addItem' => 'Incluir item',
|
||||
'back' => 'VOLTAR',
|
||||
];
|
148
lang/pt-br/validation.php
Normal file
148
lang/pt-br/validation.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => 'The :attribute must be accepted.',
|
||||
'active_url' => 'The :attribute is not a valid URL.',
|
||||
'after' => 'The :attribute must be a date after :date.',
|
||||
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
|
||||
'alpha' => 'The :attribute may only contain letters.',
|
||||
'alpha_dash' => 'The :attribute may only contain letters, numbers, dashes and underscores.',
|
||||
'alpha_num' => 'The :attribute may only contain letters and numbers.',
|
||||
'array' => 'The :attribute must be an array.',
|
||||
'before' => 'The :attribute must be a date before :date.',
|
||||
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
|
||||
'between' => [
|
||||
'numeric' => 'The :attribute must be between :min and :max.',
|
||||
'file' => 'The :attribute must be between :min and :max kilobytes.',
|
||||
'string' => 'The :attribute must be between :min and :max characters.',
|
||||
'array' => 'The :attribute must have between :min and :max items.',
|
||||
],
|
||||
'boolean' => 'The :attribute field must be true or false.',
|
||||
'confirmed' => 'Os campos :attribute e confirmar :attribute são diferentes.',
|
||||
'date' => 'The :attribute is not a valid date.',
|
||||
'date_format' => 'The :attribute does not match the format :format.',
|
||||
'different' => 'The :attribute and :other must be different.',
|
||||
'digits' => 'The :attribute must be :digits digits.',
|
||||
'digits_between' => 'The :attribute must be between :min and :max digits.',
|
||||
'dimensions' => 'The :attribute has invalid image dimensions.',
|
||||
'distinct' => 'The :attribute field has a duplicate value.',
|
||||
'email' => 'The :attribute must be a valid email address.',
|
||||
'exists' => 'The selected :attribute is invalid.',
|
||||
'file' => 'The :attribute must be a file.',
|
||||
'filled' => 'The :attribute field must have a value.',
|
||||
'gt' => [
|
||||
'numeric' => 'The :attribute must be greater than :value.',
|
||||
'file' => 'The :attribute must be greater than :value kilobytes.',
|
||||
'string' => 'The :attribute must be greater than :value characters.',
|
||||
'array' => 'The :attribute must have more than :value items.',
|
||||
],
|
||||
'gte' => [
|
||||
'numeric' => 'The :attribute must be greater than or equal :value.',
|
||||
'file' => 'The :attribute must be greater than or equal :value kilobytes.',
|
||||
'string' => 'The :attribute must be greater than or equal :value characters.',
|
||||
'array' => 'The :attribute must have :value items or more.',
|
||||
],
|
||||
'image' => 'The :attribute must be an image.',
|
||||
'in' => 'The selected :attribute is invalid.',
|
||||
'in_array' => 'The :attribute field does not exist in :other.',
|
||||
'integer' => 'The :attribute must be an integer.',
|
||||
'ip' => 'The :attribute must be a valid IP address.',
|
||||
'ipv4' => 'The :attribute must be a valid IPv4 address.',
|
||||
'ipv6' => 'The :attribute must be a valid IPv6 address.',
|
||||
'json' => 'The :attribute must be a valid JSON string.',
|
||||
'lt' => [
|
||||
'numeric' => 'The :attribute must be less than :value.',
|
||||
'file' => 'The :attribute must be less than :value kilobytes.',
|
||||
'string' => 'The :attribute must be less than :value characters.',
|
||||
'array' => 'The :attribute must have less than :value items.',
|
||||
],
|
||||
'lte' => [
|
||||
'numeric' => 'The :attribute must be less than or equal :value.',
|
||||
'file' => 'The :attribute must be less than or equal :value kilobytes.',
|
||||
'string' => 'The :attribute must be less than or equal :value characters.',
|
||||
'array' => 'The :attribute must not have more than :value items.',
|
||||
],
|
||||
'max' => [
|
||||
'numeric' => 'The :attribute may not be greater than :max.',
|
||||
'file' => 'The :attribute may not be greater than :max kilobytes.',
|
||||
'string' => 'The :attribute may not be greater than :max characters.',
|
||||
'array' => 'The :attribute may not have more than :max items.',
|
||||
],
|
||||
'mimes' => 'The :attribute must be a file of type: :values.',
|
||||
'mimetypes' => 'The :attribute must be a file of type: :values.',
|
||||
'min' => [
|
||||
'numeric' => 'O campo :attribute precisa ter pelo menos :min.',
|
||||
'file' => 'The :attribute must be at least :min kilobytes.',
|
||||
'string' => 'O campo :attribute precisa ter pelo menos :min caracteres.',
|
||||
'array' => 'The :attribute must have at least :min items.',
|
||||
],
|
||||
'not_in' => 'The selected :attribute is invalid.',
|
||||
'not_regex' => 'The :attribute format is invalid.',
|
||||
'numeric' => 'The :attribute must be a number.',
|
||||
'present' => 'The :attribute field must be present.',
|
||||
'regex' => 'The :attribute format is invalid.',
|
||||
'required' => 'The :attribute field is required.',
|
||||
'required_if' => 'The :attribute field is required when :other is :value.',
|
||||
'required_unless' => 'The :attribute field is required unless :other is in :values.',
|
||||
'required_with' => 'The :attribute field is required when :values is present.',
|
||||
'required_with_all' => 'The :attribute field is required when :values is present.',
|
||||
'required_without' => 'The :attribute field is required when :values is not present.',
|
||||
'required_without_all' => 'The :attribute field is required when none of :values are present.',
|
||||
'same' => 'The :attribute and :other must match.',
|
||||
'size' => [
|
||||
'numeric' => 'The :attribute must be :size.',
|
||||
'file' => 'The :attribute must be :size kilobytes.',
|
||||
'string' => 'The :attribute must be :size characters.',
|
||||
'array' => 'The :attribute must contain :size items.',
|
||||
],
|
||||
'string' => 'The :attribute must be a string.',
|
||||
'timezone' => 'The :attribute must be a valid zone.',
|
||||
'unique' => 'The :attribute has already been taken.',
|
||||
'uploaded' => 'The :attribute failed to upload.',
|
||||
'url' => 'The :attribute format is invalid.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'custom-message',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [
|
||||
'password' => 'senha'
|
||||
],
|
||||
|
||||
];
|
10
lang/pt-br/welcome.php
Normal file
10
lang/pt-br/welcome.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
return [
|
||||
'Home' => 'Início',
|
||||
'Login' => 'Login',
|
||||
'Register' => 'Cadastrar',
|
||||
'Products' => 'Produtos',
|
||||
'Help' => 'Ajuda',
|
||||
'copyright' => '© 2018 Bruno Fontes Todos os direitos reservados',
|
||||
'byAuthor' => 'Por Bruno Fontes',
|
||||
];
|
0
public/favicon.ico → package-lock.json
generated
0
public/favicon.ico → package-lock.json
generated
34
package.json
34
package.json
@ -1,22 +1,26 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "npm run development -- --watch",
|
||||
"watch-poll": "npm run watch -- --watch-poll",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
"dev": "vite",
|
||||
"build": "vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.18",
|
||||
"bootstrap": "^4.0.0",
|
||||
"cross-env": "^5.1",
|
||||
"jquery": "^3.2",
|
||||
"laravel-mix": "^2.0",
|
||||
"lodash": "^4.17.5",
|
||||
"popper.js": "^1.12",
|
||||
"vue": "^2.5.7"
|
||||
"axios": "^1.1.3",
|
||||
"bootstrap": "^4.6.0",
|
||||
"cross-env": "^5.2.1",
|
||||
"jquery": "^3.5.1",
|
||||
"laravel-echo": "^1.14.1",
|
||||
"laravel-vite-plugin": "^0.7.0",
|
||||
"lodash": "^4.17.21",
|
||||
"popper.js": "^1.16.1",
|
||||
"postcss": "^8.4.19",
|
||||
"pusher-js": "^7.4.1",
|
||||
"resolve-url-loader": "^3.1.3",
|
||||
"sass": "^1.56.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"vite": "^3.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"moment": "^2.29.4"
|
||||
}
|
||||
}
|
||||
|
17
phpstan.neon
Normal file
17
phpstan.neon
Normal file
@ -0,0 +1,17 @@
|
||||
includes:
|
||||
- ./vendor/nunomaduro/larastan/extension.neon
|
||||
|
||||
parameters:
|
||||
paths:
|
||||
- app
|
||||
|
||||
# The level 8 is the highest level
|
||||
level: 5
|
||||
|
||||
ignoreErrors:
|
||||
- '#Unsafe usage of new static#'
|
||||
|
||||
excludePaths:
|
||||
- ./*/*/FileToBeExcluded.php
|
||||
|
||||
checkMissingIterableValueType: false
|
48
public/build/assets/app.4993c47e.js
vendored
Normal file
48
public/build/assets/app.4993c47e.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/build/assets/pusher.a7756fcc.js
vendored
Normal file
1
public/build/assets/pusher.a7756fcc.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
import"https://js.pusher.com/7.2/pusher.min.js";var n=new Pusher("93b3e504421787295454",{cluster:"us2"}),o=n.subscribe("touchedItem");o.bind("RefreshPage",function(e){window.location.reload(),console.log(JSON.stringify(e))});
|
12
public/build/manifest.json
Normal file
12
public/build/manifest.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"resources/js/app.js": {
|
||||
"file": "assets/app.4993c47e.js",
|
||||
"src": "resources/js/app.js",
|
||||
"isEntry": true
|
||||
},
|
||||
"resources/js/pusher.js": {
|
||||
"file": "assets/pusher.a7756fcc.js",
|
||||
"src": "resources/js/pusher.js",
|
||||
"isEntry": true
|
||||
}
|
||||
}
|
9254
public/css/app.css
vendored
9254
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
BIN
public/favicon.png
Normal file
BIN
public/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
46233
public/js/app.js
vendored
46233
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
77
public/js/app.js.LICENSE.txt
Normal file
77
public/js/app.js.LICENSE.txt
Normal file
@ -0,0 +1,77 @@
|
||||
/*!
|
||||
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Determine if an object is a Buffer
|
||||
*
|
||||
* @author Feross Aboukhadijeh <https://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Sizzle CSS Selector Engine v2.3.5
|
||||
* https://sizzlejs.com/
|
||||
*
|
||||
* Copyright JS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://js.foundation/
|
||||
*
|
||||
* Date: 2020-03-14
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Vue.js v2.6.12
|
||||
* (c) 2014-2020 Evan You
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* jQuery JavaScript Library v3.5.1
|
||||
* https://jquery.com/
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* https://sizzlejs.com/
|
||||
*
|
||||
* Copyright JS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2020-05-04T22:49Z
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Lodash <https://lodash.com/>
|
||||
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
||||
* Released under MIT license <https://lodash.com/license>
|
||||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||||
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||
*/
|
||||
|
||||
/**!
|
||||
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||
* @version 1.16.1
|
||||
* @license
|
||||
* Copyright (c) 2016 Federico Zivolo and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
1
public/mix-manifest.json
Normal file
1
public/mix-manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
15
readme.md
15
readme.md
@ -1,16 +1,7 @@
|
||||
# Share It
|
||||
|
||||
Cada usuário, identificado por e-mail, pode ter outros amigos
|
||||
Just a simple tool to share items with friends.
|
||||
|
||||
## DB
|
||||
It is my first try with Laravel, so I am just learning it. :)
|
||||
|
||||
[x] usuário(nome, email)
|
||||
[x] product[site/software](nome, admin)
|
||||
[ ] usersPerItem(productID, userID)
|
||||
[x] item[licença](nome, productID, used_by, usedSince)
|
||||
[ ] waiting(userID, itemID, waitingSince)
|
||||
|
||||
## VIEWS
|
||||
|
||||
- Product (administration)
|
||||
- Item (view itens, other itens from the same product if this one is occupied)
|
||||
More information about **Share It** [here](https://shareit.brunofontes.net/help).
|
62
resources/js/app.js
vendored
62
resources/js/app.js
vendored
@ -5,9 +5,10 @@
|
||||
* building robust, powerful web applications using Vue and Laravel.
|
||||
*/
|
||||
|
||||
require('./bootstrap');
|
||||
import './bootstrap';
|
||||
import moment from "moment";
|
||||
|
||||
window.Vue = require('vue');
|
||||
// window.Vue = require('vue');
|
||||
|
||||
/**
|
||||
* Next, we will create a fresh Vue application instance and attach it to
|
||||
@ -15,8 +16,59 @@ window.Vue = require('vue');
|
||||
* or customize the JavaScript scaffolding to fit your unique needs.
|
||||
*/
|
||||
|
||||
Vue.component('example-component', require('./components/ExampleComponent.vue'));
|
||||
// Vue.component('example-component', require('./components/ExampleComponent.vue'));
|
||||
|
||||
const app = new Vue({
|
||||
el: '#app'
|
||||
// const app = new Vue({
|
||||
// el: '#app'
|
||||
// });
|
||||
|
||||
function updateTime() {
|
||||
var dates = document.getElementsByClassName("takenItemDate");
|
||||
for (let i = 0; i < dates.length; i++) {
|
||||
let time = dates.item(i).innerText;
|
||||
let fromNow = moment(time).fromNow();
|
||||
let id = "itemPassedTime_" + dates.item(i).id;
|
||||
document.getElementById(id).innerText = fromNow;
|
||||
}
|
||||
}
|
||||
updateTime();
|
||||
setInterval(updateTime, 1 * 60 * 1000);
|
||||
|
||||
|
||||
function setFaviconNumber(number) {
|
||||
var canvas = document.createElement('canvas'),
|
||||
ctx,
|
||||
img = document.createElement('img'),
|
||||
link = document.getElementById('favicon').cloneNode(true);
|
||||
|
||||
if (canvas.getContext) {
|
||||
canvas.height = canvas.width = 48; // set the size
|
||||
ctx = canvas.getContext('2d');
|
||||
img.onload = function () { // once the image has loaded
|
||||
ctx.drawImage(this, 0, 0);
|
||||
ctx.font = 'bold 35px "helvetica", sans-serif';
|
||||
ctx.fillStyle = '#ffff66';
|
||||
ctx.fillText(number, 3, 25);
|
||||
link.href = canvas.toDataURL('image/png');
|
||||
document.body.appendChild(link);
|
||||
};
|
||||
img.src = 'favicon.png';
|
||||
}
|
||||
};
|
||||
|
||||
usedItems = document.getElementById("usedItems").innerText;
|
||||
setFaviconNumber(usedItems);
|
||||
|
||||
/**
|
||||
* Source:
|
||||
* https://www.designcise.com/web/tutorial/how-to-detect-if-the-browser-tab-is-active-or-not-using-javascript
|
||||
*/
|
||||
document.addEventListener('visibilitychange', function (event) {
|
||||
if (document.hidden) {
|
||||
console.log('not visible');
|
||||
} else {
|
||||
updateTime();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
54
resources/js/bootstrap.js
vendored
54
resources/js/bootstrap.js
vendored
@ -1,18 +1,5 @@
|
||||
|
||||
window._ = require('lodash');
|
||||
window.Popper = require('popper.js').default;
|
||||
|
||||
/**
|
||||
* We'll load jQuery and the Bootstrap jQuery plugin which provides support
|
||||
* for JavaScript based Bootstrap features such as modals and tabs. This
|
||||
* code may be modified to fit the specific needs of your application.
|
||||
*/
|
||||
|
||||
try {
|
||||
window.$ = window.jQuery = require('jquery');
|
||||
|
||||
require('bootstrap');
|
||||
} catch (e) {}
|
||||
import _ from 'lodash';
|
||||
window._ = _;
|
||||
|
||||
/**
|
||||
* We'll load the axios HTTP library which allows us to easily issue requests
|
||||
@ -20,37 +7,28 @@ try {
|
||||
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
||||
*/
|
||||
|
||||
window.axios = require('axios');
|
||||
import axios from 'axios';
|
||||
window.axios = axios;
|
||||
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
/**
|
||||
* Next we will register the CSRF Token as a common header with Axios so that
|
||||
* all outgoing HTTP requests automatically have it attached. This is just
|
||||
* a simple convenience so we don't have to attach every token manually.
|
||||
*/
|
||||
|
||||
let token = document.head.querySelector('meta[name="csrf-token"]');
|
||||
|
||||
if (token) {
|
||||
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
|
||||
} else {
|
||||
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo exposes an expressive API for subscribing to channels and listening
|
||||
* for events that are broadcast by Laravel. Echo and event broadcasting
|
||||
* allows your team to easily build robust real-time web applications.
|
||||
*/
|
||||
|
||||
// import Echo from 'laravel-echo'
|
||||
import Echo from 'laravel-echo';
|
||||
|
||||
// window.Pusher = require('pusher-js');
|
||||
import Pusher from 'pusher-js';
|
||||
window.Pusher = Pusher;
|
||||
|
||||
// window.Echo = new Echo({
|
||||
// broadcaster: 'pusher',
|
||||
// key: process.env.MIX_PUSHER_APP_KEY,
|
||||
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
|
||||
// encrypted: true
|
||||
// });
|
||||
window.Echo = new Echo({
|
||||
broadcaster: 'pusher',
|
||||
key: import.meta.env.VITE_PUSHER_APP_KEY,
|
||||
wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
|
||||
wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
|
||||
wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
|
||||
forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
|
||||
enabledTransports: ['ws', 'wss'],
|
||||
});
|
||||
|
@ -1,23 +0,0 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card card-default">
|
||||
<div class="card-header">Example Component</div>
|
||||
|
||||
<div class="card-body">
|
||||
I'm an example component.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
console.log('Component mounted.')
|
||||
}
|
||||
}
|
||||
</script>
|
10
resources/js/pusher.js
vendored
Normal file
10
resources/js/pusher.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import 'https://js.pusher.com/7.2/pusher.min.js';
|
||||
var pusher = new Pusher('93b3e504421787295454', {
|
||||
cluster: 'us2'
|
||||
});
|
||||
|
||||
var channel = pusher.subscribe('touchedItem');
|
||||
channel.bind('RefreshPage', function(data) {
|
||||
window.location.reload();
|
||||
console.log(JSON.stringify(data));
|
||||
});
|
@ -14,8 +14,10 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
|
||||
@csrf
|
||||
{{ __('Before proceeding, please check your email for a verification link.') }}
|
||||
{{ __('If you did not receive the email') }}, <a href="{{ route('verification.resend') }}">{{ __('click here to request another') }}</a>.
|
||||
{{ __('If you did not receive the email') }}, <button type="submit" class="btn btn-link p-0 m-0 align-baseline">{{ __('click here to request another') }}</button>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,12 +1,18 @@
|
||||
@component('mail::message')
|
||||
Hi, {{$username}},
|
||||
<br>
|
||||
<br>
|
||||
#Good news: {{$item->name}} is available!
|
||||
<br>
|
||||
The item <em>{{$item->name}} ({{$item->product->name}})</em> is now available on **Share It**.
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://shareit.brunofontes.net/home">Take it</a> before anyone else.
|
||||
{!! __('Hi, :username,', ['username' => $username]) !!}
|
||||
|
||||
|
||||
#{!! __('Good news: :itemname is available!', ['itemname' => $item->name]) !!}
|
||||
|
||||
|
||||
{!! __('The item <em>:itemname (:productname)</em> is now available on **Share It**.', ['itemname' => $item->name, 'productname' => $item->product->name]) !!}
|
||||
|
||||
|
||||
{!! __('**Take It** before anyone else at the website:') !!}
|
||||
|
||||
|
||||
@component('mail::button', ['url' => 'https://shareit.brunofontes.net/home'])
|
||||
{{ config('app.name') }}
|
||||
@endcomponent
|
||||
|
||||
@endcomponent
|
@ -1,16 +1,20 @@
|
||||
@component('mail::message')
|
||||
Hello, {{$userWithItem}},
|
||||
{!! __('Hi, :username,', ['username' => $userWithItem]) !!}
|
||||
|
||||
Are you still using {{$item->name}}?
|
||||
|
||||
We just want to let you know that {{$waitingUser}} asked us to be alerted when this item were available.
|
||||
{!! __('Are you still using :itemname?', ['itemname' => $item->name]) !!}
|
||||
|
||||
|
||||
{!! __('We just want to let you know that :waitinguser asked us to be alerted when this item were available.', ['waitinguser' => $waitingUser]) !!}
|
||||
|
||||
|
||||
{!! __('So, if you are not using it anymore, please **Return It** at the website:') !!}
|
||||
|
||||
So, if you are not using it anymore, please go to our site and...
|
||||
|
||||
@component('mail::button', ['url' => 'https://shareit.brunofontes.net/home'])
|
||||
Return it!
|
||||
Share It!
|
||||
@endcomponent
|
||||
|
||||
Thanks,<br>
|
||||
{{ config('app.name') }}
|
||||
@endcomponent
|
||||
@endcomponent
|
@ -1,14 +1,17 @@
|
||||
@component('mail::message')
|
||||
# Welcome, {{$user->name}},
|
||||
# @lang('Welcome, :username,', ['username' => $user->name])
|
||||
|
||||
Thank's for registering at **Share It!**
|
||||
|
||||
Your account was created and it is active. And you? Are you ready to Share It with your friends? :)
|
||||
@lang("Thank's for registering at **Share It!**")
|
||||
|
||||
|
||||
@lang("Your account was created, but you still need to activate it. We've sent you another e-mail and we are ready to go!")
|
||||
|
||||
|
||||
@lang("And you? Are you ready to Share It with your friends?")
|
||||
|
||||
|
||||
@component('mail::button', ['url' => 'https://shareit.brunofontes.net'])
|
||||
Share it!
|
||||
@endcomponent
|
||||
|
||||
Thanks,<br>
|
||||
{{ config('app.name') }}
|
||||
@endcomponent
|
||||
@endcomponent
|
@ -4,26 +4,16 @@
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="row"><h1>Help...</h1></div>
|
||||
<div class="row"><h1>{!! __('help.helpTitle') !!}</h1></div>
|
||||
<div class="card">
|
||||
<div class="card-header"><strong>What is it?</strong></div>
|
||||
<div class="card-header"><strong>{!! __('help.whatIsIt') !!}</strong></div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
<strong>Share It!</strong> is a site dedicated to help you sharing items with others.
|
||||
</p>
|
||||
<p>But before sharing anything, you just need to understand 2 basic ideas:</p>
|
||||
{!! __('help.siteHelpOthers') !!}
|
||||
<p class="my-4"><ul>
|
||||
<li><strong>Product</strong> - The category that has some similar items</li>
|
||||
<li><strong>Item</strong> - The item that will be shared. Every item belongs to a <strong>Product</strong></li>
|
||||
{!! __('help.product_item') !!}
|
||||
</ul></p>
|
||||
<p class="my-4"><strong><em>Examples:</em></strong> You can create the following Categories/Items</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Books -> Don Quixote, The Hitchhiker's Guide to the Galaxy</li>
|
||||
<li>Matrix Movies -> Matrix 1, Matrix 2, Matrix 3</li>
|
||||
<li>Website Y -> <em>YourAccount</em>*</li>
|
||||
</ul>
|
||||
<p><em>* Please note that many websites does not allow sharing your account. Read the site EULA before include it here.</em></p>
|
||||
<p class="my-4">
|
||||
{!! __('help.examples') !!}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -32,31 +22,24 @@
|
||||
<div class="row justify-content-center mt-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header"><strong>Step-by-step</strong></div>
|
||||
<div class="card-header"><strong>{!! __('help.step_title') !!}</strong></div>
|
||||
<div class="card-body">
|
||||
<div>
|
||||
<strong>Sharing a product/item</strong>
|
||||
<strong>{!! __('help.step_sharing_subtitle') !!}</strong>
|
||||
<ol>
|
||||
<li>Go to the <strong><a href="/product">Products</a></strong> page;</li>
|
||||
<li>Include the Product and click on it;</li>
|
||||
<li>Include an Item that belongs to that Product and click on it;</li>
|
||||
<li>Add other people with their subscribed e-mail address.</li>
|
||||
{!! __('help.step_sharing_steps') !!}
|
||||
</ol>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Using a shared item</strong>
|
||||
<strong>{!! __('help.step_sharedItem_subtitle') !!}</strong>
|
||||
<ol>
|
||||
<li>Go to the <strong><a href="/home">Home</a></strong> page (tip: add this page as a bookmark);</li>
|
||||
<li>Click on <strong>Take</strong> to take the item you want to use;</li>
|
||||
<li>When you finish using it, click on <strong>Return</strong> button.</li>
|
||||
{!! __('help.step_sharedItem_steps') !!}
|
||||
</ol>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Getting alerted when an item is available</strong>
|
||||
<strong>{!! __('help.step_getAlerted_subtitle') !!}</strong>
|
||||
<ol>
|
||||
<li>Go to the <strong><a href="/home">Home</a></strong> page (tip: add this page as a bookmark);</li>
|
||||
<li>Click on <strong>Alert me</strong> next the taken item;</li>
|
||||
<li>The active user will be alerted you want to use it later. When the person return it, you will be notified.</li>
|
||||
{!! __('help.step_getAlerted_steps') !!}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
@ -66,23 +49,16 @@
|
||||
<div class="row justify-content-center mt-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header"><strong>Screens</strong></div>
|
||||
<div class="card-header"><strong>{!! __('help.screens_title') !!}</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center mt-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header"><strong>Home</strong></div>
|
||||
<div class="card-header"><strong>{!! __('help.home_title') !!}</strong></div>
|
||||
<div class="card-body">
|
||||
<p>The <strong>Home</strong> is the main screen where you will going to <strong>Take</strong>
|
||||
and <strong>Return</strong> items.</p>
|
||||
<p>It shows all items that were shared with you or that you are sharing, unless you remove yourself from there.</p>
|
||||
<p>If the item has a website, the items name will become a link, so you can just click on it to open.</p>
|
||||
<p>When the item you want is already taken, you are going to see who got it and for how long.
|
||||
So you can identify if the person is still using it or if someone just forgot to return it.</p>
|
||||
<p>You can also ask to be alerted when the item is available. This will notify the active
|
||||
user that you want to use that item. So the person can return it as soon as they finish using it.</p>
|
||||
{!! __('help.home_body') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -90,12 +66,9 @@
|
||||
<div class="row justify-content-center mt-4">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header"><strong>Products</strong></div>
|
||||
<div class="card-header"><strong>{!! __('help.products_title') !!}</strong></div>
|
||||
<div class="card-body">
|
||||
<p>The <strong>Products</strong> is the screen to include Products and Items.</p>
|
||||
<p>You can also <strong>add users</strong> to your items from this screen.
|
||||
To be able to do that you just need to select the item.</p>
|
||||
<p class="mb-4">When adding a Product, you can specify a webpage (this is optional).</p>
|
||||
{!! __('help.products_body') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,45 +1,48 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
@vite('resources/js/pusher.js')
|
||||
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">Your items</div>
|
||||
@forelse ($products as $items)
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">{{$items->first()->product->name}}</div>
|
||||
<div class="card-body">
|
||||
@if (session('status'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@forelse ($items->sortBy('name', SORT_NATURAL | SORT_FLAG_CASE) as $item)
|
||||
@if (!$loop->first)
|
||||
<hr class="m-3">
|
||||
@endif
|
||||
|
||||
@forelse ($items as $item)
|
||||
@if (!$loop->first)
|
||||
<hr class="m-3">
|
||||
@endif
|
||||
<div class="my-4 p-2">
|
||||
<div class="row align-items-center p-2">
|
||||
<div class="col col-xs-auto">
|
||||
@if ($item->product->url)
|
||||
<a href="{{$item->product->url}}" class="link-unstyled" target="_blank" rel="noopener noreferrer">
|
||||
@endif
|
||||
<a href="{{$item->product->url}}" class="link-unstyled" target="_blank" rel="noopener noreferrer">
|
||||
@endif
|
||||
|
||||
<strong>{{$item->name}}</strong> ({{$item->product->name}})
|
||||
<strong>{{$item->name}}</strong>
|
||||
|
||||
@if ($item->product->url)
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if ($item->used_by)
|
||||
@include('home.usedItem')
|
||||
@else
|
||||
@include('home.unusedItem')
|
||||
@if ($item->product->url)
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
<div class="ml-auto align-self-end text-right">
|
||||
@if ($item->used_by)
|
||||
@include('home.usedItem')
|
||||
@else
|
||||
@include('home.unusedItem')
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p>There are no items shared with you yet. <a href="/product">Share an item!</a></p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p>@lang('home.no_messages') <a href="/product">@lang('home.share_item')</a></p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@endsection
|
||||
|
@ -1,7 +1,5 @@
|
||||
<span class="float-right">
|
||||
<form action="/take" method="POST">
|
||||
{{ csrf_field() }}
|
||||
<input type="hidden" name="item" value="{{$item->id}}">
|
||||
<button type="submit" class="btn btn-sm btn-success">Take It</button>
|
||||
</form>
|
||||
</span>
|
||||
<form action="/take" method="POST">
|
||||
{{ csrf_field() }}
|
||||
<input type="hidden" name="item" value="{{$item->id}}">
|
||||
<button type="submit" class="btn btn-sm btn-success">@lang('home.take')</button>
|
||||
</form>
|
@ -1,35 +1,33 @@
|
||||
@if ($item->used_by == \Auth::id())
|
||||
<span class="float-right">
|
||||
<form action="/take" method="POST">
|
||||
{{ csrf_field() }}
|
||||
@method('DELETE')
|
||||
<input type="hidden" name="item" value="{{$item->id}}">
|
||||
<button type="submit" class="btn btn-sm btn-danger">Return It</button>
|
||||
</form>
|
||||
</span>
|
||||
<span class="float-right mr-3"><em>{{\Carbon\Carbon::parse($item->updated_at)->diffForHumans()}}</em></span>
|
||||
<form action="/take" method="POST" class="form-inline">
|
||||
<em id="itemPassedTime_{{$item->id}}" class="pr-sm-2 ml-auto">{{\Carbon\Carbon::parse($item->updated_at)->diffForHumans()}}</em>
|
||||
<div hidden class="takenItemDate" id="{{$item->id}}">{{\Carbon\Carbon::parse($item->updated_at)->format('Y-m-d\TH:i:s.uP')}}</div>
|
||||
<div class="w-100 d-xm-block d-sm-none"></div>
|
||||
{{ csrf_field() }}
|
||||
@method('DELETE')
|
||||
<input type="hidden" name="item" value="{{$item->id}}">
|
||||
<button type="submit" class="btn btn-sm btn-danger ml-auto">@lang('home.return')</button>
|
||||
</form>
|
||||
|
||||
|
||||
@else
|
||||
<span class="float-right">
|
||||
<form action="/alert" method="POST">
|
||||
{{ csrf_field() }}
|
||||
<input type="hidden" name="item" value="{{$item->id}}">
|
||||
@if ($item->waiting_user_id == \Auth::id())
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">Cancel Alert</button>
|
||||
@elseif (!$item->waiting_user_id)
|
||||
<button type="submit" class="btn btn-sm btn-outline-secondary">Alert me</button>
|
||||
@endif
|
||||
</form>
|
||||
</span>
|
||||
<span class="float-right mr-3">
|
||||
<em>
|
||||
{{str_limit($users[$item->used_by], 15, '...')}}
|
||||
@if ($item->waiting_user_id && $item->waiting_user_id != \Auth::id())
|
||||
<strong>> {{str_limit($users[$item->waiting_user_id], 15, '...')}}</strong>
|
||||
@endif
|
||||
<small>({{$item->updated_at->diffForHumans()}})</small>
|
||||
</em>
|
||||
</span>
|
||||
@endif
|
||||
<form action="/alert" method="POST" class="form-inline">
|
||||
<em class="pr-sm-2 ml-auto">
|
||||
{{str_limit($users[$item->used_by], 15, '...')}}
|
||||
@if ($item->waiting_user_id && $item->waiting_user_id != \Auth::id())
|
||||
<strong>> {{str_limit($users[$item->waiting_user_id], 15, '...')}}</strong>
|
||||
@endif
|
||||
<small id="itemPassedTime_{{$item->id}}">({{$item->updated_at->diffForHumans()}})</small>
|
||||
</em>
|
||||
<div hidden class="takenItemDate" id="{{$item->id}}">{{$item->updated_at->format('Y-m-d\TH:i:s.uP')}}</div>
|
||||
<div class="w-100 d-xm-block d-sm-none"></div>
|
||||
{{ csrf_field() }}
|
||||
<input type="hidden" name="item" value="{{$item->id}}">
|
||||
@if ($item->waiting_user_id == \Auth::id())
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger ml-auto">@lang('home.cancel_alert')</button>
|
||||
@elseif (!$item->waiting_user_id)
|
||||
<button type="submit" class="btn btn-sm btn-outline-secondary ml-auto">@lang('home.alert_me')</button>
|
||||
@endif
|
||||
</form>
|
||||
@endif
|
||||
|
@ -29,7 +29,7 @@
|
||||
@include ('item.otherItems')
|
||||
|
||||
|
||||
<div class="float-right mt-2"><a class="btn btn-secondary" href="/product/{{ $item->product->id }}">BACK</a></div>
|
||||
<div class="float-right mt-2"><a class="btn btn-secondary" href="/product/{{ $item->product->id }}">{{ __('item.back') }}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,22 +5,22 @@
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="deleteModalLabel">Confirmation...</h5>
|
||||
<h5 class="modal-title" id="deleteModalLabel">{{ __('item.confirmation') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Would you like to delete the item <strong>{{$item->name}}</strong>?</p>
|
||||
<p>You will not be able to restore it after deletion.</p>
|
||||
<p>{!! __('item.confirmDeletion', ['itemname' => $item->name]) !!}</p>
|
||||
<p>{!! __('item.notAbleRestore') !!}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ __('item.close') }}</button>
|
||||
<form action="/item/" method="POST">
|
||||
@method('DELETE')
|
||||
{{ csrf_field() }}
|
||||
<input type="hidden" name="item" value="{{$item->id}}">
|
||||
<button type="submit" class="btn btn-danger">Delete</button>
|
||||
<button type="submit" class="btn btn-danger">{{ __('item.delete') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,11 +1,11 @@
|
||||
<button type="button" class="btn btn-sm btn-secondary mr-1" data-toggle="modal" data-target="#editModal">Edit</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary mr-1" data-toggle="modal" data-target="#editModal">{{ __('item.edit') }}</button>
|
||||
|
||||
<!-- MODAL - CHANGE WINDOW -->
|
||||
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="editModalLabel">Edit item</h5>
|
||||
<h5 class="modal-title" id="editModalLabel">{{ __('item.edititem') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
@ -14,7 +14,7 @@
|
||||
<form action="/item" method="POST">
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-form-label">New name: </label>
|
||||
<label for="name" class="col-form-label">{{ __('item.newname') }} </label>
|
||||
<input type="text" name="name" id="name" class="form-control" value="{{$item->name}}">
|
||||
</div>
|
||||
</div>
|
||||
@ -22,8 +22,8 @@
|
||||
@method('PATCH')
|
||||
{{ csrf_field() }}
|
||||
<input type="hidden" name="item" value="{{$item->id}}">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-danger">Edit</button>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ __('item.close') }}</button>
|
||||
<button type="submit" class="btn btn-danger">{{ __('item.edit') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="card mt-4">
|
||||
<div class="card-header">
|
||||
Other items from the same product
|
||||
{{ __('item.otherItems') }}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
@ -10,7 +10,7 @@
|
||||
<li><a href="/item/{{ $otherItem->id }}">{{ $otherItem->name }}</a></li>
|
||||
@endif
|
||||
@empty
|
||||
<p>There are no items yet. Include one with the form above.</p>
|
||||
<p>{{ __('item.noItems') }}</p>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<p><strong>Users:</strong></p>
|
||||
<p><strong>{{ __('item.users') }}</strong></p>
|
||||
@forelse ($users as $user)
|
||||
@if (!$loop->first)
|
||||
<hr>
|
||||
@ -14,27 +14,27 @@
|
||||
@method('DELETE')
|
||||
<input type="hidden" name="item_id" id="item_id" value="{{ $item['id'] }}">
|
||||
<input type="hidden" class="form-control" name="user_id" id="user_id" value="{{$user->id}}">
|
||||
<button type="submit" class="btn btn-sm btn-danger">Delete</button>
|
||||
<button type="submit" class="btn btn-sm btn-danger">{{ __('item.delete') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@empty
|
||||
<p>There are no items yet. Include one with the form above.</p>
|
||||
<p>{{ __('item.noItems') }}</p>
|
||||
@endforelse
|
||||
|
||||
|
||||
<!-- ADD USERS -->
|
||||
<hr class="mt-5">
|
||||
<p><strong>Add user</strong></p>
|
||||
<p><strong>{{ __('item.addUser') }}</strong></p>
|
||||
<form method="POST" action="/user">
|
||||
<div class="container-fluid">
|
||||
<div class="form-group row mt-2">
|
||||
{{ csrf_field() }}
|
||||
<div class="col-sm-2 col-lg-auto"><label for="name">E-mail: </label></div>
|
||||
<div class="col-xs-12 col-sm mb-3"><input type="email" class="form-control" name="email" id="email" placeholder="name@domain.com" required></div>
|
||||
<div class="col-sm-2 col-lg-auto"><label for="name">{{ __('item.email') }}</label></div>
|
||||
<div class="col-xs-12 col-sm mb-3"><input type="email" class="form-control" name="email" id="email" placeholder="{{ __('item.nameDomain') }}" required></div>
|
||||
<input type="hidden" name="item_id" id="item_id" value="{{ $item['id'] }}" required>
|
||||
<div class="col-sm-2 col-lg-1 mr-4"><button type="submit" class="btn btn-primary">Insert</button></div>
|
||||
<div class="col-sm-2 col-lg-1 mr-4"><button type="submit" class="btn btn-primary">{{ __('item.insert') }}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
@ -7,10 +8,10 @@
|
||||
<!-- CSRF Token -->
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
<title>{{ config('app.name', 'Laravel') }}</title>
|
||||
<title>{{ config('app.name', 'Laravel') }} {{ isset($usedItems) && $usedItems > 0 ? "(${usedItems})" : '' }}</title>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="{{ asset('js/app.js') }}" defer></script>
|
||||
@vite('resources/js/app.js')
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
|
||||
@ -18,15 +19,20 @@
|
||||
|
||||
<!-- Styles -->
|
||||
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
|
||||
|
||||
<link id="favicon" rel="icon" type="image/png" href="favicon.png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div hidden id="usedItems">{{ isset($usedItems) && $usedItems > 0 ? $usedItems : '' }}</div>
|
||||
<div id="app">
|
||||
<nav class="navbar navbar-expand-md navbar-light navbar-laravel">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="{{ url('/') }}">
|
||||
{{ config('app.name', 'Laravel') }}
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
||||
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
@ -40,39 +46,49 @@
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<!-- Authentication Links -->
|
||||
@guest
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="nav-item dropdown">
|
||||
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
|
||||
{{ Auth::user()->name }} <span class="caret"></span>
|
||||
<li class="nav-item dropdown">
|
||||
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false" v-pre>
|
||||
{{ Auth::user()->name }} <span class="caret"></span>
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item" href="{{ route('logout') }}" onclick="event.preventDefault();
|
||||
document.getElementById('logout-form').submit();">
|
||||
{{ __('Logout') }}
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item" href="{{ route('logout') }}"
|
||||
onclick="event.preventDefault();
|
||||
document.getElementById('logout-form').submit();">
|
||||
{{ __('Logout') }}
|
||||
</a>
|
||||
|
||||
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
|
||||
@csrf
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
|
||||
@csrf
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
@endguest
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="py-4">
|
||||
@if ($flashMsg = session('primary'))
|
||||
<div class="alert alert-primary text-center" role="alert">{{ $flashMsg }}</div>
|
||||
@endif
|
||||
@if ($flashMsg = session('danger'))
|
||||
<div class="alert alert-danger text-center" role="alert">{{ $flashMsg }}</div>
|
||||
@endif
|
||||
|
||||
<main class="py-4 mb-5">
|
||||
@yield('content')
|
||||
</main>
|
||||
|
||||
@include('layouts.footer')
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
20
resources/views/layouts/footer.blade.php
Normal file
20
resources/views/layouts/footer.blade.php
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
<div class="my-4"><br></div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="fixed-bottom page-footer font-small mt-5">
|
||||
<div class="row footer-copyright text-left bg-secondary text-white mt-5 py-3">
|
||||
<!-- Copyright -->
|
||||
<div class="col ml-4">
|
||||
© 2018<?='2018' != date('Y')?'-' . date('Y'):'';?> Copyright <a href="https://brunofontes.net" class="link text-white-50" target="_blank">Bruno Fontes</a>
|
||||
</div>
|
||||
<div class="col mr-4 text-right">
|
||||
<a href="{{ url('/lang/pt-br') }}" class="link text-white">Português</a>
|
||||
<span class="d-none d-sm-inline"> | </span>
|
||||
<span class="d-xs-block d-sm-none"> <br> </span>
|
||||
<a href="{{ url('/lang/en') }}" class="link text-white">English</a>
|
||||
</div>
|
||||
<!-- Copyright -->
|
||||
</div>
|
||||
</footer>
|
||||
@include('layouts.tracker')
|
3
resources/views/layouts/tracker.blade.php
Normal file
3
resources/views/layouts/tracker.blade.php
Normal file
@ -0,0 +1,3 @@
|
||||
<script type="text/javascript">
|
||||
var owa_baseUrl='https://brunofontes.net/owa/';var owa_cmds=owa_cmds||[];owa_cmds.push(['setSiteId','15a38975230dfe7528d647a1419be7f7']);owa_cmds.push(['trackPageView']);owa_cmds.push(['trackClicks']);owa_cmds.push(['trackDomStream']);(function(){var _owa=document.createElement('script');_owa.type='text/javascript';_owa.async=true;owa_baseUrl=('https:'==document.location.protocol?window.owa_baseSecUrl||owa_baseUrl.replace(/http:/,'https:'):owa_baseUrl);_owa.src=owa_baseUrl+'modules/base/js/owa.tracker-combined-min.js';var _owa_s=document.getElementsByTagName('script')[0];_owa_s.parentNode.insertBefore(_owa,_owa_s)}());
|
||||
</script>
|
@ -3,10 +3,10 @@
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="form-group row mt-2">
|
||||
<div class="col-sm-2 col-lg-1"><label for="product">Item:</label></div>
|
||||
<div class="col-xs-12 col-sm mb-3"><input type="text" class="form-control" name="item" id="item" placeholder="One Hundred Years of Solitude" required></div>
|
||||
<div class="col-sm-2 col-lg-1"><label for="product">{{ __('product.item') }}</label></div>
|
||||
<div class="col-xs-12 col-sm mb-3"><input type="text" class="form-control" name="item" id="item" placeholder="{{ __('product.100yearsSolitude') }}" required></div>
|
||||
<input type="hidden" name="product_id" id="product_id" value="{{ $product['id'] }}" required>
|
||||
<div class="col-sm-2 col-lg-1 mr-4"><button type="submit" class="btn btn-primary">Insert</button></div>
|
||||
<div class="col-sm-2 col-lg-1 mr-4"><button type="submit" class="btn btn-primary">{{ __('product.insert') }}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2,16 +2,16 @@
|
||||
{{ csrf_field() }}
|
||||
<div class="container-fluid">
|
||||
<div class="form-group row mt-2">
|
||||
<div class="col-sm-2 col-lg-1"><label for="product">Name:</label></div>
|
||||
<div class="col-xs-12 col-sm"><input type="text" class="form-control" name="product" id="product" placeholder="Book" required></div>
|
||||
<div class="col-sm-2 col-lg-1"><label for="product">{{ __('product.name') }}</label></div>
|
||||
<div class="col-xs-12 col-sm"><input type="text" class="form-control" name="product" id="product" placeholder="{{ __('product.book') }}" required></div>
|
||||
</div>
|
||||
<div class="form-group row mt-2">
|
||||
<div class="col-sm-2 col-lg-1"><label for="product">URL:</label></div>
|
||||
<div class="col-xs-12 col-sm"><input type="text" class="form-control" name="url" id="url" placeholder="(Optional) http://bookwebsite.com"></div>
|
||||
<div class="col-sm-2 col-lg-1"><label for="product">{{ __('product.url') }}</label></div>
|
||||
<div class="col-xs-12 col-sm"><input type="text" class="form-control" name="url" id="url" placeholder="{{ __('product.optionalUrlExample') }}"></div>
|
||||
</div>
|
||||
<div class="form-group row mt-2">
|
||||
<div class="col-xs-0 col-sm-1 col-md-1 col-lg-1 col-xg-1"></div>
|
||||
<div class="col col-xs-12"><button type="submit" class="btn btn-primary">Insert</button></div>
|
||||
<div class="col col-xs-12"><button type="submit" class="btn btn-primary">{{ __('product.insert') }}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
@include ('layouts.errors')
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user