├── screenshots ├── auth.png ├── error.png └── example.png ├── mix-manifest.json ├── resources ├── js │ ├── card.js │ └── components │ │ └── Card.vue └── sass │ └── card.scss ├── webpack.mix.js ├── .gitignore ├── dist ├── css │ └── card.css └── js │ └── card.js ├── src ├── Http │ └── Controllers │ │ └── PaypalController.php ├── Paypal.php └── CardServiceProvider.php ├── routes └── api.php ├── composer.json ├── package.json ├── README.md └── main.js /screenshots/auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naifalshaye/nova-paypal/HEAD/screenshots/auth.png -------------------------------------------------------------------------------- /screenshots/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naifalshaye/nova-paypal/HEAD/screenshots/error.png -------------------------------------------------------------------------------- /screenshots/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naifalshaye/nova-paypal/HEAD/screenshots/example.png -------------------------------------------------------------------------------- /mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/dist/js/card.js": "/dist/js/card.js", 3 | "/dist/css/card.css": "/dist/css/card.css" 4 | } -------------------------------------------------------------------------------- /resources/js/card.js: -------------------------------------------------------------------------------- 1 | Nova.booting((Vue, router) => { 2 | Vue.component('paypal', require('./components/Card')); 3 | }) 4 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | let mix = require('laravel-mix') 2 | 3 | mix.js('resources/js/card.js', 'dist/js') 4 | .sass('resources/sass/card.scss', 'dist/css') 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | /node_modules 4 | package-lock.json 5 | composer.phar 6 | composer.lock 7 | phpunit.xml 8 | .phpunit.result.cache 9 | .DS_Store 10 | Thumbs.db 11 | /screenshots/ 12 | -------------------------------------------------------------------------------- /resources/sass/card.scss: -------------------------------------------------------------------------------- 1 | // Nova Card CSS 2 | @keyframes spinner { 3 | to {transform: rotate(360deg);} 4 | } 5 | .spinner:before { 6 | content: ''; 7 | box-sizing: border-box; 8 | position: absolute; 9 | width: 45px; 10 | height: 45px; 11 | margin-top: 20px; 12 | margin-left: -15px; 13 | border-radius: 50%; 14 | border: 3px solid #ccc; 15 | border-top-color: #07d; 16 | animation: spinner .6s linear infinite; 17 | } -------------------------------------------------------------------------------- /dist/css/card.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes spinner{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes spinner{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.spinner:before{content:"";-webkit-box-sizing:border-box;box-sizing:border-box;position:absolute;width:45px;height:45px;margin-top:20px;margin-left:-15px;border-radius:50%;border:3px solid #ccc;border-top-color:#07d;-webkit-animation:spinner .6s linear infinite;animation:spinner .6s linear infinite} -------------------------------------------------------------------------------- /src/Http/Controllers/PaypalController.php: -------------------------------------------------------------------------------- 1 | get('days'); 15 | $count = $request->get('count'); 16 | $paypal = new LaravelPayPal(); 17 | $response['balance'] = $paypal->getBalance(); 18 | $response['transactions'] = $paypal->getTransactions($days,$count); 19 | return $response; 20 | } 21 | } -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- 1 | =7.1.0", 12 | "naif/laravel-paypal": "dev-master" 13 | }, 14 | "autoload": { 15 | "psr-4": { 16 | "Naif\\Paypal\\": "src/" 17 | } 18 | }, 19 | "extra": { 20 | "laravel": { 21 | "providers": [ 22 | "Naif\\Paypal\\CardServiceProvider" 23 | ] 24 | } 25 | }, 26 | "config": { 27 | "sort-packages": true 28 | }, 29 | "minimum-stability": "dev", 30 | "prefer-stable": true 31 | } 32 | -------------------------------------------------------------------------------- /src/Paypal.php: -------------------------------------------------------------------------------- 1 | withMeta([ 29 | 'days' => $days 30 | ]); 31 | return $this; 32 | } 33 | 34 | public function count($count = 10) 35 | { 36 | $this->withMeta([ 37 | 'count' => $count 38 | ]); 39 | return $this; 40 | } 41 | 42 | public function hideLogo($hide = false) 43 | { 44 | $this->withMeta([ 45 | 'hide_logo' => $hide 46 | ]); 47 | return $this; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "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", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "cross-env": "^5.0.0", 14 | "laravel-mix": "^1.0" 15 | }, 16 | "dependencies": { 17 | "vue": "^2.5.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nova PayPal Card 2 | 3 | A Laravel Nova card to display PayPal current balance and latest transactions. 4 | 5 | ## Installation: 6 | 7 | You can install the package in to a Laravel app that uses Nova via composer: 8 | 9 | ```bash 10 | composer require naif/paypal 11 | ``` 12 | 13 | ## Usage: 14 |

Add the below to the card function in app/Providers/NovaServiceProvider.php

15 | 16 | ```php 17 | 18 | protected function cards() 19 | { 20 | return [ 21 | (new Paypal()) 22 | 23 | //you can set days to retrieve transacitons 24 | (new Paypal())->days(3) //default last 5 days 25 | 26 | //you can specifivy how many transactions to retreive 27 | (new Paypal())->count(5) //default is 10 transactions 28 | 29 | //you can hide PayPal logo 30 | (new Paypal())->hideLogo(true) //default false 31 | 32 | //Example for all options 33 | (new Paypal())->days(3)->count(5)->hideLogo(true) 34 | ]; 35 | } 36 | ``` 37 | 38 | ## Support: 39 | naif@naif.io 40 | 41 | https://www.linkedin.com/in/naif 42 | 43 | ## License: 44 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 45 | -------------------------------------------------------------------------------- /src/CardServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->booted(function () { 20 | $this->routes(); 21 | }); 22 | 23 | Nova::serving(function (ServingNova $event) { 24 | Nova::script('paypal', __DIR__.'/../dist/js/card.js'); 25 | Nova::style('paypal', __DIR__.'/../dist/css/card.css'); 26 | }); 27 | } 28 | 29 | /** 30 | * Register the card's routes. 31 | * 32 | * @return void 33 | */ 34 | protected function routes() 35 | { 36 | if ($this->app->routesAreCached()) { 37 | return; 38 | } 39 | 40 | Route::middleware(['nova']) 41 | ->prefix('nova-vendor/paypal') 42 | ->group(__DIR__.'/../routes/api.php'); 43 | } 44 | 45 | /** 46 | * Register any application services. 47 | * 48 | * @return void 49 | */ 50 | public function register() 51 | { 52 | // 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { 40 | /******/ configurable: false, 41 | /******/ enumerable: true, 42 | /******/ get: getter 43 | /******/ }); 44 | /******/ } 45 | /******/ }; 46 | /******/ 47 | /******/ // getDefaultExport function for compatibility with non-harmony modules 48 | /******/ __webpack_require__.n = function(module) { 49 | /******/ var getter = module && module.__esModule ? 50 | /******/ function getDefault() { return module['default']; } : 51 | /******/ function getModuleExports() { return module; }; 52 | /******/ __webpack_require__.d(getter, 'a', getter); 53 | /******/ return getter; 54 | /******/ }; 55 | /******/ 56 | /******/ // Object.prototype.hasOwnProperty.call 57 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 58 | /******/ 59 | /******/ // __webpack_public_path__ 60 | /******/ __webpack_require__.p = ""; 61 | /******/ 62 | /******/ // Load entry module and return exports 63 | /******/ return __webpack_require__(__webpack_require__.s = 7); 64 | /******/ }) 65 | /************************************************************************/ 66 | /******/ ({ 67 | 68 | /***/ 7: 69 | /***/ (function(module, exports, __webpack_require__) { 70 | 71 | (function webpackMissingModule() { throw new Error("Cannot find module \"npm\""); }()); 72 | (function webpackMissingModule() { throw new Error("Cannot find module \"run\""); }()); 73 | (function webpackMissingModule() { throw new Error("Cannot find module \"watch\""); }()); 74 | 75 | 76 | /***/ }) 77 | 78 | /******/ }); -------------------------------------------------------------------------------- /resources/js/components/Card.vue: -------------------------------------------------------------------------------- 1 | 38 | -------------------------------------------------------------------------------- /dist/js/card.js: -------------------------------------------------------------------------------- 1 | !function(t){var e={};function a(n){if(e[n])return e[n].exports;var s=e[n]={i:n,l:!1,exports:{}};return t[n].call(s.exports,s,s.exports,a),s.l=!0,s.exports}a.m=t,a.c=e,a.d=function(t,e,n){a.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},a.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return a.d(e,"a",e),e},a.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},a.p="",a(a.s=0)}([function(t,e,a){a(1),t.exports=a(6)},function(t,e,a){Nova.booting(function(t,e){t.component("paypal",a(2))})},function(t,e,a){var n=a(3)(a(4),a(5),!1,null,null,null);t.exports=n.exports},function(t,e){t.exports=function(t,e,a,n,s,i){var o,r=t=t||{},c=typeof t.default;"object"!==c&&"function"!==c||(o=t,r=t.default);var l,d="function"==typeof r?r.options:r;if(e&&(d.render=e.render,d.staticRenderFns=e.staticRenderFns,d._compiled=!0),a&&(d.functional=!0),s&&(d._scopeId=s),i?(l=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),n&&n.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(i)},d._ssrRegister=l):n&&(l=n),l){var _=d.functional,p=_?d.render:d.beforeCreate;_?(d._injectStyles=l,d.render=function(t,e){return l.call(e),p(t,e)}):d.beforeCreate=p?[].concat(p,l):[l]}return{esModule:o,exports:r,options:d}}},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={props:["card"],data:function(){return{paypal_logo:"https://www.paypalobjects.com/webstatic/en_US/mktg/pages/stories/pp_h_rgb.jpg",response:[],balance:[],hide_logo:!1,loading:!0,days:5}},mounted:function(){var t=this;1==this.card.hide_logo&&(this.hide_logo=!0,this.days=!0),this.card.days>0?this.days=this.card.days:this.days=5,Nova.request().get("/nova-vendor/paypal/getData",{params:{days:this.card.days,count:this.card.count}}).then(function(e){t.balance=e.data.balance.balance,e.data.transactions.transactions.length>0?t.transactions=e.data.transactions.transactions:t.transactions=!1,t.loading=!1,document.getElementById("spinner").style.display="none"})}}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("card",{staticClass:"h-auto"},[a("div",{staticClass:"px-3 py-3",staticStyle:{"min-height":"200px"}},[a("div",{attrs:{align:"left"}},[a("img",{directives:[{name:"show",rawName:"v-show",value:!1===t.hide_logo,expression:"hide_logo === false"}],attrs:{src:t.paypal_logo,width:"150"}}),t._v(" "),a("div",{staticClass:"spinner",attrs:{id:"spinner",align:"center"}})]),t._v(" "),a("div",{directives:[{name:"show",rawName:"v-show",value:!t.loading,expression:"!loading"}]},[a("div",{staticStyle:{"margin-bottom":"20px","font-family":"'Arial'"}},["Success"===t.balance.ACK?a("div",{staticClass:"text-center text-2lg font-light",staticStyle:{"font-size":"14px",color:"green"}},[t._v("Current Balance: $"+t._s(t.balance.L_AMT0))]):t._e(),t._v(" "),"Failure"===t.balance.ACK?a("div",{staticClass:"text-center",staticStyle:{color:"red","font-size":"12px"}},[t._v(t._s(t.balance.L_SEVERITYCODE0)+" "+t._s(t.balance.L_ERRORCODE0)+": "+t._s(t.balance.L_LONGMESSAGE0))]):t._e()]),t._v(" "),!1!==t.transactions?a("div",{staticStyle:{"margin-bottom":"20px"}},[a("table",{staticClass:"table table-bordered table-hover table-responsive",staticStyle:{"font-size":"14px","margin-left":"auto","margin-right":"auto"}},[a("tr",[a("th",[t._v("Transaction ID")]),t._v(" "),a("th",[t._v("Date")]),t._v(" "),a("th",[t._v("Amount")]),t._v(" "),a("th",[t._v("Status")])]),t._v(" "),t._l(t.transactions,function(e){return a("tr",[a("td",{staticStyle:{height:"40px","font-size":"12px"}},[a("a",{attrs:{href:"https://www.paypal.com/activity/payment/"+e.transaction_id,target:"_blank"}},[t._v(t._s(e.transaction_id))])]),t._v(" "),a("td",{staticStyle:{height:"40px"}},[t._v(t._s(e.timestamp))]),t._v(" "),a("td",{staticStyle:{height:"40px"}},[t._v("$"+t._s(e.amt))]),t._v(" "),a("td",{staticStyle:{height:"40px"}},[t._v(t._s(e.status))])])})],2)]):t._e(),t._v(" "),!1===t.transactions?a("div",{staticStyle:{"text-align":"center",color:"#db363c","font-size":"12px"}},[t._v("No transacitons found since "+t._s(this.days)+" days ago!")]):t._e()])])])},staticRenderFns:[]}},function(t,e){}]); --------------------------------------------------------------------------------