update menu data ulasan
This commit is contained in:
parent
1f653dda6c
commit
84b66d4465
|
|
@ -5,50 +5,111 @@
|
|||
use Illuminate\Http\Request;
|
||||
use App\Models\Ulasan;
|
||||
use App\Models\PreprocessingData;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class UlasanController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$wisata = $request->wisata;
|
||||
|
||||
$query = Ulasan::query();
|
||||
if ($request->filled('search')) {
|
||||
$query->where('ulasan', 'LIKE', '%' . $request->search . '%');
|
||||
}
|
||||
|
||||
if ($wisata) {
|
||||
$query->where('wisata', 'LIKE', '%' . $wisata . '%');
|
||||
// 🔍 SEARCH (ulasan + wisata)
|
||||
if ($request->filled('search')) {
|
||||
$search = $request->search;
|
||||
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('ulasan', 'LIKE', "%$search%")
|
||||
->orWhere('wisata', 'LIKE', "%$search%");
|
||||
});
|
||||
}
|
||||
|
||||
// 🔍 FILTER WISATA
|
||||
if ($request->filled('wisata')) {
|
||||
$query->where('wisata', 'LIKE', '%' . $request->wisata . '%');
|
||||
}
|
||||
|
||||
// ✅ PAGINATION 50 DATA
|
||||
$mentah = $query->latest()->paginate(50)->withQueryString();
|
||||
|
||||
// preprocessing
|
||||
// OPTIONAL
|
||||
$preprocessing = PreprocessingData::latest()->paginate(30, ['*'], 'pre_page');
|
||||
|
||||
return view('ulasan.index', compact('mentah', 'preprocessing'));
|
||||
// 🔥 RINGKASAN DATA
|
||||
$totalUlasan = Ulasan::count();
|
||||
$totalWisata = Ulasan::distinct('wisata')->count('wisata');
|
||||
$lastUpdate = Ulasan::max('updated_at');
|
||||
|
||||
return view('ulasan.index', compact(
|
||||
'mentah',
|
||||
'preprocessing',
|
||||
'totalUlasan',
|
||||
'totalWisata',
|
||||
'lastUpdate'
|
||||
));
|
||||
}
|
||||
|
||||
public function ambilData()
|
||||
public function upload(Request $request)
|
||||
{
|
||||
$pythonPath = "C:\\Users\\Mufrida Farah\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
|
||||
$scriptPath = base_path('scraper/scraping_pipeline.py');
|
||||
$request->validate([
|
||||
'file' => 'required|mimes:csv,txt,xlsx,xls|max:10240'
|
||||
]);
|
||||
|
||||
shell_exec($pythonPath . " " . $scriptPath);
|
||||
$file = $request->file('file');
|
||||
$extension = strtolower($file->getClientOriginalExtension());
|
||||
|
||||
if (in_array($extension, ['xlsx', 'xls'])) {
|
||||
|
||||
$data = Excel::toArray(null, $file);
|
||||
$rows = $data[0] ?? [];
|
||||
unset($rows[0]);
|
||||
|
||||
foreach ($rows as $row) {
|
||||
if (empty($row) || count($row) < 4) continue;
|
||||
|
||||
DB::table('ulasan')->insert([
|
||||
'wisata' => $row[0] ?? null,
|
||||
'rating' => isset($row[1]) ? (float) $row[1] : 0,
|
||||
'ulasan' => $row[2] ?? '',
|
||||
'tanggal' => isset($row[3]) ? date('Y-m-d H:i:s', strtotime($row[3])) : now(),
|
||||
'sentimen' => null,
|
||||
'reviewer' => 'anonymous',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
|
||||
$data = array_map(fn($line) => str_getcsv($line, ';'), file($file));
|
||||
unset($data[0]);
|
||||
|
||||
foreach ($data as $row) {
|
||||
if (empty($row) || count($row) < 4) continue;
|
||||
|
||||
DB::table('ulasan')->insert([
|
||||
'wisata' => $row[0] ?? null,
|
||||
'rating' => isset($row[1]) ? (float) $row[1] : 0,
|
||||
'ulasan' => $row[2] ?? '',
|
||||
'tanggal' => isset($row[3]) ? date('Y-m-d H:i:s', strtotime($row[3])) : now(),
|
||||
'sentimen' => null,
|
||||
'reviewer' => 'anonymous',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('ulasan.index')
|
||||
->with('success','Data berhasil diambil');
|
||||
->with('success', 'Upload berhasil dan data masuk!');
|
||||
}
|
||||
|
||||
public function analisisData()
|
||||
{
|
||||
$pythonPath = '"C:\\Users\\Mufrida Farah\\AppData\\Local\\Programs\\Python\\Python312\\python.exe"';
|
||||
$scriptPath = '"C:\\laragon\\www\\Sentara\\scraper\\preprocessing.py"';
|
||||
public function analisisData()
|
||||
{
|
||||
$pythonPath = '"C:\\Users\\Mufrida Farah\\AppData\\Local\\Programs\\Python\\Python312\\python.exe"';
|
||||
$scriptPath = '"C:\\laragon\\www\\Sentara\\scraper\\preprocessing.py"';
|
||||
|
||||
$output = shell_exec($pythonPath . " " . $scriptPath . " 2>&1");
|
||||
shell_exec($pythonPath . " " . $scriptPath . " 2>&1");
|
||||
|
||||
return redirect()->route('ulasan.index')
|
||||
->with('success','Analisis berhasil');
|
||||
}
|
||||
return redirect()->route('ulasan.index')
|
||||
->with('success', 'Analisis berhasil dijalankan');
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,8 @@
|
|||
"require": {
|
||||
"php": "^8.2",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/tinker": "^2.10.1"
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"maatwebsite/excel": "^3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "bdc6d92507d397adf1c269ed49ec424d",
|
||||
"content-hash": "bd6c0a0d1d5ee815cddc3b491e5fbb8e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
|
|
@ -135,6 +135,162 @@
|
|||
],
|
||||
"time": "2024-02-09T16:56:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
"version": "3.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/pcre.git",
|
||||
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<1.11.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.12 || ^2",
|
||||
"phpstan/phpstan-strict-rules": "^1 || ^2",
|
||||
"phpunit/phpunit": "^8 || ^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Pcre\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||
"keywords": [
|
||||
"PCRE",
|
||||
"preg",
|
||||
"regex",
|
||||
"regular expression"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/pcre/issues",
|
||||
"source": "https://github.com/composer/pcre/tree/3.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-12T16:29:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/semver",
|
||||
"version": "3.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/semver.git",
|
||||
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
|
||||
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.11",
|
||||
"symfony/phpunit-bridge": "^3 || ^7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Semver\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nils Adermann",
|
||||
"email": "naderman@naderman.de",
|
||||
"homepage": "http://www.naderman.de"
|
||||
},
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
},
|
||||
{
|
||||
"name": "Rob Bast",
|
||||
"email": "rob.bast@gmail.com",
|
||||
"homepage": "http://robbast.nl"
|
||||
}
|
||||
],
|
||||
"description": "Semver library that offers utilities, version constraint parsing and validation.",
|
||||
"keywords": [
|
||||
"semantic",
|
||||
"semver",
|
||||
"validation",
|
||||
"versioning"
|
||||
],
|
||||
"support": {
|
||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||
"issues": "https://github.com/composer/semver/issues",
|
||||
"source": "https://github.com/composer/semver/tree/3.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-20T19:15:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
"version": "v3.0.3",
|
||||
|
|
@ -508,6 +664,67 @@
|
|||
],
|
||||
"time": "2025-03-06T22:45:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ezyang/htmlpurifier",
|
||||
"version": "v4.19.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ezyang/htmlpurifier.git",
|
||||
"reference": "b287d2a16aceffbf6e0295559b39662612b77fcf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/b287d2a16aceffbf6e0295559b39662612b77fcf",
|
||||
"reference": "b287d2a16aceffbf6e0295559b39662612b77fcf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cerdic/css-tidy": "^1.7 || ^2.0",
|
||||
"simpletest/simpletest": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
|
||||
"ext-bcmath": "Used for unit conversion and imagecrash protection",
|
||||
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
|
||||
"ext-tidy": "Used for pretty-printing HTML"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"library/HTMLPurifier.composer.php"
|
||||
],
|
||||
"psr-0": {
|
||||
"HTMLPurifier": "library/"
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/library/HTMLPurifier/Language/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Edward Z. Yang",
|
||||
"email": "admin@htmlpurifier.org",
|
||||
"homepage": "http://ezyang.com"
|
||||
}
|
||||
],
|
||||
"description": "Standards compliant HTML filter written in PHP",
|
||||
"homepage": "http://htmlpurifier.org/",
|
||||
"keywords": [
|
||||
"html"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ezyang/htmlpurifier/issues",
|
||||
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.19.0"
|
||||
},
|
||||
"time": "2025-10-17T16:34:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fruitcake/php-cors",
|
||||
"version": "v1.4.0",
|
||||
|
|
@ -2019,6 +2236,272 @@
|
|||
],
|
||||
"time": "2026-01-15T06:54:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maatwebsite/excel",
|
||||
"version": "3.1.68",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SpartnerNL/Laravel-Excel.git",
|
||||
"reference": "1854739267d81d38eae7d8c623caf523f30f256b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/1854739267d81d38eae7d8c623caf523f30f256b",
|
||||
"reference": "1854739267d81d38eae7d8c623caf523f30f256b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/semver": "^3.3",
|
||||
"ext-json": "*",
|
||||
"illuminate/support": "5.8.*||^6.0||^7.0||^8.0||^9.0||^10.0||^11.0||^12.0||^13.0",
|
||||
"php": "^7.0||^8.0",
|
||||
"phpoffice/phpspreadsheet": "^1.30.0",
|
||||
"psr/simple-cache": "^1.0||^2.0||^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/scout": "^7.0||^8.0||^9.0||^10.0||^11.0",
|
||||
"orchestra/testbench": "^6.0||^7.0||^8.0||^9.0||^10.0||^11.0",
|
||||
"predis/predis": "^1.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"Excel": "Maatwebsite\\Excel\\Facades\\Excel"
|
||||
},
|
||||
"providers": [
|
||||
"Maatwebsite\\Excel\\ExcelServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Maatwebsite\\Excel\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Patrick Brouwers",
|
||||
"email": "patrick@spartner.nl"
|
||||
}
|
||||
],
|
||||
"description": "Supercharged Excel exports and imports in Laravel",
|
||||
"keywords": [
|
||||
"PHPExcel",
|
||||
"batch",
|
||||
"csv",
|
||||
"excel",
|
||||
"export",
|
||||
"import",
|
||||
"laravel",
|
||||
"php",
|
||||
"phpspreadsheet"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
|
||||
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.68"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://laravel-excel.com/commercial-support",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/patrickbrouwers",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-03-17T20:51:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maennchen/zipstream-php",
|
||||
"version": "3.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/maennchen/ZipStream-PHP.git",
|
||||
"reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e",
|
||||
"reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"ext-zlib": "*",
|
||||
"php-64bit": "^8.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"brianium/paratest": "^7.7",
|
||||
"ext-zip": "*",
|
||||
"friendsofphp/php-cs-fixer": "^3.86",
|
||||
"guzzlehttp/guzzle": "^7.5",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"php-coveralls/php-coveralls": "^2.5",
|
||||
"phpunit/phpunit": "^12.0",
|
||||
"vimeo/psalm": "^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"guzzlehttp/psr7": "^2.4",
|
||||
"psr/http-message": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ZipStream\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paul Duncan",
|
||||
"email": "pabs@pablotron.org"
|
||||
},
|
||||
{
|
||||
"name": "Jonatan Männchen",
|
||||
"email": "jonatan@maennchen.ch"
|
||||
},
|
||||
{
|
||||
"name": "Jesse Donat",
|
||||
"email": "donatj@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "András Kolesár",
|
||||
"email": "kolesar@kolesar.hu"
|
||||
}
|
||||
],
|
||||
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
|
||||
"keywords": [
|
||||
"stream",
|
||||
"zip"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
|
||||
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/maennchen",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-04-11T18:38:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/complex",
|
||||
"version": "3.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Complex\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@lange.demon.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with complex numbers",
|
||||
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||
"keywords": [
|
||||
"complex",
|
||||
"mathematics"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
||||
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
|
||||
},
|
||||
"time": "2022-12-06T16:21:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/matrix",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
||||
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
|
||||
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpdocumentor/phpdocumentor": "2.*",
|
||||
"phploc/phploc": "^4.0",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"sebastian/phpcpd": "^4.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Matrix\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@demon-angel.eu"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with matrices",
|
||||
"homepage": "https://github.com/MarkBaker/PHPMatrix",
|
||||
"keywords": [
|
||||
"mathematics",
|
||||
"matrix",
|
||||
"vector"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
||||
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
|
||||
},
|
||||
"time": "2022-12-02T22:17:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.10.0",
|
||||
|
|
@ -2526,6 +3009,114 @@
|
|||
],
|
||||
"time": "2025-11-20T02:34:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "1.30.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||
"reference": "02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9",
|
||||
"reference": "02970383cc12e7bf0bc0707ea6e2e8ed23a7aec9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/pcre": "^1||^2||^3",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": "*",
|
||||
"ezyang/htmlpurifier": "^4.15",
|
||||
"maennchen/zipstream-php": "^2.1 || ^3.0",
|
||||
"markbaker/complex": "^3.0",
|
||||
"markbaker/matrix": "^3.0",
|
||||
"php": ">=7.4.0 <8.5.0",
|
||||
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
|
||||
"doctrine/instantiator": "^1.5",
|
||||
"dompdf/dompdf": "^1.0 || ^2.0 || ^3.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"mitoteam/jpgraph": "^10.3",
|
||||
"mpdf/mpdf": "^8.1.1",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpstan/phpstan": "^1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^8.5 || ^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.7",
|
||||
"tecnickcom/tcpdf": "^6.5"
|
||||
},
|
||||
"suggest": {
|
||||
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
|
||||
"ext-intl": "PHP Internationalization Functions",
|
||||
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
|
||||
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Maarten Balliauw",
|
||||
"homepage": "https://blog.maartenballiauw.be"
|
||||
},
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"homepage": "https://markbakeruk.net"
|
||||
},
|
||||
{
|
||||
"name": "Franck Lefevre",
|
||||
"homepage": "https://rootslabs.net"
|
||||
},
|
||||
{
|
||||
"name": "Erik Tilt"
|
||||
},
|
||||
{
|
||||
"name": "Adrien Crivelli"
|
||||
},
|
||||
{
|
||||
"name": "Owen Leibman"
|
||||
}
|
||||
],
|
||||
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
|
||||
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
|
||||
"keywords": [
|
||||
"OpenXML",
|
||||
"excel",
|
||||
"gnumeric",
|
||||
"ods",
|
||||
"php",
|
||||
"spreadsheet",
|
||||
"xls",
|
||||
"xlsx"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.30.4"
|
||||
},
|
||||
"time": "2026-04-19T06:00:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
"version": "1.9.5",
|
||||
|
|
|
|||
|
|
@ -2,271 +2,259 @@
|
|||
|
||||
@section('content')
|
||||
|
||||
<div class="max-w-6xl mx-auto space-y-8">
|
||||
<div class="max-w-7xl mx-auto space-y-6">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="flex justify-between items-center">
|
||||
<h2 class="text-3xl font-bold text-gray-800">Data Ulasan</h2>
|
||||
<h2 class="text-2xl font-bold text-gray-800">Data Ulasan</h2>
|
||||
|
||||
<!-- ============================= -->
|
||||
<!-- 🔥 UPLOAD + FORMAT + SUMMARY -->
|
||||
<!-- ============================= -->
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
|
||||
<div class="grid grid-cols-3 gap-6 items-center">
|
||||
|
||||
<!-- UPLOAD -->
|
||||
<div class="border-2 border-dashed border-blue-300 rounded-xl p-6 text-center">
|
||||
|
||||
<div class="flex justify-center mb-3">
|
||||
<div class="bg-blue-100 text-blue-600 p-3 rounded-full text-xl">
|
||||
☁️
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-600 text-sm mb-2">
|
||||
Upload file CSV / XLSX
|
||||
</p>
|
||||
|
||||
<p class="text-gray-400 text-xs mb-3">klik tombol di bawah</p>
|
||||
|
||||
<form id="uploadForm" action="{{ route('ulasan.upload') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
|
||||
<input type="file" name="file" id="fileInput"
|
||||
accept=".csv,.xlsx,.xls"
|
||||
class="hidden">
|
||||
|
||||
<button type="button"
|
||||
onclick="document.getElementById('fileInput').click()"
|
||||
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg text-sm shadow">
|
||||
Pilih File
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- <a href="#" class="block mt-3 text-blue-500 text-xs hover:underline">
|
||||
⬇ Download template CSV
|
||||
</a> -->
|
||||
|
||||
</div>
|
||||
|
||||
<!-- FORMAT -->
|
||||
<div class="bg-blue-50 rounded-xl p-5">
|
||||
|
||||
<h4 class="font-semibold text-blue-700 mb-3">
|
||||
Format CSV yang Diperlukan
|
||||
</h4>
|
||||
|
||||
<ul class="space-y-2 text-sm text-gray-700">
|
||||
<li>✔ wisata, rating, ulasan, tanggal</li>
|
||||
<li>✔ Format: YYYY-MM-DD HH:MM:SS</li>
|
||||
<li>✔ Maks 10MB</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- SUMMARY -->
|
||||
<div class="space-y-4">
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="bg-blue-100 text-blue-600 p-3 rounded-full">📄</div>
|
||||
<div>
|
||||
<p class="text-xs text-gray-500">Total Ulasan</p>
|
||||
<p class="font-bold text-lg">{{ $totalUlasan }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="bg-green-100 text-green-600 p-3 rounded-full">📍</div>
|
||||
<div>
|
||||
<p class="text-xs text-gray-500">Total Wisata</p>
|
||||
<p class="font-bold text-lg">{{ $totalWisata }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="bg-orange-100 text-orange-600 p-3 rounded-full">📅</div>
|
||||
<div>
|
||||
<p class="text-xs text-gray-500">Terakhir Update</p>
|
||||
<p class="text-sm font-semibold">
|
||||
{{ $lastUpdate ? \Carbon\Carbon::parse($lastUpdate)->format('d M Y H:i') : '-' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ALERT -->
|
||||
@if(session('success'))
|
||||
<div class="bg-green-100 text-green-700 px-4 py-2 rounded-lg text-sm">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- ============================= -->
|
||||
<!-- 🔍 SEARCH + FILTER -->
|
||||
<!-- ============================= -->
|
||||
<form method="GET" action="{{ route('ulasan.index') }}" class="flex gap-3">
|
||||
|
||||
<input type="text" name="search" value="{{ request('search') }}"
|
||||
placeholder="Cari ulasan atau wisata..."
|
||||
class="flex-1 border px-3 py-2 rounded-lg text-sm">
|
||||
|
||||
<!-- <select name="wisata" onchange="this.form.submit()"
|
||||
class="border rounded-lg px-3 py-2 text-sm">
|
||||
|
||||
<select id="filterWisata" class="border rounded px-3 py-2 text-sm">
|
||||
<option value="">Semua Destinasi</option>
|
||||
<option value="Pantai Papuma" {{ request('wisata')=='Pantai Papuma'?'selected':'' }}>Pantai Papuma</option>
|
||||
<option value="Pantai Watu Ulo" {{ request('wisata')=='Pantai Watu Ulo'?'selected':'' }}>Pantai Watu Ulo</option>
|
||||
<option value="Teluk Love" {{ request('wisata')=='Teluk Love'?'selected':'' }}>Teluk Love</option>
|
||||
<option value="Kebun Teh Gunung Gambir" {{ request('wisata')=='Kebun Teh Gunung Gambir'?'selected':'' }}>Kebun Teh Gunung Gambir</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.getElementById("filterWisata").addEventListener("change", function () {
|
||||
window.location.href = "/ulasan?wisata=" + encodeURIComponent(this.value);
|
||||
});
|
||||
</script>
|
||||
</select> -->
|
||||
|
||||
<!-- BUTTON -->
|
||||
<form action="{{ route('ulasan.ambil') }}" method="POST">
|
||||
@csrf
|
||||
<button class="bg-blue-600 text-white px-5 py-2 rounded">
|
||||
Ambil Data Terbaru
|
||||
<button class="bg-blue-500 text-white px-4 py-2 rounded-lg text-sm">
|
||||
Cari
|
||||
</button>
|
||||
|
||||
<a href="{{ route('ulasan.index') }}"
|
||||
class="bg-gray-200 px-4 py-2 rounded-lg text-sm">
|
||||
Reset
|
||||
</a>
|
||||
|
||||
</form>
|
||||
|
||||
<!-- ================= TABLE ================= -->
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
<!-- ============================= -->
|
||||
<!-- TABLE -->
|
||||
<!-- ============================= -->
|
||||
<div class="bg-white rounded-xl shadow overflow-hidden">
|
||||
|
||||
<h3 class="font-semibold mb-4">Data Ulasan Mentah</h3>
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th class="px-4 py-3 w-[5%]">No</th>
|
||||
<th class="px-4 py-3 w-[20%]">Nama Wisata</th>
|
||||
<th class="px-4 py-3 w-[10%] text-center">Rating</th>
|
||||
<th class="px-4 py-3 w-[45%]">Ulasan</th>
|
||||
<th class="px-4 py-3 w-[20%] text-center">Tanggal</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<div class="border rounded overflow-hidden">
|
||||
<tbody class="divide-y">
|
||||
|
||||
<!-- HEADER -->
|
||||
<table class="w-full text-sm text-left table-fixed border border-gray-200 rounded-t-lg overflow-hidden">
|
||||
<thead class="bg-gray-100 text-gray-700">
|
||||
<tr>
|
||||
<th class="px-4 py-3 w-[15%]">Wisata</th>
|
||||
<th class="px-4 py-3 w-[10%] text-center">Rating</th>
|
||||
<th class="px-4 py-3 w-[60%]">Ulasan</th>
|
||||
<th class="px-4 py-3 w-[15%] text-center">Tanggal</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
@forelse($mentah as $i => $item)
|
||||
<tr class="hover:bg-gray-50">
|
||||
|
||||
<!-- BODY -->
|
||||
<div class="max-h-[300px] overflow-y-auto border-x border-b border-gray-200 rounded-b-lg">
|
||||
<table class="w-full text-sm table-fixed">
|
||||
<td class="px-4 py-3">{{ $mentah->firstItem() + $i }}</td>
|
||||
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
|
||||
@foreach($mentah as $item)
|
||||
<tr class="hover:bg-gray-50 transition">
|
||||
|
||||
<!-- WISATA -->
|
||||
<td class="px-4 py-3 w-[15%] font-medium text-gray-700">
|
||||
<td class="px-4 py-3 font-medium">
|
||||
{{ $item->wisata }}
|
||||
</td>
|
||||
|
||||
<!-- RATING -->
|
||||
<td class="px-4 py-3 w-[10%] text-center">
|
||||
{{ $item->rating }}
|
||||
<td class="px-4 py-3 text-center text-yellow-500">
|
||||
{{ str_repeat('★', round($item->rating)) }}
|
||||
<span class="text-gray-500 ml-1">{{ $item->rating }}</span>
|
||||
</td>
|
||||
|
||||
<!-- ULASAN -->
|
||||
<td class="px-4 py-3 w-[60%] text-black-700 leading-relaxed">
|
||||
<div class="line-clamp-3">
|
||||
<td class="px-4 py-3">
|
||||
<div class="line-clamp-2 text-gray-600">
|
||||
{{ $item->ulasan }}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- TANGGAL -->
|
||||
<td class="px-4 py-3 w-[15%] text-center text-black-700 leading-relaxed">
|
||||
<td class="px-4 py-3 text-center text-gray-500">
|
||||
{{ $item->tanggal }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- INFO -->
|
||||
<div class="text-sm text-gray-500 mt-4 text-center">
|
||||
Showing {{ $mentah->firstItem() }} to {{ $mentah->lastItem() }}
|
||||
of {{ $mentah->total() }} results
|
||||
</div>
|
||||
|
||||
<!-- PAGINATION -->
|
||||
<div class="flex justify-center mt-6 items-center gap-2 text-sm">
|
||||
|
||||
{{-- FIRST --}}
|
||||
@if ($mentah->currentPage() > 1)
|
||||
<a href="{{ $mentah->url(1) }}">«</a>
|
||||
@endif
|
||||
|
||||
{{-- PREV --}}
|
||||
@if ($mentah->onFirstPage())
|
||||
<span class="text-gray-400">‹</span>
|
||||
@else
|
||||
<a href="{{ $mentah->previousPageUrl() }}">‹</a>
|
||||
@endif
|
||||
|
||||
@php
|
||||
$start = max($mentah->currentPage() - 2, 1);
|
||||
$end = min($mentah->currentPage() + 2, $mentah->lastPage());
|
||||
@endphp
|
||||
|
||||
{{-- NUMBER DINAMIS --}}
|
||||
@for ($i = $start; $i <= $end; $i++)
|
||||
@if ($i == $mentah->currentPage())
|
||||
<span class="px-3 py-1 bg-blue-600 text-white rounded-full">{{ $i }}</span>
|
||||
@else
|
||||
<a href="{{ $mentah->url($i) }}" class="px-3 py-1 hover:underline">
|
||||
{{ $i }}
|
||||
</a>
|
||||
@endif
|
||||
@endfor
|
||||
|
||||
{{-- NEXT --}}
|
||||
@if ($mentah->hasMorePages())
|
||||
<a href="{{ $mentah->nextPageUrl() }}">›</a>
|
||||
@else
|
||||
<span class="text-gray-400">›</span>
|
||||
@endif
|
||||
|
||||
{{-- LAST --}}
|
||||
@if ($mentah->currentPage() < $mentah->lastPage())
|
||||
<a href="{{ $mentah->url($mentah->lastPage()) }}">»</a>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- BUTTON ANALISIS -->
|
||||
<form action="{{ route('ulasan.analisis') }}" method="POST">
|
||||
@csrf
|
||||
<button class="bg-green-600 text-white px-5 py-2 rounded">
|
||||
Proses Analisis
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- PREPROCESSING -->
|
||||
<div class="bg-white rounded-xl shadow p-6">
|
||||
<h3 class="font-semibold mb-4">Hasil Preprocessing</h3>
|
||||
|
||||
<div id="preprocessingTabel">
|
||||
|
||||
<!-- TABLE -->
|
||||
<div class="max-h-[300px] overflow-y-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-gray-100 sticky top-0">
|
||||
<tr>
|
||||
<th class="px-4 py-2">Wisata</th>
|
||||
<th class="px-4 py-2">Ulasan Mentah</th>
|
||||
<th class="px-4 py-2">Ulasan Bersih</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($preprocessing as $row)
|
||||
<tr class="border-b">
|
||||
<td class="px-4 py-2">{{ $row->wisata }}</td>
|
||||
<td class="px-4 py-2">{{ $row->ulasan_asli }}</td>
|
||||
<td class="px-4 py-2">{{ $row->stemming }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="3" class="text-center py-4 text-gray-400">
|
||||
<td colspan="5" class="text-center py-6 text-gray-400">
|
||||
Belum ada data
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="p-4 flex justify-between items-center text-sm text-gray-500">
|
||||
|
||||
<!-- KIRI (FINAL FIX) -->
|
||||
<div>
|
||||
Menampilkan {{ $mentah->firstItem() ?? 0 }} - {{ $mentah->lastItem() ?? 0 }}
|
||||
dari {{ $mentah->total() }} data
|
||||
</div>
|
||||
|
||||
<!-- INFO -->
|
||||
<div class="text-sm text-gray-500 mt-4 text-center">
|
||||
Showing {{ $preprocessing->firstItem() }} to {{ $preprocessing->lastItem() }}
|
||||
of {{ $preprocessing->total() }} results
|
||||
</div>
|
||||
<!-- KANAN (PAGINATION) -->
|
||||
<div class="flex items-center gap-1">
|
||||
|
||||
<!-- PAGINATION -->
|
||||
<div class="flex justify-center mt-4 items-center gap-2 text-sm">
|
||||
|
||||
{{-- PREV --}}
|
||||
@if ($preprocessing->onFirstPage())
|
||||
<span class="text-gray-400">‹</span>
|
||||
@if ($mentah->onFirstPage())
|
||||
<span class="px-3 py-1 bg-gray-200 rounded-lg">«</span>
|
||||
@else
|
||||
<a href="{{ $preprocessing->previousPageUrl() }}">‹</a>
|
||||
<a href="{{ $mentah->previousPageUrl() }}"
|
||||
class="px-3 py-1 bg-gray-100 rounded-lg">«</a>
|
||||
@endif
|
||||
|
||||
@php
|
||||
$start = max($preprocessing->currentPage() - 2, 1);
|
||||
$end = min($preprocessing->currentPage() + 2, $preprocessing->lastPage());
|
||||
@endphp
|
||||
|
||||
{{-- NUMBER --}}
|
||||
@for ($i = $start; $i <= $end; $i++)
|
||||
@if ($i == $preprocessing->currentPage())
|
||||
<span class="px-3 py-1 bg-blue-600 text-white rounded-full">
|
||||
{{ $i }}
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $preprocessing->url($i) }}" class="px-3 py-1 hover:underline">
|
||||
{{ $i }}
|
||||
</a>
|
||||
@for ($i = 1; $i <= $mentah->lastPage(); $i++)
|
||||
@if ($i == $mentah->currentPage())
|
||||
<span class="px-3 py-1 bg-blue-600 text-white rounded-lg">{{ $i }}</span>
|
||||
@elseif ($i <= 3 || $i > $mentah->lastPage() - 2 || abs($i - $mentah->currentPage()) <= 1)
|
||||
<a href="{{ $mentah->url($i) }}"
|
||||
class="px-3 py-1 bg-gray-100 rounded-lg">{{ $i }}</a>
|
||||
@elseif ($i == 4 || $i == $mentah->lastPage() - 3)
|
||||
<span class="px-2">...</span>
|
||||
@endif
|
||||
@endfor
|
||||
|
||||
{{-- NEXT --}}
|
||||
@if ($preprocessing->hasMorePages())
|
||||
<a href="{{ $preprocessing->nextPageUrl() }}">›</a>
|
||||
@if ($mentah->hasMorePages())
|
||||
<a href="{{ $mentah->nextPageUrl() }}"
|
||||
class="px-3 py-1 bg-gray-100 rounded-lg">»</a>
|
||||
@else
|
||||
<span class="text-gray-400">›</span>
|
||||
<span class="px-3 py-1 bg-gray-200 rounded-lg">»</span>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
document.getElementById("filterWisata").addEventListener("change", function () {
|
||||
let wisata = this.value;
|
||||
|
||||
fetch(`/ulasan?wisata=${wisata}`)
|
||||
.then(res => res.text())
|
||||
.then(html => {
|
||||
document.querySelector("#tableContainer").innerHTML =
|
||||
new DOMParser().parseFromString(html, "text/html")
|
||||
.querySelector("#tableContainer").innerHTML;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- BUTTON ANALISIS -->
|
||||
<div class="flex justify-end">
|
||||
<form action="{{ route('ulasan.analisis') }}" method="POST">
|
||||
@csrf
|
||||
<button class="bg-blue-600 text-white px-6 py-3 rounded-full shadow-lg">
|
||||
Proses Analisis
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- AUTO SUBMIT UPLOAD -->
|
||||
<script>
|
||||
document.addEventListener("click", function(e) {
|
||||
if(e.target.closest("#preprocessingTable a")) {
|
||||
e.preventDefault();
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const input = document.getElementById("fileInput");
|
||||
const form = document.getElementById("uploadForm");
|
||||
|
||||
let url = e.target.closest("a").getAttribute("href");
|
||||
|
||||
fetch(url)
|
||||
.then(res => res.text())
|
||||
.then(html => {
|
||||
let doc = new DOMParser().parseFromString(html, 'text/html');
|
||||
let newContent = doc.querySelector("#preprocessingTable").innerHTML;
|
||||
|
||||
document.querySelector("#preprocessingTable").innerHTML = newContent;
|
||||
});
|
||||
}
|
||||
input.addEventListener("change", function () {
|
||||
form.submit();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
|
|
@ -31,12 +31,14 @@
|
|||
Route::get('/ulasan', [UlasanController::class, 'index'])->name('ulasan.index');
|
||||
Route::post('/ulasan/ambil', [UlasanController::class, 'ambilData'])->name('ulasan.ambil');
|
||||
Route::post('/ulasan/analisis', [UlasanController::class, 'analisisData'])->name('ulasan.analisis');
|
||||
Route::post('/ulasan/upload', [UlasanController::class, 'upload'])->name('ulasan.upload');
|
||||
Route::get('/hasil-analisis', [AnalisisController::class, 'index'])
|
||||
->name('analisis.index');
|
||||
Route::get('/rekomendasi', [RekomendasiController::class, 'index'])
|
||||
->name('rekomendasi.index');;
|
||||
Route::get('/', function () {
|
||||
return redirect()->route('login');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue