Commit 6d7e0fbc authored by ZeMKI's avatar ZeMKI
Browse files

better interview

* modernized layout of interview
* better modals
* homepage including studies where you are invited
parent 43b93c25
......@@ -51,8 +51,13 @@ class HomeController extends Controller
$data['studies'][$key]['authiscreator'] = Auth::user()->is($data['studies'][$key]->creator());
$data['studies'][$key]['editable'] = $data['studies'][$key]->isEditable();
}
ray($data['studies']);
$data['invited_studies'] = auth()->user()->invites;
$data['invited_studies'] = auth()->user()->invites()->with('sortings', 'interviews')->get();
foreach ($data['invited_studies'] as $key => $value) {
$data['invited_studies'][$key]['authiscreator'] = false;
$data['invited_studies'][$key]['editable'] = false;
$data['invited_studies'][$key]['owner'] = $data['invited_studies'][$key]->creator()->email;
}
$data['breadcrumb'] = ['Home'];
if (auth()->user()->profile()->exists()) {
$data['newsletter'] = auth()->user()->profile->newsletter === config('enums.newsletter_status.NOT DECIDED');
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -224,45 +224,6 @@ window.app = new Vue({
},
},
methods: {
confirmLeaveProject: function (userToDetach, study) {
let confirmDelete = this.$buefy.dialog.confirm({
title: this.trans("Confirm Leave"),
message: this.trans(
"Are you sure you want to leave this study?"
),
cancelText: this.trans("No"),
confirmText: this.trans("YES remove me"),
hasIcon: true,
type: "is-danger",
onConfirm: () => this.detachUser(userToDetach, study),
});
},
detachUser: function (userToDetach, study) {
let self = this;
window.axios
.post(
window.location.origin +
self.productionUrl +
"/studies/invite/" +
userToDetach.id,
{
email: userToDetach.email,
study: study,
}
)
.then((response) => {
self.$buefy.snackbar.open(response.data.message);
setTimeout(function () {
window.location.reload();
}, 1000);
})
.catch(function (error) {
self.$buefy.snackbar.open(
"There it was an error during the request - refresh page and try again"
);
});
},
iWantNewsletter(will) {
let subscribed = will === "true";
......
......@@ -44,7 +44,11 @@
</tr>
</thead>
<tbody>
<tr v-for="(interview, index) in interviews" :key="index">
<tr
v-for="(interview, index) in interviews"
:key="index"
class="hover:bg-gray-100"
>
<td class="relative py-4 pl-4 pr-3 text-sm sm:pl-6">
{{ interview.id }}
</td>
......
......@@ -121,7 +121,29 @@
{{ trans("Studies") }}
</h1>
<div class="flex justify-center flex-1">
<div class="w-full px-2 lg:px-6">
<div
v-if="invitesExists"
class="relative flex items-center w-auto mr-4 align-center"
>
<div class="flex items-center h-6">
<input
v-model="onlyInvitation"
id="invites"
aria-describedby="invites-description"
name="invites"
type="checkbox"
class="w-4 h-4 text-blue-500 border-gray-300 rounded focus:ring-blue-500"
/>
</div>
<div class="ml-3 text-sm">
<label
for="invites"
class="font-medium text-gray-700"
>Only Invitations</label
>
</div>
</div>
<div class="w-2/3 px-2 lg:px-6">
<label for="search studies" class="sr-only">{{
trans("Search Studies")
}}</label>
......@@ -151,7 +173,7 @@
name="search studies"
v-model="search"
autocomplete="off"
class="block w-full py-2 pl-10 pr-3 leading-5 text-white placeholder-blue-200 bg-white border border-transparent rounded-md focus:outline-none focus:bg-white focus:ring-0 focus:placeholder-gray-400 focus:text-gray-900 sm:text-sm"
class="block w-full py-2 pl-10 pr-3 leading-5 text-white placeholder-blue-200 bg-white border border-blue-100 rounded-md focus:outline-none focus:bg-white focus:ring-0 focus:placeholder-gray-400 focus:text-gray-900 sm:text-sm"
:placeholder="trans('Search Studies')"
/>
</div>
......@@ -171,15 +193,13 @@
<div class="flex items-center justify-between space-x-4">
<div class="min-w-0 space-y-3">
<div class="flex items-center space-x-3">
<span class="block">
<h2 class="text-xl font-medium">
<span
class="absolute inset-0"
aria-hidden="true"
></span>
{{ study.name }}
</h2>
</span>
<h2 class="text-xl font-medium">
<span
class="absolute inset-0"
aria-hidden="true"
></span>
{{ study.name }}
</h2>
</div>
<span
class="relative group flex items-center space-x-2.5"
......@@ -206,6 +226,19 @@
class="max-w-sm text-sm text-gray-500 lex"
v-html="study.author"
></pre>
<span
v-if="!study.authiscreator"
class="inline-flex items-center px-2.5 py-0.5 rounded-md text-sm font-medium bg-blue-100 text-blue-700"
>
<svg
class="-ml-0.5 mr-1.5 h-2 w-2 text-blue-500"
fill="currentColor"
viewBox="0 0 8 8"
>
<circle cx="4" cy="4" r="3" />
</svg>
{{ trans("Invited By") }} {{ study.owner }}
</span>
</div>
<div
class="flex-col items-end space-y-3 flex-shrink-1 sm:flex"
......@@ -222,7 +255,7 @@
<a
title="manage study"
:href="productionUrl + 'studies/' + study.id"
class="inline-flex items-center justify-center px-4 py-2 text-sm font-medium text-white bg-blue-500 border border-transparent rounded-md shadow-sm cursor-pointer hover:bg-blue-700 hover:text-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 xl:w-full"
class="inline-flex items-center justify-center px-4 py-2 text-sm font-medium text-white bg-blue-500 border border-transparent rounded-md shadow-sm cursor-pointer hover:bg-blue-700 hover:text-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 xl:w-full"
>
{{ trans("Manage Study") }}
</a>
......@@ -233,8 +266,8 @@
'interview/new?study=' +
study.id
"
@click.prevent="setinterviewdname(study.id)"
class="inline-flex items-center justify-center px-4 py-2 text-sm font-medium text-white bg-blue-500 border border-transparent rounded-md shadow-sm cursor-pointer hover:bg-blue-700 hover:text-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 xl:w-full"
@click.prevent="setintervieweename(study.id)"
class="inline-flex items-center justify-center px-4 py-2 text-sm font-medium text-white bg-blue-500 border border-transparent rounded-md shadow-sm cursor-pointer hover:bg-blue-700 hover:text-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 xl:w-full"
>{{ trans("New Interview") }}</a
>
......@@ -242,7 +275,7 @@
type="button"
href="#"
@click="toggleModal(study.id)"
class="inline-flex items-center justify-center px-4 py-2 mt-3 text-sm font-medium text-white bg-blue-500 border border-gray-300 rounded-md shadow-sm hover:bg-blue-700 hover:text-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 xl:ml-0 xl:mt-3 xl:w-full"
class="inline-flex items-center justify-center px-4 py-2 mt-3 text-sm font-medium text-white bg-blue-500 border border-gray-300 rounded-md shadow-sm hover:bg-blue-700 hover:text-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:mt-0 sm:ml-3 xl:ml-0 xl:mt-3 xl:w-full"
>{{ trans("New Public Url") }}</a
>
......@@ -262,8 +295,16 @@
class="inline-flex items-center justify-center px-4 py-2 mt-3 text-sm font-medium text-white bg-blue-500 border border-gray-300 rounded-md shadow-sm hover:bg-blue-700 hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:mt-0 sm:ml-3 xl:ml-0 xl:mt-3 xl:w-full"
>{{ trans("Duplicate Study") }}</a
>
<a
v-if="!study.authiscreator"
type="button"
href="#"
@click="confirmLeaveProject(loggedUser, study.id)"
class="inline-flex items-center justify-center px-4 py-2 mt-3 text-sm font-medium text-white bg-red-500 border border-gray-300 rounded-md shadow-sm hover:bg-red-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:mt-0 sm:ml-3 xl:ml-0 xl:mt-3 xl:w-full"
>{{ trans("Leave Study") }}</a
>
<a
v-if="study.authiscreator"
type="button"
:aria-disabled="!study.editable"
:href="
......@@ -281,56 +322,227 @@
</div>
</li>
</ul>
<div
class="fixed inset-0 z-50 hidden overflow-y-auto newinterviewmodal"
aria-labelledby="modal-title"
role="dialog"
aria-modal="true"
>
<div
class="flex items-end justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0"
>
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div
class="fixed inset-0 hidden transition-opacity bg-gray-500 bg-opacity-75 newinterviewmodal"
aria-hidden="true"
></div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>&#8203;</span
>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
To: "opacity-100 translate-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 translate-y-0 sm:scale-100"
To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
-->
<div
class="relative hidden inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white rounded-lg shadow-xl newinterviewmodal sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6"
>
<div>
<div class="mt-3 text-center sm:mt-5">
<h3
class="text-lg font-medium leading-6 text-gray-900"
id="modal-title"
>
{{ trans("Interviewee Name") }}
</h3>
</div>
</div>
<div>
<label for="name" class="sr-only">Name</label>
<input
v-model="interviewee"
type="name"
name="name"
id="name"
class="block w-full p-2 m-2 border-black rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
placeholder=". . ."
/>
</div>
<div
class="mt-5 sm:mt-6 sm:grid sm:grid-cols-2 sm:gap-3 sm:grid-flow-row-dense"
>
<button
@click.prevent="setintervieweename()"
type="button"
class="inline-flex justify-center w-full px-4 py-2 mt-3 text-base font-medium text-gray-700 bg-white border border-gray-300 rounded-md shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:mt-0"
>
Cancel
</button>
<button
@click="gotoInterview"
type="button"
class="inline-flex justify-center w-full px-4 py-2 mt-3 text-base font-medium text-white bg-blue-500 border border-gray-300 rounded-md shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:mt-0"
>
Start Interview
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["studies"],
props: ["studies", "user"],
computed: {
filteredList() {
return JSON.parse(this.studies).filter((study) => {
return study.name
.toLowerCase()
.includes(this.search.toLowerCase());
if (this.onlyInvitation) {
return (
study.name
.toLowerCase()
.includes(this.search.toLowerCase()) &&
!study.authiscreator
);
} else {
return study.name
.toLowerCase()
.includes(this.search.toLowerCase());
}
});
},
invitesExists() {
return (
_.filter(this.filteredList, (s) => {
return !s.authiscreator;
}).length > 0
);
},
},
data() {
return {
search: "",
loggedUser: JSON.parse(this.user),
interview: {
interviewed: "",
study: "",
url: "",
},
onlyInvitation: false,
interviewee: "",
studyid: 0,
};
},
created() {},
created() {
this.interviewee = "";
this.studyid = 0;
},
methods: {
setinterviewdname: function (studyid) {
confirmLeaveProject: function (userToDetach, study) {
let confirmDelete = this.$buefy.dialog.confirm({
title: this.trans("Confirm Leave"),
message: this.trans(
"Are you sure you want to leave this study?"
),
cancelText: this.trans("No"),
confirmText: this.trans("YES remove me"),
hasIcon: true,
type: "is-danger",
onConfirm: () => this.detachUser(userToDetach, study),
});
},
detachUser: function (userToDetach, study) {
let self = this;
this.$buefy.dialog.prompt({
message: self.trans(`What's the interviewee name?`),
confirmText: self.trans("Start Interview"),
inputAttrs: {
placeholder: "",
maxlength: 20,
required: false,
},
onConfirm: (value) => {
self.interview.interviewed = value;
window.location.href =
"interviews/new?study=" +
studyid +
"&interviewed=" +
value;
},
window.axios
.post(
window.location.origin +
self.productionUrl +
"/studies/invite/" +
userToDetach.id,
{
email: userToDetach.email,
study: study,
}
)
.then((response) => {
self.$buefy.snackbar.open(response.data.message);
setTimeout(function () {
window.location.reload();
}, 1000);
})
.catch(function (error) {
self.$buefy.snackbar.open(
"There it was an error during the request - refresh page and try again"
);
});
},
gotoInterview: function () {
this.interview.interviewed = this.interviewee;
window.location.href =
"interviews/new?study=" +
this.studyid +
"&interviewed=" +
this.interviewee;
},
setintervieweename: function (studyid = 0) {
if (studyid === 0) {
this.interviewee = "";
this.studyid = 0;
this.$forceUpdate();
} else {
this.studyid = studyid;
}
this.studyid = studyid;
let self = this;
let elements = document.querySelectorAll(".newinterviewmodal");
elements.forEach((element) => {
element.classList.toggle("hidden");
});
setTimeout(function () {
let el = document.querySelector(".modal-card input");
document.activeElement.blur();
}, 100);
// this.$buefy.dialog.prompt({
// message: self.trans(`What's the interviewee name?`),
// confirmText: self.trans("Start Interview"),
// inputAttrs: {
// placeholder: "",
// maxlength: 20,
// required: false,
// },
// onConfirm: (value) => {
// self.interview.interviewed = value;
// window.location.href =
// "interviews/new?study=" +
// studyid +
// "&interviewed=" +
// value;
// },
// });
// setTimeout(function () {
// let el = document.querySelector(".modal-card input");
// document.activeElement.blur();
// }, 100);
},
toggleModal(id = "") {
const body = document.querySelector("body");
......
......@@ -57,7 +57,7 @@
id="invitee"
name="invitee"
class="block w-full py-2 pl-10 pr-3 my-2 leading-5 placeholder-gray-500 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-blue-600 focus:border-blue-600 sm:text-sm"
placeholder=""
:placeholder="trans('Enter email and press Enter')"
v-model="toInvite"
autocomplete="off"
@keydown.enter.prevent="invite"
......
......@@ -78,6 +78,12 @@ position: relative;
}
.is-selected{
@apply bg-blue-500;
@apply text-white;
@apply hover:bg-blue-700
}
.radio + .radio {
margin-left: 0em; }
......
......@@ -66,7 +66,7 @@
<!-- Studies List -->
<div class="bg-white lg:min-w-0 lg:flex-1">
@if(count($studies) === 0)
@if(count($studies) === 0 && count($invited_studies) === 0)
<div class="mt-12 text-center">
......@@ -95,7 +95,7 @@
</div>
@else
<studies-list studies="{{$studies}}"></studies-list>
<studies-list studies="{{$studies->merge($invited_studies)}}" user="{{auth()->user()}}"></studies-list>
@endif
</div>
......@@ -103,10 +103,6 @@
</div>
@if(count($invited_studies) > 0)
@include('study.home_invited_studies')
@endif
@endsection
......
......@@ -15,218 +15,210 @@ foreach ($columns as $key => $value)
$columnValues = $baseArray;
?>
<div class="w-2/3 mx-auto">
<h1 class="font-bold text-4xl">{{$study->name}}</h1>
<p class="text-base">
<p class="font-bold inline">{{__('Interview done by')}}:</p> {{$author}}<br>
<p class="font-bold inline">{{__('Interviewed')}}: </p>{{$interview->interviewed}} <br>
<p class="font-bold inline">{{__('From')}}: </p>{{date('d.m.Y H:i:s', strtotime($interview->start))}}
- <p class="font-bold inline">{{__('To')}}: </p>{{date('d.m.Y H:i:s', strtotime($interview->end))}}
</p>
<hr>
<h5 class="text-sm font-bold">
{{$study->description}}
</h5>
<h1 class="font-bold text-4xl uppercase ">{{__('Sorting(s)')}}</h1>
<?php $i = 1 ?>
<div class="block mt-2 w-full h-auto">
<b-tabs type="is-toggle" expanded>
@foreach($screenshots as $screenshot)
<b-tab-item :label="trans('Sorting')+' '+{{$i}}" icon="google-photos"><a href="
{{url('/interview/'.$interview->id.'/sorting/'.$screenshot['type'].'/show')}}"
target="_blank">
<img src="{{$screenshot['image']}}" alt="sorting" class="w-full h-auto"/></a>
</b-tab-item>
<?php $i++; ?>
@endforeach
</b-tabs>
</div>
<div class="w-2/3 mx-auto print:w-full">
<h1 class="text-4xl font-bold">{{$study->name}}</h1>
<h2 class="text-sm font-bold">
{{$study->description}}
</h2>
<p class="text-base">
<p class="inline font-bold">{{__('Interview done by')}}:</p> {{$author}}<br>
<p class="inline font-bold">{{__('Interviewed')}}: </p>{{$interview->interviewed}} <br>
<p class="inline font-bold">{{__('From')}}: </p>{{date('d.m.Y H:i:s', strtotime($interview->start))}}
- <p class="inline font-bold">{{__('To')}}: </p>{{date('d.m.Y H:i:s', strtotime($interview->end))}}
</p>
<hr>
<h1 class="text-4xl font-bold uppercase ">{{__('Sorting(s)')}}</h1>
<?php $i = 1 ?>
<div class="block w-full h-auto mt-2">
<b-tabs type="is-toggle" expanded>
@foreach($screenshots as $screenshot)
<b-tab-item :label="trans('Sorting')+' '+{{$i}}" icon="google-photos"><a
href="
{{url('/interview/'.$interview->id.'/sorting/'.$screenshot['type'].'/show')}}" target="_blank">
<img src="{{$screenshot['image']}}" alt="sorting" class="w-full h-auto" /></a>
</b-tab-item>
<?php $i++; ?>
@endforeach
</b-tabs>
</div>
<h1 class="text-2xl font-bold">{{__('Created Tokens')}}</h1>
<h1 class="text-2xl font-bold">{{__('Created Tokens')}}</h1>
@forelse($createdtokens->unique('id') as $token)
<div class="flex">
<div class="self-center flex-shrink-0 mr-4">
<img src="{{$token->image_path}}" alt="token created" class="block w-10" />
</div>
<div>
<h4 class="text-lg font-bold">{{$token->name}}</h4>
<p class="mt-1">{{__('Created in Sorting')}}
: {{ json_decode($token->pivot->valutation)->sorting}}</p>
</div>
</div>
@forelse($createdtokens->unique('id') as $token)
<div class="block ml-2">
<img src="{{$token->image_path}}" alt="token created" class="block w-10"/>
{{$token->name}} - {{__('Created in Sorting')}}
: {{ json_decode($token->pivot->valutation)->sorting}}
</div>