Added flash messages, minor UI changes
This commit is contained in:
parent
03da2ae482
commit
6bc022b0f3
|
@ -8,7 +8,7 @@ use App\Models\Question;
|
||||||
use App\Models\Response;
|
use App\Models\Response;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Session;
|
||||||
class FormController extends Controller
|
class FormController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
|
@ -64,7 +64,7 @@ return view('forms.edit', compact('form', 'questions'));
|
||||||
|
|
||||||
$question->save();
|
$question->save();
|
||||||
}
|
}
|
||||||
|
Session::flash('success', 'Form created successfully!');
|
||||||
return response()->json(['success' => true, 'form_id' => $form->id]);
|
return response()->json(['success' => true, 'form_id' => $form->id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,12 @@ return view('forms.edit', compact('form', 'questions'));
|
||||||
return view('forms.show', compact('form'));
|
return view('forms.show', compact('form'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function preview($id)
|
||||||
|
{
|
||||||
|
$form = Form::findOrFail($id);
|
||||||
|
return view('forms.previewForm', compact('form'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function update(Request $request, Form $form)
|
public function update(Request $request, Form $form)
|
||||||
{
|
{
|
||||||
|
@ -147,6 +153,6 @@ return view('forms.edit', compact('form', 'questions'));
|
||||||
// This will also delete all related questions and responses due to foreign key constraints
|
// This will also delete all related questions and responses due to foreign key constraints
|
||||||
$form->delete();
|
$form->delete();
|
||||||
|
|
||||||
return redirect()->route('forms.index')->with('success', 'Form deleted successfully.');
|
return redirect()->route('forms.index')->with('delete', 'Form deleted successfully.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,9 @@ public function viewResponses(Form $form)
|
||||||
public function showForm(Form $form)
|
public function showForm(Form $form)
|
||||||
{
|
{
|
||||||
$questions = $form->questions;
|
$questions = $form->questions;
|
||||||
|
if (!$form->is_published) {
|
||||||
|
return redirect('/forms')->with('delete', 'This form is not published.');
|
||||||
|
}
|
||||||
|
|
||||||
return view('responses.showForm', compact('form', 'questions'));
|
return view('responses.showForm', compact('form', 'questions'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"sweetalert": "^2.1.2"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@popperjs/core": "^2.11.6",
|
"@popperjs/core": "^2.11.6",
|
||||||
"axios": "^1.6.4",
|
"axios": "^1.6.4",
|
||||||
|
@ -723,6 +726,11 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/es6-object-assign": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw=="
|
||||||
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.21.5",
|
"version": "0.21.5",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
|
||||||
|
@ -994,6 +1002,11 @@
|
||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/promise-polyfill": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-g0LWaH0gFsxovsU7R5LrrhHhWAWiHRnh1GPrhXnPgYsDkIqjRYUYSZEsej/wtleDrz5xVSIDbeKfidztp2XHFQ=="
|
||||||
|
},
|
||||||
"node_modules/proxy-from-env": {
|
"node_modules/proxy-from-env": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
@ -1073,6 +1086,15 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sweetalert": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-iWx7X4anRBNDa/a+AdTmvAzQtkN1+s4j/JJRWlHpYE8Qimkohs8/XnFcWeYHH2lMA8LRCa5tj2d244If3S/hzA==",
|
||||||
|
"dependencies": {
|
||||||
|
"es6-object-assign": "^1.1.0",
|
||||||
|
"promise-polyfill": "^6.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
|
|
@ -12,5 +12,8 @@
|
||||||
"laravel-vite-plugin": "^1.0.0",
|
"laravel-vite-plugin": "^1.0.0",
|
||||||
"sass": "^1.56.1",
|
"sass": "^1.56.1",
|
||||||
"vite": "^5.0.0"
|
"vite": "^5.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"sweetalert": "^2.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 75%;
|
left: 75%;
|
||||||
top: 10%;
|
top: 10%;
|
||||||
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btnp {
|
.btnp {
|
||||||
|
|
|
@ -81,10 +81,24 @@ body {
|
||||||
background-color: #c5c5c5;
|
background-color: #c5c5c5;
|
||||||
}
|
}
|
||||||
.form_name {
|
.form_name {
|
||||||
color: #5f6368;
|
color: black;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
.roboto-light {
|
.roboto-light {
|
||||||
font-family: "Roboto", sans-serif;
|
font-family: "Roboto", sans-serif;
|
||||||
font-weight: 150;
|
font-weight: 150;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#shareLink{
|
||||||
|
border: 2px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary{
|
||||||
|
background-color: rgb(103, 58, 183);
|
||||||
|
}
|
||||||
|
|
||||||
|
:hover.btn-primary{
|
||||||
|
background-color: rgb(96, 4, 96);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
.form_preview {
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: auto;
|
||||||
|
background-color: #f4f4f9;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#form_name {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 135%;
|
||||||
|
border-bottom: 1px solid #f4f4f9;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#form_desc {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 100%;
|
||||||
|
border-bottom: 1px solid #f4f4f9;
|
||||||
|
color: black;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.question {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
border-top: 8px solid rgb(103, 58, 183);
|
||||||
|
}
|
||||||
|
|
||||||
|
.question_title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option input[type="radio"],
|
||||||
|
.option input[type="checkbox"] {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
|
@ -48,7 +48,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-secondary" onclick="addOption(this)">Add Option</button>
|
<button class="btn btn-secondary" onclick="addOption(this)">Add Option</button>
|
||||||
<button class="btnn" onclick="deleteQuestion(this)">
|
<button class="btnn" onclick="deleteQuestion(this)">
|
||||||
<img src={{asset("images/bin.png")}} alt="" width="20px" height="20px" />
|
<img src={{ asset('images/bin.png') }} alt="" width="20px" height="20px" />
|
||||||
</button>
|
</button>
|
||||||
`;
|
`;
|
||||||
questionsSection.appendChild(newQuestionDiv);
|
questionsSection.appendChild(newQuestionDiv);
|
||||||
|
@ -133,7 +133,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
window.changeQuestionType = changeQuestionType;
|
window.changeQuestionType = changeQuestionType;
|
||||||
window.saveForm = saveForm;
|
window.saveForm = saveForm;
|
||||||
|
|
||||||
window.previewForm = function () {
|
window.previewForm = function (formId) {
|
||||||
const formTitle = document.getElementById("form-title").value;
|
const formTitle = document.getElementById("form-title").value;
|
||||||
const formDescription =
|
const formDescription =
|
||||||
document.getElementById("form-description").value;
|
document.getElementById("form-description").value;
|
||||||
|
@ -160,7 +160,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
data: JSON.stringify(formData),
|
data: JSON.stringify(formData),
|
||||||
});
|
});
|
||||||
|
|
||||||
window.open(`preview.html?${formParams.toString()}`, "_blank");
|
window.location.href = '/forms/' + formId + '/preview';
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addNewQuestion = addNewQuestion;
|
window.addNewQuestion = addNewQuestion;
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="question_form">
|
<div style="background-color: #f0ebf8" class="question_form">
|
||||||
<br />
|
<br />
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="question_title_section">
|
<div class="question_title_section">
|
||||||
|
@ -92,14 +92,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<div id="moveableDiv">
|
<div id="moveableDiv">
|
||||||
<button class="btnp" onclick="addNewQuestion(); moveDown()">
|
<button style="background-color: white"class="btnp" onclick="addNewQuestion(); moveDown()">
|
||||||
<img src={{ asset('images/add.png') }} alt="" width="20px" height="20px" />
|
<img src={{ asset('images/add.png') }} alt="" width="20px" height="20px" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btnsub">
|
<div style="background-color: #f0ebf8"class="btnsub">
|
||||||
<span>
|
<span>
|
||||||
<button type="submit" name="save" value="save" onclick="saveForm()"
|
<button type="submit" name="save" value="save" onclick="saveForm()"
|
||||||
class="btnsave btn btn-secondary">
|
class="btnsave btn btn-secondary">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
@ -9,20 +10,25 @@
|
||||||
.dropdown:hover .dropdown-menu {
|
.dropdown:hover .dropdown-menu {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shadow-custom {
|
.shadow-custom {
|
||||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-50">
|
|
||||||
|
<body style="bg-gray-100">
|
||||||
<nav class="bg-white p-4 shadow-lg">
|
<nav class="bg-white p-4 shadow-lg">
|
||||||
<div class="container mx-auto flex justify-between items-center">
|
<div class="container mx-auto flex justify-between items-center">
|
||||||
<a href="{{ url('/') }}" style="color: rgb(103,58,183)" class="text-3xl font-bold font-sans">LaraForms</a>
|
<a href="{{ url('/') }}" style="color: rgb(103,58,183)"
|
||||||
|
class="text-3xl font-bold font-sans">LaraForms</a>
|
||||||
<div class="relative dropdown">
|
<div class="relative dropdown">
|
||||||
<button id="profileMenuButton" class="flex items-center focus:outline-none">
|
<button id="profileMenuButton" class="flex items-center focus:outline-none">
|
||||||
<img src="{{ asset('images/user.png') }}" alt="Profile" class="w-10 h-10 rounded-full border-2 border-white">
|
<img src="{{ asset('images/user.png') }}" alt="Profile"
|
||||||
|
class="w-10 h-10 rounded-full border-2 border-white">
|
||||||
</button>
|
</button>
|
||||||
<div id="profileMenu" class="dropdown-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-2">
|
<div id="profileMenu"
|
||||||
|
class="dropdown-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-2">
|
||||||
<form method="POST" action="{{ route('logout') }}">
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
@csrf
|
@csrf
|
||||||
<button type="submit" class="block px-4 py-2 text-gray-700 hover:bg-gray-200 w-full text-left">
|
<button type="submit" class="block px-4 py-2 text-gray-700 hover:bg-gray-200 w-full text-left">
|
||||||
|
@ -33,10 +39,21 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
@if (session('success'))
|
||||||
|
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-2 rounded relative mt-4" role="alert">
|
||||||
|
<span class="block sm:inline">{{ session('success') }}</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@if (session('delete'))
|
||||||
|
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-2 rounded relative mt-4" role="alert">
|
||||||
|
<span class="block sm:inline">{{ session('delete') }}</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
<div class="container mx-auto mt-10">
|
<div class="container mx-auto mt-10">
|
||||||
<div class="flex justify-between mb-6 items-center">
|
<div class="flex justify-between mb-6 items-center">
|
||||||
<a href="{{ route('forms.create') }}" class="inline-block px-6 py-3 text-white font-semibold rounded-md shadow bg-purple-700 hover:bg-purple-900 transition duration-200">Start a new form</a>
|
<a href="{{ route('forms.create') }}"
|
||||||
|
class="inline-block px-6 py-3 text-white font-semibold rounded-md shadow bg-purple-700 hover:bg-purple-900 transition duration-200">Start
|
||||||
|
a new form</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<h2 class="text-3xl font-semibold text-gray-800 font-sans">Recent Forms</h2>
|
<h2 class="text-3xl font-semibold text-gray-800 font-sans">Recent Forms</h2>
|
||||||
|
@ -48,30 +65,41 @@
|
||||||
<table class="min-w-full bg-white rounded-md overflow-hidden">
|
<table class="min-w-full bg-white rounded-md overflow-hidden">
|
||||||
<thead class="bg-gray-100">
|
<thead class="bg-gray-100">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">Form Title</th>
|
<th
|
||||||
<th class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">Created At</th>
|
class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
|
||||||
<th class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">Responses</th>
|
Form Title</th>
|
||||||
<th class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">Actions</th>
|
<th
|
||||||
|
class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
|
||||||
|
Created At</th>
|
||||||
|
<th
|
||||||
|
class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
|
||||||
|
Responses</th>
|
||||||
|
<th
|
||||||
|
class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
|
||||||
|
Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($forms as $form)
|
@foreach ($forms as $form)
|
||||||
<tr class="hover:bg-gray-50 transition duration-150">
|
<tr class="hover:bg-gray-50 transition duration-150">
|
||||||
<td class="py-4 px-6 border-b border-gray-200">
|
<td class="py-4 px-6 border-b border-gray-200">
|
||||||
<a href="{{ route('forms.show', $form) }}" class="text-blue-600 font-semibold hover:underline">{{ $form->title }}</a>
|
<a href="{{ route('forms.show', $form) }}"
|
||||||
|
class="text-blue-600 font-semibold hover:underline">{{ $form->title }}</a>
|
||||||
<p class="text-gray-600">{{ $form->description }}</p>
|
<p class="text-gray-600">{{ $form->description }}</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="py-4 px-6 border-b border-gray-200">{{ $form->created_at->format('M d, Y') }}</td>
|
<td class="py-4 px-6 border-b border-gray-200">{{ $form->created_at->format('M d, Y') }}
|
||||||
|
</td>
|
||||||
<td class="py-4 px-6 border-b border-gray-200">
|
<td class="py-4 px-6 border-b border-gray-200">
|
||||||
@if ($form->is_published)
|
<a href="{{ route('responses.viewResponses', $form) }}"
|
||||||
<a href="{{ route('responses.viewResponses', $form) }}" class="text-blue-500 hover:underline">View Responses</a>
|
class="text-blue-500 hover:underline">View Responses</a>
|
||||||
@else
|
|
||||||
<span class="text-gray-600">Not Published</span>
|
|
||||||
@endif
|
|
||||||
</td>
|
</td>
|
||||||
<td class="py-8 px-6 border-b border-gray-200 flex items-center space-x-10">
|
<td class="py-8 px-6 border-b border-gray-200 flex items-center space-x-10">
|
||||||
<a href="{{ route('forms.edit', $form) }}" class="text-green-500 hover:underline">Edit</a>
|
@if (!$form->is_published)
|
||||||
<form action="{{ route('forms.destroy', $form) }}" method="POST" class="inline-block">
|
<a href="{{ route('forms.edit', $form) }}"
|
||||||
|
class="text-green-500 hover:underline">Edit</a>
|
||||||
|
@endif
|
||||||
|
<form action="{{ route('forms.destroy', $form) }}" method="POST"
|
||||||
|
class="inline-block">
|
||||||
@csrf
|
@csrf
|
||||||
@method('DELETE')
|
@method('DELETE')
|
||||||
<button type="submit" class="text-red-500 hover:underline">Delete</button>
|
<button type="submit" class="text-red-500 hover:underline">Delete</button>
|
||||||
|
@ -89,13 +117,13 @@
|
||||||
document.getElementById('profileMenuButton').addEventListener('click', function() {
|
document.getElementById('profileMenuButton').addEventListener('click', function() {
|
||||||
document.getElementById('profileMenu').classList.toggle('hidden');
|
document.getElementById('profileMenu').classList.toggle('hidden');
|
||||||
});
|
});
|
||||||
|
setTimeout(function() {
|
||||||
|
var successMessage = document.getElementById('successMessage');
|
||||||
|
if (successMessage) {
|
||||||
|
successMessage.remove();
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Form Preview</title>
|
||||||
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="{{asset("css/preview.css")}}">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="form_preview">
|
||||||
|
<h1 id="form_name"></h1>
|
||||||
|
<p id="form_desc"></p>
|
||||||
|
<div id="questions_container"></div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const formName = document.getElementById('form_name');
|
||||||
|
const formDesc = document.getElementById('form_desc');
|
||||||
|
const questionsContainer = document.getElementById('questions_container');
|
||||||
|
|
||||||
|
function getParameterByName(name, url = window.location.href) {
|
||||||
|
name = name.replace(/[\[\]]/g, '\\$&');
|
||||||
|
const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`),
|
||||||
|
results = regex.exec(url);
|
||||||
|
if (!results) return null;
|
||||||
|
if (!results[2]) return '';
|
||||||
|
return decodeURIComponent(results[2].replace(/\+/g, ' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
const formTitle = getParameterByName('title');
|
||||||
|
const formDescription = getParameterByName('description');
|
||||||
|
const formData = JSON.parse(getParameterByName('data'));
|
||||||
|
|
||||||
|
formName.textContent = formTitle;
|
||||||
|
formDesc.textContent = formDescription;
|
||||||
|
|
||||||
|
formData.forEach((question, index) => {
|
||||||
|
const questionType = question.type;
|
||||||
|
const questionText = question.text;
|
||||||
|
const options = question.options;
|
||||||
|
|
||||||
|
let questionHtml = `<div class="question"><h3 class="question_title">${questionText}</h3><div class="options">`;
|
||||||
|
|
||||||
|
options.forEach(option => {
|
||||||
|
if (questionType === 'multiple_choice') {
|
||||||
|
questionHtml += `<div class="option"><input type="radio" name="q${index}">${option}</div>`;
|
||||||
|
} else if (questionType === 'checkbox') {
|
||||||
|
questionHtml += `<div class="option"><input type="checkbox" name="q${index}">${option}</div>`;
|
||||||
|
} else if (questionType === 'dropdown') {
|
||||||
|
if (option === options[0]) questionHtml += `<select class="form-control">`;
|
||||||
|
questionHtml += `<option>${option}</option>`;
|
||||||
|
if (option === options[options.length - 1]) questionHtml += `</select>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
questionHtml += `</div></div>`;
|
||||||
|
questionsContainer.innerHTML += questionHtml;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -17,9 +17,9 @@
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
|
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body style="background-color: #f0ebf8">
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<nav class="navbar navbar-expand-md navbar-light shadow-sm" style="background-color: rgb(103,58,183)">
|
<nav class="navbar navbar-expand-md navbar-light shadow-md px-4 py-3 flex justify-between items-center" style="background-color: rgb(103,58,183)">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a class="navbar-brand text-white" href="{{ url('/') }}">
|
<a class="navbar-brand text-white" href="{{ url('/') }}">
|
||||||
{{ config('app.name', 'Laravel') }}
|
{{ config('app.name', 'Laravel') }}
|
||||||
|
|
|
@ -1,51 +1,5 @@
|
||||||
{{-- @extends('layouts.app')
|
{{-- @extends('layouts.app')
|
||||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||||
@section('content')
|
|
||||||
<div class="container">
|
|
||||||
<h1>{{ $form->title }}</h1>
|
|
||||||
<p>{{ $form->description }}</p>
|
|
||||||
|
|
||||||
<form action="{{ route('responses.submitForm', $form) }}" method="POST">
|
|
||||||
@csrf
|
|
||||||
@foreach ($questions as $question)
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{ $question->question_text }}</label>
|
|
||||||
@if ($question->type == 'multiple_choice')
|
|
||||||
@foreach (json_decode($question->options) as $option)
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="radio" name="answers[{{ $question->id }}]"
|
|
||||||
value="{{ $option }}">
|
|
||||||
<label class="form-check-label">{{ $option }}</label>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
@elseif($question->type == 'checkbox')
|
|
||||||
@foreach (json_decode($question->options) as $option)
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" name="answers[{{ $question->id }}][]"
|
|
||||||
value="{{ $option }}">
|
|
||||||
<label class="form-check-label">{{ $option }}</label>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
@elseif($question->type == 'dropdown')
|
|
||||||
<select class="form-control" name="answers[{{ $question->id }}]">
|
|
||||||
@foreach (json_decode($question->options) as $option)
|
|
||||||
<option value="{{ $option }}">{{ $option }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<button type="submit" class="focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-sm px-5 py-2.5 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900"">Submit</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
@endsection --}}
|
|
||||||
|
|
||||||
|
|
||||||
@extends('layouts.app')
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container mx-auto py-8">
|
<div class="container mx-auto py-8">
|
||||||
|
@ -91,4 +45,53 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
--}}
|
||||||
|
|
||||||
|
|
||||||
|
@extends('layouts.app')
|
||||||
|
@section('content')
|
||||||
|
<div class="container mx-auto py-8 px-4 md:px-0">
|
||||||
|
<div class="bg-white shadow-md rounded-lg p-6">
|
||||||
|
<h1 class="text-3xl font-semibold text-gray-900">{{ $form->title }}</h1>
|
||||||
|
<p class="text-gray-600 mt-2">{{ $form->description }}</p>
|
||||||
|
|
||||||
|
<form action="{{ route('responses.submitForm', $form) }}" method="POST" class="mt-8">
|
||||||
|
@csrf
|
||||||
|
@foreach ($questions as $question)
|
||||||
|
<div class="mt-6">
|
||||||
|
<label class="block font-medium text-base text-gray-800 mb-2">{{ $question->question_text }}</label>
|
||||||
|
@if ($question->type == 'multiple_choice')
|
||||||
|
@foreach (json_decode($question->options) as $option)
|
||||||
|
<label class="flex items-center mt-2">
|
||||||
|
<input class="form-radio text-base text-purple-600 h-4 w-4" type="radio" name="answers[{{ $question->id }}]" value="{{ $option }}">
|
||||||
|
<span class="ml-2 text-gray-700">{{ $option }}</span>
|
||||||
|
</label>
|
||||||
|
@endforeach
|
||||||
|
@elseif($question->type == 'checkbox')
|
||||||
|
@foreach (json_decode($question->options) as $option)
|
||||||
|
<label class="flex items-center mt-2">
|
||||||
|
<input class="form-checkbox text-purple-600 h-4 w-4" type="checkbox" name="answers[{{ $question->id }}][]" value="{{ $option }}">
|
||||||
|
<span class="ml-2 text-gray-700">{{ $option }}</span>
|
||||||
|
</label>
|
||||||
|
@endforeach
|
||||||
|
@elseif($question->type == 'dropdown')
|
||||||
|
<select class="form-select mt-2 block w-full p-2 border border-gray-300 rounded-md bg-white shadow-sm focus:outline-none focus:ring-purple-500 focus:border-purple-500 sm:text-sm" name="answers[{{ $question->id }}]">
|
||||||
|
@foreach (json_decode($question->options) as $option)
|
||||||
|
<option value="{{ $option }}">{{ $option }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
@elseif($question->type == 'short_answer')
|
||||||
|
<input type="text" name="answers[{{ $question->id }}]" class="form-input mt-2 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-purple-500 focus:border-purple-500 sm:text-sm">
|
||||||
|
@elseif($question->type == 'long_answer')
|
||||||
|
<textarea name="answers[{{ $question->id }}]" class="form-textarea mt-2 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-purple-500 focus:border-purple-500 sm:text-sm"></textarea>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<button type="submit" class="mt-8 w-full md:w-auto inline-flex justify-center items-center px-6 py-3 bg-purple-700 border border-transparent rounded-md font-semibold text-white text-lg uppercase tracking-widest hover:bg-purple-800 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2">
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
|
@ -4,45 +4,61 @@
|
||||||
<head>
|
<head>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">
|
||||||
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900&display=swap"
|
|
||||||
rel="stylesheet">
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>Response Detail</title>
|
<title>Response Detail</title>
|
||||||
<link rel="stylesheet" href="{{ asset('css/index.css') }}">
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="bg-gray-50 font-roboto">
|
||||||
<div class="form_header roboto-light">
|
<div class="bg-white shadow-md p-4 flex justify-between items-center">
|
||||||
<div class="form_header_left">
|
<div class="flex items-center">
|
||||||
<a href="/forms"><img src="{{ asset('images/google-form.png') }}" class="form_header_icon" height="45px"
|
<a href="/forms">
|
||||||
width="40px" /></a>
|
<img src="{{ asset('images/google-form.png') }}" class="h-12 w-12 mr-4" alt="Google Form Icon" />
|
||||||
<h1 class="form_name">{{ $form->title }} - Response Detail</h1>
|
</a>
|
||||||
|
<h1 class="text-xl font-semibold">{{ $form->title }} - Response Detail</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
|
||||||
<div class="response_detail">
|
<div class="container mx-auto mt-8">
|
||||||
<h2>Response from {{ $responses->first()->user->name ?? 'Anonymous' }} - {{ $responses->first()->submitted_at }}</h2>
|
<div class="bg-white p-6 shadow-md rounded-lg">
|
||||||
|
<h2 class="text-2xl font-bold mb-4">Response from {{ $responses->first()->user->name ?? 'Anonymous' }} - {{ $responses->first()->submitted_at }}</h2>
|
||||||
|
|
||||||
@foreach ($responses as $response)
|
@foreach ($responses as $response)
|
||||||
@php
|
@php
|
||||||
$question = $questions[$response->question_id];
|
$question = $questions[$response->question_id] ?? null;
|
||||||
$decodedAnswers = json_decode($response->answers, true);
|
$decodedAnswers = json_decode($response->answers, true);
|
||||||
@endphp
|
@endphp
|
||||||
<div class="question">
|
|
||||||
<h3>{{ $question->question_text }}</h3>
|
@if ($question)
|
||||||
@if ($question->type == 'multiple_choice' || $question->type == 'checkbox' || $question->type == 'dropdown')
|
<div class="mb-6">
|
||||||
|
<h3 class="text-lg font-medium">{{ $question->question_text }}</h3>
|
||||||
|
@if ($question->type == 'dropdown')
|
||||||
|
<select disabled class="w-full p-2 mt-2 border rounded">
|
||||||
@foreach (json_decode($question->options) as $option)
|
@foreach (json_decode($question->options) as $option)
|
||||||
<p>
|
<option {{ ($option == $decodedAnswers) ? 'selected' : '' }}>
|
||||||
<input type="radio" disabled {{ in_array($option, (array)$decodedAnswers) ? 'checked' : '' }}>
|
|
||||||
{{ $option }}
|
{{ $option }}
|
||||||
</p>
|
</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
</select>
|
||||||
|
@elseif (in_array($question->type, ['multiple_choice', 'checkbox']))
|
||||||
|
<div class="mt-2">
|
||||||
|
@foreach (json_decode($question->options) as $option)
|
||||||
|
<label class="block">
|
||||||
|
<input type="{{ $question->type == 'checkbox' ? 'checkbox' : 'radio' }}" disabled {{ in_array($option, (array)$decodedAnswers) ? 'checked' : '' }} class="mr-2">
|
||||||
|
{{ $option }}
|
||||||
|
</label>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
@else
|
@else
|
||||||
<p>{{ is_array($decodedAnswers) ? implode(', ', $decodedAnswers) : $decodedAnswers }}</p>
|
<p class="mt-2 p-2 bg-gray-100 rounded">{{ is_array($decodedAnswers) ? implode(', ', $decodedAnswers) : $decodedAnswers }}</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@else
|
||||||
|
<p class="text-red-500">Question not found for ID: {{ $response->question_id }}</p>
|
||||||
|
@endif
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,28 +75,29 @@
|
||||||
<head>
|
<head>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">
|
||||||
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900&display=swap"
|
|
||||||
rel="stylesheet">
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>Response Detail</title>
|
<title>Response Detail</title>
|
||||||
<link rel="stylesheet" href="{{ asset('css/index.css') }}">
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body style="background-color: #f0ebf8" class="font-roboto">
|
||||||
<div class="form_header roboto-light">
|
<header class="bg-white shadow-md py-4">
|
||||||
<div class="form_header_left">
|
<div class="container mx-auto flex justify-between items-center">
|
||||||
<a href="/forms"><img src="{{ asset('images/google-form.png') }}" class="form_header_icon" height="45px"
|
<div class="flex items-center">
|
||||||
width="40px" /></a>
|
<a href="/forms">
|
||||||
<h1 class="form_name">{{ $form->title }} - Response Detail</h1>
|
<img src="{{ asset('images/google-form.png') }}" class="h-12 w-12 mr-4" alt="Google Form Icon" />
|
||||||
|
</a>
|
||||||
|
<h1 style="color: rgb(103,58,183)" class="text-xl font-semibold">{{ $form->title }} - Response Detail</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
</header>
|
||||||
<div class="response_detail">
|
|
||||||
<h2>Response from {{ $responses->first()->user->name ?? 'Anonymous' }} - {{ $responses->first()->submitted_at }}</h2>
|
|
||||||
|
|
||||||
|
<main class="container mx-auto mt-8">
|
||||||
|
<div class="bg-white p-8 shadow-lg rounded-lg">
|
||||||
|
<h2 class="text-2xl font-bold mb-6">Response from {{ $responses->first()->user->name ?? 'Anonymous' }} - {{ $responses->first()->submitted_at }}</h2>
|
||||||
|
|
||||||
@foreach ($responses as $response)
|
@foreach ($responses as $response)
|
||||||
@php
|
@php
|
||||||
|
@ -89,10 +106,10 @@
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@if ($question)
|
@if ($question)
|
||||||
<div class="question">
|
<div class="mb-8">
|
||||||
<h3>{{ $question->question_text }}</h3>
|
<h3 class="text-lg font-medium mb-2">{{ $question->question_text }}</h3>
|
||||||
@if ($question->type == 'dropdown')
|
@if ($question->type == 'dropdown')
|
||||||
<select disabled>
|
<select disabled class="w-full p-3 border border-gray-600 rounded-lg">
|
||||||
@foreach (json_decode($question->options) as $option)
|
@foreach (json_decode($question->options) as $option)
|
||||||
<option {{ ($option == $decodedAnswers) ? 'selected' : '' }}>
|
<option {{ ($option == $decodedAnswers) ? 'selected' : '' }}>
|
||||||
{{ $option }}
|
{{ $option }}
|
||||||
|
@ -100,25 +117,26 @@
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@elseif (in_array($question->type, ['multiple_choice', 'checkbox']))
|
@elseif (in_array($question->type, ['multiple_choice', 'checkbox']))
|
||||||
|
<div class="space-y-2">
|
||||||
@foreach (json_decode($question->options) as $option)
|
@foreach (json_decode($question->options) as $option)
|
||||||
<p>
|
<label class="block">
|
||||||
<input type="{{ $question->type == 'checkbox' ? 'checkbox' : 'radio' }}" disabled {{ in_array($option, (array)$decodedAnswers) ? 'checked' : '' }}>
|
<input type="{{ $question->type == 'checkbox' ? 'checkbox' : 'radio' }}" disabled {{ in_array($option, (array)$decodedAnswers) ? 'checked' : '' }} class="mr-2">
|
||||||
{{ $option }}
|
{{ $option }}
|
||||||
</p>
|
</label>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
</div>
|
||||||
@else
|
@else
|
||||||
<p>{{ is_array($decodedAnswers) ? implode(', ', $decodedAnswers) : $decodedAnswers }}</p>
|
<p class="mt-2 p-3 bg-gray-100 rounded-lg">{{ is_array($decodedAnswers) ? implode(', ', $decodedAnswers) : $decodedAnswers }}</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<p>Question not found for ID: {{ $response->question_id }}</p>
|
<p class="text-red-500">Question not found for ID: {{ $response->question_id }}</p>
|
||||||
@endif
|
@endif
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
|
|
||||||
<script src="{{ asset('js/script.js') }}"></script>
|
<script src="{{ asset('js/script.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,57 +1,108 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900&display=swap" rel="stylesheet">
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>Form Responses</title>
|
<title>Form Responses</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="{{ asset('css/index.css') }}">
|
<link rel="stylesheet" href="{{ asset('css/index.css') }}">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
|
||||||
<div class="form_header roboto-light">
|
|
||||||
<div class="form_header_left">
|
|
||||||
<a href="/forms"><img src="{{ asset('images/google-form.png') }}" class="form_header_icon" height="45px" width="40px" /></a>
|
|
||||||
<h1 class="form_name">{{ $form->title }} - Responses</h1>
|
|
||||||
</div>
|
|
||||||
<div class="form_header_right">
|
|
||||||
<img src="{{ asset('images/menu.png') }}" alt="menu" height="30px" width="30px" />
|
|
||||||
<img src="{{ asset('images/user.png') }}" alt="" height="30px" width="30px" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="container">
|
|
||||||
<h2>Responses</h2>
|
|
||||||
|
|
||||||
<div class="share-link">
|
<body style="background-color: #f0ebf8" class="font-roboto text-gray-800">
|
||||||
<input type="text" value="{{ route('responses.showForm', $form) }}" id="shareLink" readonly>
|
|
||||||
<button onclick="copyLink()">Copy Link</button>
|
<!-- Header -->
|
||||||
|
<div class="bg-white shadow-md px-6 py-4 flex justify-between items-center">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<a href="/forms" class="mr-4">
|
||||||
|
<img src="{{ asset('images/google-form.png') }}" alt="Google Forms" class="h-12 w-auto">
|
||||||
|
</a>
|
||||||
|
<h1 class="text-2xl font-semibold text-purple-900">{{ $form->title }} - Responses</h1>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img src="{{ asset('images/menu.png') }}" alt="Menu" class="h-8 w-8 mr-4">
|
||||||
|
<img src="{{ asset('images/user.png') }}" alt="User" class="h-8 w-8">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div class="mx-auto max-w-7xl px-6 py-8">
|
||||||
|
|
||||||
|
<!-- Share Link -->
|
||||||
|
<div class="flex items-center mb-6">
|
||||||
|
<h2 class="text-xl font-semibold mr-4">Responses</h2>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<input type="text" value="{{ route('responses.showForm', $form) }}" id="shareLink"
|
||||||
|
class="bg-white border border-gray-300 px-3 py-1 rounded-l sm:w-auto focus:outline-none"
|
||||||
|
readonly>
|
||||||
|
|
||||||
|
<button onclick="copyLink()"
|
||||||
|
class="bg-purple-600 text-white px-4 py-1.5 rounded-r hover:bg-purple-700 focus:outline-none ml-2 sm:ml-0 mt-2 sm:mt-0">
|
||||||
|
Copy Link
|
||||||
|
</button>
|
||||||
|
<!-- Copy Link Notification -->
|
||||||
|
<div id="copyNotification"
|
||||||
|
class="hidden bg-green-100 border border-green-500 text-green-700 px-3 py-2 rounded ml-2">
|
||||||
|
Link copied!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Responses Table -->
|
||||||
|
@if ($responses->isEmpty())
|
||||||
|
<p class="text-gray-600">No responses available.</p>
|
||||||
|
@else
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="min-w-full bg-white shadow-md rounded-lg overflow-hidden">
|
||||||
|
<thead class="bg-gray-200 text-gray-600 text-sm leading-normal">
|
||||||
|
<tr>
|
||||||
|
<th class="py-3 px-6 text-left">User</th>
|
||||||
|
<th class="py-3 px-6 text-left">Submitted At</th>
|
||||||
|
<th class="py-3 px-6 text-left">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="text-gray-600 text-sm font-light">
|
||||||
|
@foreach ($responses as $responseGroup)
|
||||||
|
<tr class="border-b border-gray-200 hover:bg-gray-100">
|
||||||
|
<td class="py-3 px-6 text-left">
|
||||||
|
{{ $responseGroup->first()->user->name ?? 'Anonymous' }}
|
||||||
|
</td>
|
||||||
|
<td class="py-3 px-6 text-left">
|
||||||
|
{{ $responseGroup->first()->created_at->diffForHumans()}}
|
||||||
|
</td>
|
||||||
|
<td class="py-3 px-6 text-left">
|
||||||
|
<a href="{{ route('responses.viewResponse', ['form' => $form, 'responseId' => $responseGroup->first()->response_id]) }}"
|
||||||
|
target="_blank"
|
||||||
|
class="text-blue-600 hover:text-blue-700 focus:outline-none">View Response</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Script for Copy Link Functionality -->
|
||||||
<script>
|
<script>
|
||||||
function copyLink() {
|
function copyLink() {
|
||||||
var copyText = document.getElementById("shareLink");
|
var copyText = document.getElementById("shareLink");
|
||||||
copyText.select();
|
copyText.select();
|
||||||
copyText.setSelectionRange(0, 99999); /* For mobile devices */
|
copyText.setSelectionRange(0, 99999); /* For mobile devices */
|
||||||
document.execCommand("copy");
|
document.execCommand("copy");
|
||||||
alert("Link copied: " + copyText.value);
|
|
||||||
|
// Show copy notification next to the copy button
|
||||||
|
var copyNotification = document.getElementById("copyNotification");
|
||||||
|
copyNotification.classList.remove("hidden");
|
||||||
|
setTimeout(function () {
|
||||||
|
copyNotification.classList.add("hidden");
|
||||||
|
}, 2000);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@if ($responses->isEmpty())
|
<!-- Custom Scripts -->
|
||||||
<p>No responses available.</p>
|
|
||||||
@else
|
|
||||||
<ul>
|
|
||||||
@foreach ($responses as $responseGroup)
|
|
||||||
<li>
|
|
||||||
User: {{ $responseGroup->first()->user->name ?? 'Anonymous' }} - Submitted at: {{ $responseGroup->first()->submitted_at }}
|
|
||||||
<a href="{{ route('responses.viewResponse', ['form' => $form, 'responseId' => $responseGroup->first()->response_id]) }}" target="_blank">View Response</a>
|
|
||||||
</li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
<script src="{{ asset('js/script.js') }}"></script>
|
<script src="{{ asset('js/script.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -21,6 +21,8 @@ Route::middleware(['auth'])->group(function () {
|
||||||
Route::get('/forms/{form}/edit', [FormController::class, 'edit'])->name('forms.edit');
|
Route::get('/forms/{form}/edit', [FormController::class, 'edit'])->name('forms.edit');
|
||||||
Route::put('/forms/{form}', [FormController::class, 'update'])->name('forms.update');
|
Route::put('/forms/{form}', [FormController::class, 'update'])->name('forms.update');
|
||||||
Route::delete('/forms/{form}', [FormController::class, 'destroy'])->name('forms.destroy');
|
Route::delete('/forms/{form}', [FormController::class, 'destroy'])->name('forms.destroy');
|
||||||
|
Route::get('/forms/{form}/preview', [FormController::class, 'preview'])->name('forms.preview');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Response routes
|
// Response routes
|
||||||
|
|
Loading…
Reference in New Issue