This commit is contained in:
2023-11-20 00:32:26 +08:00
parent 9ce3e5c82a
commit 2559d4be1c
37 changed files with 288 additions and 12419 deletions

View File

@@ -4,11 +4,10 @@
use App\Jobs\BrowseAndWriteWithAIJob;
use App\Jobs\PublishIndexPostJob;
use App\Models\Post;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Models\Post;
class Kernel extends ConsoleKernel
{
/**
@@ -22,10 +21,9 @@ protected function schedule(Schedule $schedule): void
})->dailyAt('00:00');
$schedule->call(function () {
$future_post = Post::whereNotNull('published_at')->where('status','future')->where('published_at', '>=', now())->orderBy('published_at','ASC')->first();
PublishIndexPostJob::dispatch($future_post->id)->onQueue('default')->onConnection('default');
$future_post = Post::whereNotNull('published_at')->where('status', 'future')->where('published_at', '>=', now())->orderBy('published_at', 'ASC')->first();
PublishIndexPostJob::dispatch($future_post->id)->onQueue('default')->onConnection('default');
})->everyMinute();

View File

@@ -21,9 +21,8 @@ public static function liveAdvanced($se, $se_type, $keyword, $location_name, $la
'language_code' => $language_code,
];
if (!is_empty($search_param))
{
$query['search_param'] = $search_param;
if (! is_empty($search_param)) {
$query['search_param'] = $search_param;
}
try {

View File

@@ -12,55 +12,51 @@
class FrontListController extends Controller
{
public function search(Request $request)
{
$page_type = 'search';
public function search(Request $request)
{
$page_type = 'search';
$query = $request->get('query', '');
$query = $request->get('query', '');
$breadcrumbs = collect([
['name' => 'Home', 'url' => route('front.home')],
['name' => 'Search', 'url' => null],
['name' => $query, 'url' => url()->current()],
]);
$breadcrumbs = collect([
['name' => 'Home', 'url' => route('front.home')],
['name' => 'Search', 'url' => null],
['name' => $query, 'url' => url()->current()],
]);
$title = 'Latest News about '.ucwords($query).' in FutureWalker';
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
SEOTools::setTitle($title, false);
// Use full-text search capabilities of your database
// For example, using MySQL's full-text search with MATCH...AGAINST
$posts = Post::with('category')
->where('status', 'publish')
->whereRaw("to_tsvector('english', title || ' ' || bites) @@ to_tsquery('english', ?)", [$query])
->orderBy('published_at', 'desc')
->cursorPaginate(10);
$title = 'Latest News about ' . ucwords($query) . ' in FutureWalker';
// breadcrumb json ld
$listItems = [];
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
SEOTools::setTitle($title, false);
foreach ($breadcrumbs as $index => $breadcrumb) {
$listItems[] = [
'name' => $breadcrumb['name'],
'url' => $breadcrumb['url'],
];
}
// Use full-text search capabilities of your database
// For example, using MySQL's full-text search with MATCH...AGAINST
$posts = Post::with('category')
->where('status', 'publish')
->whereRaw("to_tsvector('english', title || ' ' || bites) @@ to_tsquery('english', ?)", [$query])
->orderBy('published_at', 'desc')
->cursorPaginate(10);
$breadcrumb_context = Context::create('breadcrumb_list', [
'itemListElement' => $listItems,
]);
// breadcrumb json ld
$listItems = [];
foreach ($breadcrumbs as $index => $breadcrumb) {
$listItems[] = [
'name' => $breadcrumb['name'],
'url' => $breadcrumb['url'],
];
return view('front.post_list', compact('posts', 'breadcrumbs', 'breadcrumb_context', 'title', 'page_type'));
}
$breadcrumb_context = Context::create('breadcrumb_list', [
'itemListElement' => $listItems,
]);
return view('front.post_list', compact('posts', 'breadcrumbs', 'breadcrumb_context', 'title','page_type'));
}
public function index(Request $request)
{
$page_type = 'default';
@@ -96,7 +92,7 @@ public function index(Request $request)
'itemListElement' => $listItems,
]);
return view('front.post_list', compact('posts', 'breadcrumbs', 'breadcrumb_context','page_type'));
return view('front.post_list', compact('posts', 'breadcrumbs', 'breadcrumb_context', 'page_type'));
}
public function category(Request $request, $category_slug)
@@ -147,6 +143,6 @@ public function category(Request $request, $category_slug)
'itemListElement' => $listItems,
]);
return view('front.post_list', compact('category', 'posts', 'breadcrumbs', 'breadcrumb_context','page_type'));
return view('front.post_list', compact('category', 'posts', 'breadcrumbs', 'breadcrumb_context', 'page_type'));
}
}

View File

@@ -3,7 +3,6 @@
namespace App\Jobs;
use App\Jobs\Tasks\PublishIndexPostTask;
use App\Models\Post;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

View File

@@ -5,11 +5,11 @@
use App\Helpers\FirstParty\OpenAI\OpenAI;
use App\Helpers\FirstParty\OSSUploader\OSSUploader;
use App\Jobs\SchedulePublishPost;
use App\Models\Entity;
use App\Models\PostEntity;
use App\Models\Category;
use App\Models\Entity;
use App\Models\Post;
use App\Models\PostCategory;
use App\Models\PostEntity;
use App\Models\SerpUrlResearch;
use App\Models\ServiceCostUsage;
use Exception;
@@ -78,100 +78,84 @@ public static function handle(int $post_id)
$post = self::setPostImage($post);
}
if (isset($post_meta_response->output->society_impact))
{
if (!is_empty($post_meta_response->output->society_impact))
{
$post->society_impact = $post_meta_response->output->society_impact;
}
if (isset($post_meta_response->output->society_impact)) {
if (! is_empty($post_meta_response->output->society_impact)) {
$post->society_impact = $post_meta_response->output->society_impact;
}
}
if (isset($post_meta_response->output->society_impact_level))
{
if (!is_empty($post_meta_response->output->society_impact_level))
{
$post->society_impact = $post_meta_response->output->society_impact_level;
}
if (isset($post_meta_response->output->society_impact_level)) {
if (! is_empty($post_meta_response->output->society_impact_level)) {
$post->society_impact = $post_meta_response->output->society_impact_level;
}
}
if ($post->save()) {
// Set Category
// Set Category
$category_name = 'Updates';
$category_name = 'Updates';
if ((isset($post_meta_response->output->category)) && (!is_empty($post_meta_response->output->category)))
{
$category_name = $post_meta_response?->output?->category;
}
$category = Category::where('name', $category_name)->first();
if (is_null($category))
{
$category = Category::where('name', 'Updates')->first();
}
// Set Post Category
$post_category = PostCategory::where('post_id', $post->id)->first();
if (is_null($post_category))
{
$post_category = new PostCategory;
$post_category->post_id = $post->id;
}
$post_category->category_id = $category->id;
$post_category->save();
// Set Post Entities
if (isset($post_meta_response->output->entities))
{
$entity_names = [];
if (is_array($post_meta_response->output->entities))
{
$entity_names = $post_meta_response->output->entities;
if ((isset($post_meta_response->output->category)) && (! is_empty($post_meta_response->output->category))) {
$category_name = $post_meta_response?->output?->category;
}
if (count($entity_names) > 0)
{
$previous_post_entities = PostEntity::where('post_id', $post->id)->delete();
$category = Category::where('name', $category_name)->first();
foreach ($entity_names as $entity_name)
{
$entity_name = trim($entity_name);
$entity = Entity::where('name', $entity_name)->first();
if (is_null($entity))
{
$entity = new Entity;
$entity->name = $entity_name;
$entity->slug = str_slug($entity_name);
$entity->save();
}
$post_entity = PostEntity::where('post_id', $post->id)
->where('entity_id', $entity->id)
->first();
if (is_null($post_entity))
{
$post_entity = new PostEntity;
$post_entity->post_id = $post->id;
$post_entity->entity_id = $entity->id;
$post_entity->save();
}
}
if (is_null($category)) {
$category = Category::where('name', 'Updates')->first();
}
}
// Set Schedule Publish
SchedulePublishPost::dispatch($post->id, 'future')->onQueue('default')->onConnection('default');
// Set Post Category
$post_category = PostCategory::where('post_id', $post->id)->first();
if (is_null($post_category)) {
$post_category = new PostCategory;
$post_category->post_id = $post->id;
}
$post_category->category_id = $category->id;
$post_category->save();
// Set Post Entities
if (isset($post_meta_response->output->entities)) {
$entity_names = [];
if (is_array($post_meta_response->output->entities)) {
$entity_names = $post_meta_response->output->entities;
}
if (count($entity_names) > 0) {
$previous_post_entities = PostEntity::where('post_id', $post->id)->delete();
foreach ($entity_names as $entity_name) {
$entity_name = trim($entity_name);
$entity = Entity::where('name', $entity_name)->first();
if (is_null($entity)) {
$entity = new Entity;
$entity->name = $entity_name;
$entity->slug = str_slug($entity_name);
$entity->save();
}
$post_entity = PostEntity::where('post_id', $post->id)
->where('entity_id', $entity->id)
->first();
if (is_null($post_entity)) {
$post_entity = new PostEntity;
$post_entity->post_id = $post->id;
$post_entity->entity_id = $entity->id;
$post_entity->save();
}
}
}
}
// Set Schedule Publish
SchedulePublishPost::dispatch($post->id, 'future')->onQueue('default')->onConnection('default');
}
}

View File

@@ -13,9 +13,8 @@ public static function handle(int $post_id)
{
$post = Post::find($post_id);
if (is_null($post))
{
return ;
if (is_null($post)) {
return;
}
$post->status = 'publish';

View File

@@ -12,28 +12,25 @@
/**
* Class Entity
*
*
* @property int $id
* @property string $name
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @property Collection|PostEntity[] $post_entities
*
* @package App\Models
*/
class Entity extends Model
{
protected $table = 'entities';
protected $table = 'entities';
protected $fillable = [
'name',
'slug',
'description'
];
protected $fillable = [
'name',
'slug',
'description',
];
public function post_entities()
{
return $this->hasMany(PostEntity::class);
}
public function post_entities()
{
return $this->hasMany(PostEntity::class);
}
}

View File

@@ -11,39 +11,36 @@
/**
* Class PostEntity
*
*
* @property int $id
* @property int $post_id
* @property int $entity_id
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @property Post $post
* @property Entity $entity
*
* @package App\Models
*/
class PostEntity extends Model
{
protected $table = 'post_entities';
protected $table = 'post_entities';
protected $casts = [
'post_id' => 'int',
'entity_id' => 'int'
];
protected $casts = [
'post_id' => 'int',
'entity_id' => 'int',
];
protected $fillable = [
'post_id',
'entity_id'
];
protected $fillable = [
'post_id',
'entity_id',
];
public function post()
{
return $this->belongsTo(Post::class);
}
public function post()
{
return $this->belongsTo(Post::class);
}
public function entity()
{
return $this->belongsTo(Entity::class);
}
public function entity()
{
return $this->belongsTo(Entity::class);
}
}

View File

@@ -20,7 +20,7 @@ public function up(): void
$table->json('keywords')->nullable();
$table->mediumText('bites')->nullable();
$table->mediumText('society_impact')->nullable();
$table->enum('society_impact_level', ['low','medium','high'])->default('low');
$table->enum('society_impact_level', ['low', 'medium', 'high'])->default('low');
$table->foreignId('author_id')->nullable();
$table->mediumText('featured_image')->nullable();
$table->text('body')->nullable();

View File

@@ -3,7 +3,7 @@
# eval 'php artisan optimize:clear';
# eval 'php artisan responsecache:clear';
# eval 'php artisan opcache:clear';
eval 'APP_URL=https://FutureWalker.com php artisan ziggy:generate';
eval 'APP_URL=https://futurewalker.co php artisan ziggy:generate';
eval 'blade-formatter --write resources/**/*.blade.php';
eval './vendor/bin/pint';
eval 'npm run build';

View File

@@ -1 +1 @@
import{_ as i}from"./vue-7b541fc9.js";const n={name:"LqipLoader",mounted(){this.initLqipLoading()},methods:{initLqipLoading(){const e=document.getElementsByTagName("img");for(let t=0;t<e.length;t++)e[t].getAttribute("data-src")&&(e[t].onload=function(){this.classList.remove("lqip-blur")},e[t].setAttribute("src",e[t].getAttribute("data-src")))}}};function o(e,t,r,s,a,c){return null}const m=i(n,[["render",o]]);export{m as default};
import{_ as i}from"./vue-119a3b87.js";const n={name:"LqipLoader",mounted(){this.initLqipLoading()},methods:{initLqipLoading(){const e=document.getElementsByTagName("img");for(let t=0;t<e.length;t++)e[t].getAttribute("data-src")&&(e[t].onload=function(){this.classList.remove("lqip-blur")},e[t].setAttribute("src",e[t].getAttribute("data-src")))}}};function o(e,t,r,s,a,c){return null}const m=i(n,[["render",o]]);export{m as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -1 +1 @@
import{_ as o,o as p,c,a as r,b as u,p as i,d as m,e as g,f as _,g as d,v as f,Z as n,h as l}from"./vue-7b541fc9.js";const A={name:"AppAuth"};function $(s,a,t,Z,w,x){return p(),c("div")}const h=o(A,[["render",$]]),e=r({AppAuth:h}),v=Object.assign({});e.use(u());e.use(i,m);e.use(g);e.use(_);e.use(d);e.use(f.ZiggyVue,n);window.Ziggy=n;Object.entries({...v}).forEach(([s,a])=>{const t=s.split("/").pop().replace(/\.\w+$/,"").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();e.component(t,l(a))});e.mount("#app");
import{_ as o,o as p,c,a as r,b as u,p as i,d as m,e as g,f as _,g as d,v as f,Z as n,h as l}from"./vue-119a3b87.js";const A={name:"AppAuth"};function $(s,a,t,Z,w,x){return p(),c("div")}const h=o(A,[["render",$]]),e=r({AppAuth:h}),v=Object.assign({});e.use(u());e.use(i,m);e.use(g);e.use(_);e.use(d);e.use(f.ZiggyVue,n);window.Ziggy=n;Object.entries({...v}).forEach(([s,a])=>{const t=s.split("/").pop().replace(/\.\w+$/,"").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();e.component(t,l(a))});e.mount("#app");

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
{
"_vue-7b541fc9.js": {
"_vue-119a3b87.js": {
"css": [
"assets/vue-935fc652.css"
],
"file": "assets/vue-7b541fc9.js"
"file": "assets/vue-119a3b87.js"
},
"node_modules/bootstrap-icons/font/fonts/bootstrap-icons.woff": {
"file": "assets/bootstrap-icons-4d4572ef.woff",
@@ -50,9 +50,9 @@
"src": "resources/fonts/Inter/Inter-Thin.ttf"
},
"resources/js/app-auth.js": {
"file": "assets/app-auth-863829a4.js",
"file": "assets/app-auth-cd6b6188.js",
"imports": [
"_vue-7b541fc9.js"
"_vue-119a3b87.js"
],
"isEntry": true,
"src": "resources/js/app-auth.js"
@@ -61,28 +61,28 @@
"dynamicImports": [
"resources/js/vue/front/LqipLoader.vue"
],
"file": "assets/app-front-da28b0cc.js",
"file": "assets/app-front-7da267b6.js",
"imports": [
"_vue-7b541fc9.js"
"_vue-119a3b87.js"
],
"isEntry": true,
"src": "resources/js/app-front.js"
},
"resources/js/vue/front/LqipLoader.vue": {
"file": "assets/LqipLoader-343b1ab3.js",
"file": "assets/LqipLoader-63b84826.js",
"imports": [
"_vue-7b541fc9.js"
"_vue-119a3b87.js"
],
"isDynamicEntry": true,
"src": "resources/js/vue/front/LqipLoader.vue"
},
"resources/sass/app-auth.scss": {
"file": "assets/app-auth-32da185d.css",
"file": "assets/app-auth-38851d9d.css",
"isEntry": true,
"src": "resources/sass/app-auth.scss"
},
"resources/sass/app-front.scss": {
"file": "assets/app-front-ecc2f041.css",
"file": "assets/app-front-1cc890bf.css",
"isEntry": true,
"src": "resources/sass/app-front.scss"
},

Binary file not shown.

View File

@@ -1,64 +1,7 @@
const Ziggy = {
url: "https://FutureWalker.com",
port: null,
defaults: {},
routes: {
"debugbar.openhandler": { uri: "_debugbar/open", methods: ["GET", "HEAD"] },
"debugbar.clockwork": {
uri: "_debugbar/clockwork/{id}",
methods: ["GET", "HEAD"],
},
"debugbar.assets.css": {
uri: "_debugbar/assets/stylesheets",
methods: ["GET", "HEAD"],
},
"debugbar.assets.js": {
uri: "_debugbar/assets/javascript",
methods: ["GET", "HEAD"],
},
"debugbar.cache.delete": {
uri: "_debugbar/cache/{key}/{tags?}",
methods: ["DELETE"],
},
"sanctum.csrf-cookie": {
uri: "sanctum/csrf-cookie",
methods: ["GET", "HEAD"],
},
"laravelpwa.manifest": { uri: "manifest.json", methods: ["GET", "HEAD"] },
"laravelpwa.": { uri: "offline", methods: ["GET", "HEAD"] },
"ignition.healthCheck": {
uri: "_ignition/health-check",
methods: ["GET", "HEAD"],
},
"ignition.executeSolution": {
uri: "_ignition/execute-solution",
methods: ["POST"],
},
"ignition.updateConfig": {
uri: "_ignition/update-config",
methods: ["POST"],
},
"feeds.main": { uri: "feeds/posts-feed", methods: ["GET", "HEAD"] },
"front.home": { uri: "/", methods: ["GET", "HEAD"] },
"front.terms": { uri: "terms", methods: ["GET", "HEAD"] },
"front.privacy": { uri: "privacy", methods: ["GET", "HEAD"] },
"front.disclaimer": { uri: "disclaimer", methods: ["GET", "HEAD"] },
"front.all": { uri: "news", methods: ["GET", "HEAD"] },
"front.post.redirect": { uri: "news/{slug}", methods: ["GET", "HEAD"] },
"front.post": { uri: "{category_slug}/{slug}", methods: ["GET", "HEAD"] },
"front.category": {
uri: "{category_slug}",
methods: ["GET", "HEAD"],
wheres: {
category_slug:
"^(automotive|business|trading|information-technology|marketing|office|telecommunications|food-drink|collectibles|pets|photography|hobbies-gifts|hunting-fishing|law|politics|home-garden|shopping|fashion-clothing|real-estate|family|wedding|immigration|society|education|languages|health|beauty|psychology|wellness|religion-spirituality|tips-tricks|how-to|holiday|world-festivals|travel|outdoors|computer|phones|gadgets|technology|social-networks|ai)$",
},
},
},
};
const Ziggy = {"url":"https:\/\/futurewalker.co","port":null,"defaults":{},"routes":{"debugbar.openhandler":{"uri":"_debugbar\/open","methods":["GET","HEAD"]},"debugbar.clockwork":{"uri":"_debugbar\/clockwork\/{id}","methods":["GET","HEAD"],"parameters":["id"]},"debugbar.assets.css":{"uri":"_debugbar\/assets\/stylesheets","methods":["GET","HEAD"]},"debugbar.assets.js":{"uri":"_debugbar\/assets\/javascript","methods":["GET","HEAD"]},"debugbar.cache.delete":{"uri":"_debugbar\/cache\/{key}\/{tags?}","methods":["DELETE"],"parameters":["key","tags"]},"sanctum.csrf-cookie":{"uri":"sanctum\/csrf-cookie","methods":["GET","HEAD"]},"laravelpwa.manifest":{"uri":"manifest.json","methods":["GET","HEAD"]},"laravelpwa.":{"uri":"offline","methods":["GET","HEAD"]},"ignition.healthCheck":{"uri":"_ignition\/health-check","methods":["GET","HEAD"]},"ignition.executeSolution":{"uri":"_ignition\/execute-solution","methods":["POST"]},"ignition.updateConfig":{"uri":"_ignition\/update-config","methods":["POST"]},"feeds.main":{"uri":"feeds\/posts-feed","methods":["GET","HEAD"]},"front.home":{"uri":"\/","methods":["GET","HEAD"]},"front.terms":{"uri":"terms","methods":["GET","HEAD"]},"front.privacy":{"uri":"privacy","methods":["GET","HEAD"]},"front.disclaimer":{"uri":"disclaimer","methods":["GET","HEAD"]},"front.all":{"uri":"latest","methods":["GET","HEAD"]},"front.search":{"uri":"search","methods":["POST"]},"front.post":{"uri":"{category_slug}\/{slug}","methods":["GET","HEAD"],"parameters":["category_slug","slug"]},"front.category":{"uri":"{category_slug}","methods":["GET","HEAD"],"wheres":{"category_slug":"^(updates|opinions|features|new-launches|tutorials|reviews)$"},"parameters":["category_slug"]}}};
if (typeof window !== "undefined" && typeof window.Ziggy !== "undefined") {
Object.assign(Ziggy.routes, window.Ziggy.routes);
if (typeof window !== 'undefined' && typeof window.Ziggy !== 'undefined') {
Object.assign(Ziggy.routes, window.Ziggy.routes);
}
export { Ziggy };

View File

@@ -1,6 +1,9 @@
<aside class="p-4 mb-3 bg-black text-white rounded-3 shadow-sm">
<h4 class="font-family-roboto-condensed">About <span class="text-uppercase">FutureWalker</span></h4>
<p class="mb-0">
FutureWalker is an innovative news platform specializing in cutting-edge technology and AI developments. We provide insightful coverage on the latest breakthroughs and trends, offering our audience a front-row seat to the advancements shaping our future. Stay informed and ahead with FutureWalker, your go-to source for tech news that matters.
FutureWalker is an innovative news platform specializing in cutting-edge technology and AI developments. We
provide insightful coverage on the latest breakthroughs and trends, offering our audience a front-row seat to
the advancements shaping our future. Stay informed and ahead with FutureWalker, your go-to source for tech news
that matters.
</p>
</aside>

View File

@@ -1,8 +1,7 @@
<div class="row g-3 border-0 overflow-hidden flex-md-row mb-4 h-md-250 position-relative bg-white">
<div class="col-12 col-lg-3 d-flex" style="height:100%;">
<div class="align-self-center">
<img class="img-fluid rounded-4 shadow" src="{{ $post->featured_image }}"
alt="{{ $post->title }}">
<img class="img-fluid rounded-4 shadow" src="{{ $post->featured_image }}" alt="{{ $post->title }}">
</div>
</div>

View File

@@ -1,9 +1,10 @@
<aside>
<form class="d-flex mb-3" action="{{ route('front.search')}}" method="POST">
@csrf
<input name="query" class="form-control me-2" type="search" placeholder="Search for AI news..." aria-label="Search">
<button class="btn btn-outline-primary" type="submit">
<i class="bi bi-search"></i>
</button>
</form>
</aside>
<form class="d-flex mb-3" action="{{ route('front.search') }}" method="POST">
@csrf
<input name="query" class="form-control me-2" type="search" placeholder="Search for AI news..."
aria-label="Search">
<button class="btn btn-outline-primary" type="submit">
<i class="bi bi-search"></i>
</button>
</form>
</aside>

View File

@@ -1,7 +1,7 @@
@include('front.partials.about')
@include('front.partials.search')
{{--
{{--
<aside class="text-center">
<h3 class="font-family-roboto-condensed h4 text-uppercase">Never miss a news</h3>
<div class="d-flex flex-row justify-content-center">
@@ -11,7 +11,7 @@
{{-- <a href="https://twitter.com/futurewalker" target="_blank" class="mx-1 btn btn-link mb-2">
<i class="bi bi-twitter"></i>
</a> --}}
{{-- <a href="https://www.youtube.com/user/hackaday" target="_blank" class="mx-1 btn btn-link mb-2">
{{-- <a href="https://www.youtube.com/user/hackaday" target="_blank" class="mx-1 btn btn-link mb-2">
<i class="bi bi-youtube"></i>
</a>
<a href="https://hackaday.com/blog/feed/" target="_blank" class="mx-1 btn btn-link mb-2">
@@ -19,4 +19,4 @@
</a>
</div>
</aside>
--}}
--}}

View File

@@ -8,16 +8,16 @@
<div class="col-md-8">
<h1 class="pb-2 h2 font-family-roboto-condensed">
@if($page_type == 'search')
@if(isset($title))
{{ $title }}
@endif
@if ($page_type == 'search')
@if (isset($title))
{{ $title }}
@endif
@else
@if (isset($category) && !is_null($category))
{{ $category->name }} News from FutureWalker
@else
AI &amp; Tech News from FutureWalker
@endif
@if (isset($category) && !is_null($category))
{{ $category->name }} News from FutureWalker
@else
AI &amp; Tech News from FutureWalker
@endif
@endif
</h1>
@if ($posts->count() > 0)
@@ -38,9 +38,9 @@
</div>
<div class="col-md-4">
<div class="position-sticky" style="top: 2rem;">
@include('front.partials.sidebar')
</div>
<div class="position-sticky" style="top: 2rem;">
@include('front.partials.sidebar')
</div>
</div>
</div>
</main>

View File

@@ -18,94 +18,98 @@
</div>
@if ($featured_posts->count() > 0)
<div class="container-lg py-4">
<div class="text-center">
<h2 id="latest-news" class="fw-bold font-family-roboto-condensed mb-3 h2">Featured News</h2>
</div>
<div class="container-lg py-4">
<div class="text-center">
<h2 id="latest-news" class="fw-bold font-family-roboto-condensed mb-3 h2">Featured News</h2>
</div>
<div class="row g-3">
@foreach ($featured_posts as $post)
<div class="col-12 col-md-4">
<div class="card border-0" style="height:100%;">
<div class="ratio ratio-16x9">
<img src="{{ $post->featured_image }}" alt="" class="rounded-4 card-img-top shadow"
style="object-fit: cover;">
</div>
<div class="card-body px-0">
<h3 class="h4 fw-bold font-family-roboto-condensed">
<a href="{{ route('front.post', ['category_slug' => $post->category->slug,'slug' => $post->slug]) }}">{{ $post->title }}</a>
</h3>
<p>{{ str_first_sentence($post->bites) }}</p>
<div class="row g-3">
@foreach ($featured_posts as $post)
<div class="col-12 col-md-4">
<div class="card border-0" style="height:100%;">
<div class="ratio ratio-16x9">
<img src="{{ $post->featured_image }}" alt=""
class="rounded-4 card-img-top shadow" style="object-fit: cover;">
</div>
<div class="card-body px-0">
<h3 class="h4 fw-bold font-family-roboto-condensed">
<a
href="{{ route('front.post', ['category_slug' => $post->category->slug, 'slug' => $post->slug]) }}">{{ $post->title }}</a>
</h3>
<p>{{ str_first_sentence($post->bites) }}</p>
</div>
</div>
</div>
</div>
@endforeach
@endforeach
</div>
</div>
</div>
@endif
@if ($latest_posts->count() > 0)
<div class="container-lg py-4">
<div class="container-lg py-4">
<div class="row">
<div class="col-12 col-lg-8 mb-3">
<div class="text-start">
<h2 id="latest-news" class="fw-bold font-family-roboto-condensed mb-3 h2">Latest News</h2>
</div>
<div class="row g-3 mb-4">
@foreach ($latest_posts as $post)
<div class="col-12 col-md-6">
<div class="card bg-white border-0 shadow" style="height:100%;">
<div class="card-body d-flex">
<div class="row align-self-center">
<div class="col-12 col-lg-5 d-flex py-1" style="height:100%;">
<div class="align-self-center">
<img class="img-fluid rounded-4" src="{{ $post->featured_image }}"
alt="{{ $post->title }}">
</div>
<div class="row">
<div class="col-12 col-lg-8 mb-3">
<div class="text-start">
<h2 id="latest-news" class="fw-bold font-family-roboto-condensed mb-3 h2">Latest News</h2>
</div>
<div class="row g-3 mb-4">
@foreach ($latest_posts as $post)
<div class="col-12 col-md-6">
<div class="card bg-white border-0 shadow" style="height:100%;">
<div class="card-body d-flex">
<div class="row align-self-center">
<div class="col-12 col-lg-5 d-flex py-1" style="height:100%;">
<div class="align-self-center">
<img class="img-fluid rounded-4" src="{{ $post->featured_image }}"
alt="{{ $post->title }}">
</div>
</div>
<div class="col-12 col-lg-7 d-flex py-1" style="height:100%;">
<div class="align-self-center">
<div class="">
<h3 class="h6 mb-0 fw-bold font-family-roboto-condensed">
<a href="{{ route('front.post', ['category_slug' => $post->category->slug,'slug' => $post->slug]) }}" class="fw-bold"
style=" display: -webkit-box;
</div>
<div class="col-12 col-lg-7 d-flex py-1" style="height:100%;">
<div class="align-self-center">
<div class="">
<h3 class="h6 mb-0 fw-bold font-family-roboto-condensed">
<a href="{{ route('front.post', ['category_slug' => $post->category->slug, 'slug' => $post->slug]) }}"
class="fw-bold"
style=" display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;">{{ $post->title }}</a></h3>
</div>
<div><small
class="text-secondary">{{ $post->published_at->diffForHumans() }}</small>
overflow: hidden;">{{ $post->title }}</a>
</h3>
</div>
<div><small
class="text-secondary">{{ $post->published_at->diffForHumans() }}</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endforeach
</div>
<div class="w-full text-center">
<a href="{{ route('front.all') }}"
class="btn btn-outline-primary px-4 rounded-pill text-decoration-none">Discover More
News</a>
</div>
</div>
@endforeach
</div>
<div class="w-full text-center">
<a href="{{ route('front.all') }}"
class="btn btn-outline-primary px-4 rounded-pill text-decoration-none">Discover More News</a>
</div>
</div>
<div class="col-12 col-lg-4 mb-3">
<div class="position-sticky" style="top: 2rem;">
@include('front.partials.sidebar')
<div class="col-12 col-lg-4 mb-3">
<div class="position-sticky" style="top: 2rem;">
@include('front.partials.sidebar')
</div>
</div>
</div>
</div>
</div>
</div>
@endif

View File

@@ -6,7 +6,6 @@
use App\Jobs\FillPostMetadataJob;
use App\Jobs\GenerateArticleFeaturedImageJob;
use App\Jobs\GenerateArticleJob;
use App\Jobs\SchedulePublishPost;
use App\Jobs\Tasks\GetNewsSerpTask;
use App\Jobs\Tasks\ParseNewsSerpDomainsTask;
use App\Jobs\Tasks\ScrapeUrlBodyTask;