Browse Source

Populate and style recent activity pane

tags/v0.1.0
Immanuel Onyeka 3 years ago
parent
commit
95b2760840
12 changed files with 101 additions and 17 deletions
  1. +7
    -0
      app/Http/Controllers/UserController.php
  2. +6
    -1
      app/Models/Order.php
  3. +6
    -1
      database/factories/OrderFactory.php
  4. +1
    -0
      database/factories/UserFactory.php
  5. +1
    -0
      database/migrations/2021_05_18_184617_create_services_table.php
  6. +4
    -0
      database/migrations/2021_05_19_185302_create_orders_table.php
  7. +6
    -6
      database/seeders/DatabaseSeeder.php
  8. +1
    -1
      resources/js/main.js
  9. +23
    -2
      resources/js/panel/panel.vue
  10. +2
    -0
      resources/scss/_vars.scss
  11. +43
    -5
      resources/scss/main.scss
  12. +1
    -1
      routes/web.php

+ 7
- 0
app/Http/Controllers/UserController.php View File

@@ -4,6 +4,8 @@ namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Order;
use App\Models\Service;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Hash;
use Illuminate\Auth\Events\Registered;
@@ -79,7 +81,12 @@ class UserController extends Controller
return redirect('/');
}

//It should have an orderBy clause to make sure the most recent are first
//This should limit non pending orders to 50. Should also return a json of all services
public function getOrders(Request $request) {
/* Log::debug(Auth::user()->orders()->service_name); */
return Auth::user()->orders()->with('service')->withCasts(['updated_at'
=> 'datetime:d-m-Y'])->get();

}



+ 6
- 1
app/Models/Order.php View File

@@ -12,7 +12,7 @@ class Order extends Model
use HasFactory;

protected $fillable = [
'quantity'
'quantity', 'url'
];

public function service() {
@@ -22,4 +22,9 @@ class Order extends Model
public function user() {
return $this->belongsTo(User::class);
}

public function getServiceNameAttribute() {
return $this->service()->name();
}

}

+ 6
- 1
database/factories/OrderFactory.php View File

@@ -24,8 +24,13 @@ class OrderFactory extends Factory
*/
public function definition()
{
$quantity = $this->faker->numberBetween(100, 10000);
return [
'quantity' => $this->faker->randomNumber(4, false),
'quantity' => $quantity,
'status' => $this->faker->randomElement(['pending', 'completed',
'canceled', 'processing']),
'remaining' => $this->faker->numberBetween(0, $quantity),
'url' => $this->faker->url,
'service_id' => function() {
return Service::inRandomOrder()->first()->id;
},


+ 1
- 0
database/factories/UserFactory.php View File

@@ -25,6 +25,7 @@ class UserFactory extends Factory
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'url' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),


+ 1
- 0
database/migrations/2021_05_18_184617_create_services_table.php View File

@@ -20,6 +20,7 @@ class CreateServicesTable extends Migration
$table->string('name');
$table->string('type')->nullable();
$table->string('site');
$table->string('description')->default('');
$table->boolean('available');
});



+ 4
- 0
database/migrations/2021_05_19_185302_create_orders_table.php View File

@@ -19,6 +19,10 @@ class CreateOrdersTable extends Migration
$table->foreignId('service_id')->constrained();
$table->foreignId('user_id')->constrained();
$table->bigInteger('quantity');
$table->string('note')->default('');
$table->bigInteger('remaining')->default(0);
$table->string('status');
$table->string('url');
});
}



+ 6
- 6
database/seeders/DatabaseSeeder.php View File

@@ -18,37 +18,37 @@ class DatabaseSeeder extends Seeder
public function run()
{
Service::create([
'name' => 'youtube_views',
'name' => 'Youtube Views',
'type' => 'views',
'site' => 'youtube',
'available' => true,
]);
Service::create([
'name' => 'instagram_views',
'name' => 'Instagram Views',
'type' => 'views',
'site' => 'instagram',
'available' => true,
]);
Service::create([
'name' => 'spotify_plays',
'name' => 'Spotify Views',
'type' => 'plays',
'site' => 'spotify',
'available' => true,
]);
Service::create([
'name' => 'twitter_likes',
'name' => 'Twitter Likes',
'type' => 'likes',
'site' => 'spotify',
'available' => false,
]);
$test_user = User::create([
User::create([
'name' => 'test_user_unverified',
'email' => 'unverified@example.com',
'role' => 'client',
'active' => true,
'password' => Hash::make("test123")
]);
User::create([
$test_user = User::create([
'name' => 'test_user_verified',
'email' => 'verified@example.com',
'email_verified_at' => now(),


+ 1
- 1
resources/js/main.js View File

@@ -75,7 +75,6 @@ function getOrders(app) {
}).then(data => {
app.orders = data
})
/* return this.user.name */
}

//Attempt to resend the verification link
@@ -142,5 +141,6 @@ if (window.location.pathname == '/') {
const app = createApp(Panel).mount('#panel')
window.onhashchange = ()=>{app.active = location.hash}
getUser(app)
getOrders(app)
}


+ 23
- 2
resources/js/panel/panel.vue View File

@@ -7,12 +7,33 @@
<section class="alerts-pane"><h4>News and Announcements</h4>
<p>We've just launched. Thanks for joining us.</p>
</section>
<section class="recent-pane"><h4>Recent Activity</h4>Recent activity showing last 5 completed orders </section>
<section class="recent-pane"><h4>Recent Activity</h4>
<table>
<thead><th>Date</th><th>Name</th><th>Status</th> <th>Quantity</th></thead>
<tbody>
<tr v-bind:key='order.id' v-for='order in orders.slice(0, 10)'>
<template v-if="order.status != 'pending'">
<td>{{order.updated_at}}</td>
<td>{{order.service.name}}</td>
<td :class="order.status"
class="status"><span>{{order.status.charAt(0).toUpperCase() +
order.status.slice(1)}}</span></td>
<td>{{order.quantity}}</td>
</template>
</tr>
</tbody>
</table>
</section>
</div>
<div v-else-if="active === '#orders'" id="main">
<div class="actions"><a href="#orders/new">New</a></div>
<section class="pending-pane">
<h4>Pending Orders</h4>
<ul>
<template v-bind:key='order.id' v-for="order in orders">
<li v-if="order.status == 'pending'">{{order.service.name}} - {{order.updated_at}}</li>
</template>
</ul>
</section>
</div>
</transition>
@@ -27,6 +48,6 @@ export default {
},
data() {
return {active: window.location.hash, user: '',
token: ''}},
token: '', orders: ''}},
}
</script>

+ 2
- 0
resources/scss/_vars.scss View File

@@ -13,6 +13,8 @@ $theme-colors: (
"brand-orange": #f67602,
"grey": #e6ebf1,
"light-grey": #e9e9e9,
"light2-grey": rgb(190,190,190),
"light3-grey": rgb(245,245,245),
"dark-grey": #212121,
"faded-text": #425466,
"faded-text2": #6c757d,


+ 43
- 5
resources/scss/main.scss View File

@@ -43,7 +43,7 @@ ul {
padding: 0;
}

li {
.services-cards li {
padding-bottom: 8px;
&:before {
width: 30px;
@@ -721,6 +721,7 @@ main.panel {
@include vars.hovering3;
transition: opacity 0.5s ease;
vertical-align: middle;
overflow: scroll;
// text-align: center;

section {
@@ -763,10 +764,47 @@ main.panel {
}
}

// .fade-enter-active, .fade-leave-active {
// transition: opacity 1s ease;
// }

.fade-enter-from, .fade-leave-to {
opacity: 0;
}

.recent-pane {
table {
border-spacing: 4px;
margin: auto;
text-align: center;
}

th {
font-weight: normal;
color: vars.getColor("light2-grey");
}

tr {
border-bottom: 3px solid black;
}

td {
border-bottom: 2px solid vars.getColor("grey");
// color: vars.getColor("light3-grey");
// font-size: 1rem;
font-size: 0.8rem;
}

td.completed span {
background: vars.getColor('green');
color: vars.darkenColor('green');
border-radius: 4px;
padding: 2px;
}

td.processing {
color: vars.getColor('light-blue');
}

td.canceled {
color: vars.getColor('red-alert');
}

}

+ 1
- 1
routes/web.php View File

@@ -59,6 +59,6 @@ Route::get('/panel/user', function (Request $request) {
return $request->user();
})->middleware('auth');

Route::post('/panel/orders', [UserController::class,
Route::get('/panel/orders', [UserController::class,
'getOrders'])->middleware('auth');


Loading…
Cancel
Save