Construire votre démarrage personnaliser l'affichage de la réunion

Ce que vous allez créer

introduction

Ce tutoriel fait partie de la série Construire votre démarrage avec PHP sur Envato Tuts +. Dans cette série, je vous guide dans le lancement d'une startup du concept à la réalité, en utilisant mon application Meeting Planner comme exemple concret. À chaque étape du processus, je publierai le code de Meeting Planner sous forme d’exemples open source à partir desquels vous pourrez apprendre. Je traiterai également les problèmes liés au démarrage au fur et à mesure qu'ils surviennent.

Pourquoi l'écart dans cette série?

Vous remarquerez peut-être qu'il y a un énorme décalage dans le temps entre le dernier épisode et celui-ci. En avril 2015, on m'a diagnostiqué une tumeur au cerveau nécessitant une intervention chirurgicale et une radiothérapie. Dans l'ensemble, je suis incroyablement chanceux d'avoir de si bons soins, et les choses se sont bien passées - beaucoup de gens n'ont pas accès aux ressources de qualité en neurochirurgie disponibles avec l'assurance maladie dans le nord-ouest du Pacifique. J'écris encore pour Envato Tuts + depuis l'automne dernier, mais c'est amusant de revenir enfin à la série de startups et j'espère que vous l'apprécierez.

Qu'est-ce que cette couverture d'épisode?

Dans ce didacticiel, nous aborderons les fonctionnalités personnalisées nécessaires pour fournir différentes vues en fonction des personnes qui consultent les invitations à des réunions. Avant de commencer à envoyer l'invitation par courrier électronique aux participants, nous devons disposer d'une vue prête à partager avec les fonctionnalités potentiellement restreintes. Pour l’essentiel, nous veillons à ce que la vue de la réunion soit exactement ce qui est nécessaire pour le propriétaire et le participant de la réunion. Suivez le long pour apprendre ce qui est nécessaire.

Tout le code de Meeting Planner est écrit dans le framework Yii2 pour PHP, qui prend en charge I18n de manière intégrée. Si vous souhaitez en savoir plus sur Yii2, consultez notre série parallèle Programmation avec Yii2 chez Envato Tuts+.

Il est intéressant de noter qu'un investisseur providentiel potentiel m'a récemment contacté pour apporter des ressources afin d'accélérer le processus de développement de notre site. Il voit la valeur du concept. Au fur et à mesure que je détermine le chemin à suivre pour continuer, je vous tiendrai au courant. J'espère que cela créera de nouveaux sujets intéressants sur la gestion du processus de placement en tant qu'entrepreneur..

Juste un rappel, je participe aux commentaires ci-dessous. Je suis particulièrement intéressé si vous avez des approches différentes, des idées supplémentaires ou si vous souhaitez suggérer des sujets pour de futurs tutoriels. Vous pouvez également me joindre sur Twitter @reifman.

Exigences d'affichage de réunion

C'est un peu excitant. Meeting Planner va bientôt envoyer des invitations aux participants invités. Cependant, pour supporter cela, nous devons nous assurer que la page de vue de réunion est correctement configurée. Si vous avez créé la réunion, vous disposez de certains pouvoirs, tels que l'invitation de participants, l'ajout de lieux, de dates et d'heures de réunion proposés et le choix des sélections finales. Dans certains cas, l’organisateur peut vouloir offrir tout ou partie de ces pouvoirs aux participants..

Pour l’essentiel, nous devons indiquer à l’application qui visualise la page de la réunion, puis personnaliser l’apparence et les commandes disponibles. Yii facilite la tâche, mais il y a beaucoup de détails impliqués.

Mise en garde concernant l'expérience utilisateur

Et permettez-moi de dire d'emblée, il y a beaucoup de retouches et de polissages d'expérience utilisateur qui devront être effectués de manière itérative au fil du temps vers le produit minimum viable (MVP). La plupart de ce que je suis en train de construire consiste en fonctionnalités de base pour obtenir l'alpha en cours d'utilisation réelle. Je sais que cela semble difficile à certains endroits et ne semblera pas toujours aussi intuitif que vous le souhaitez. Il existe également des inefficacités de codage qui devront être optimisées à l'avenir. N'hésitez pas à poster vos pensées et commentaires ci-dessous et je les prendrai en compte pour les travaux en cours..

La réunion en cours

Voici un aperçu de la vue de réunion existante que le créateur (ou le propriétaire) voit:

le Envoyer Le bouton envoie par courrier électronique l'invitation à la réunion avec les options d'ouverture actuelles au participant pour lui permettre de faire part de ses commentaires. le cases à cocher ci-dessous Vous et Leur permettre au spectateur d’exprimer si le lieu et l’heure lui conviennent. le Choisir les cases à cocher permettent au spectateur de déterminer le lieu final et l'heure finale. le Finaliser bouton met la réunion sur l'horaire avec les options de lieu et d'heure choisies.

Certes, à mesure que le produit mûrit, nous voudrons améliorer l'expérience utilisateur de plusieurs façons et le peaufiner beaucoup, mais voici une poignée d'éléments fonctionnels que nous aimerions modifier pour les participants:

  • le Envoyer le bouton ne sera plus nécessaire une fois l'invitation envoyée par le propriétaire.
  • Les participants peuvent ou non être autorisés à Finaliser options de réunion.
  • Les participants ne pourront pas modifier (icône de crayon) le texte de détail de la réunion.
  • Les participants ne pourront pas ajouter Personnes en ce moment (pour notre MVP).
  • Les participants peuvent ou ne peuvent pas être autorisés à ajouter Des endroits (icône plus).
  • Les participants peuvent ou ne peuvent pas être autorisés à ajouter Dates et heures (icône plus).
  • À la fois Des endroits et Dates et heures panneaux, nous voudrons montrer les choix du spectateur actuel sous la Vous colonne et les données de l'autre personne dans Leur.
  • À la fois Des endroits et Dates et heures panels, les participants peuvent ou non être en mesure de Choisir le final lieu et heure.

Toutes ces options doivent être abordées dans nos travaux actuels. Passons en revue ce qui est nécessaire pour créer ces fonctionnalités.

Mise en œuvre des exigences

Si vous suivez le code, les mises à jour décrites ici sont incluses dans cette version sur GitHub.

Qui est le visualiseur actuel

Le cadre Yii fournit les informations actuelles identifiant d'utilisateur pour le spectateur ici:

$ user_id = Yii :: $ app-> user-> getId ()

Le modèle Meeting a le $ owner_id propriété et Son propriétaire fonction permettant de déterminer si le visualiseur actuel est bien le créateur de la réunion. Sinon, le téléspectateur aura conditionnellement moins de contrôle sur la réunion.. 

J'ai créé quelques fonctions d'assistance dans le modèle de réunion pour accélérer le processus:

fonction publique setViewer () $ this-> viewer_id = Yii :: $ app-> user-> getId (); if ($ this-> owner_id == $ this-> viewer_id) $ this-> viewer = Meeting :: VIEWER_ORGANIZER;  else $ this-> viewer = Meeting :: VIEWER_PARTICIPANT; 

Ceux-ci configurent le $ owner_id et $ spectateur propriétés dans le modèle de réunion.

Bâtiment pour les paramètres de réunion

Chaque réunion que vous créez aura probablement des caractéristiques différentes. Parfois, vous voudrez empêcher le participant de suggérer différents moments et lieux ou de finaliser les détails. D'autres fois, vous ne vous en souciez pas. Lorsque nous finissons par créer des modèles de réunion pour réutiliser les types de réunion courants, par exemple, Pour les réunions d’affaires matinales au café, les modèles devront probablement conserver ce type de paramètres personnalisés. Comment devrions-nous mettre en œuvre cette?

Tout d'abord, je voudrais créer un ensemble de préférences par défaut pour les utilisateurs en ce qui concerne les réunions qu'ils créent.

Ensuite, je vais créer un ensemble de MeetingSettings pour chaque réunion. Lorsqu'une réunion est créée à partir de rien, ils héritent des préférences par défaut de l'utilisateur qui les crée. La modification des paramètres de réunions individuelles peut être différée..

À l'avenir, lorsque nous mettrons en place les modèles de réunion, nous ajouterons également les paramètres de réunion pour les modèles. Cependant, cela peut aussi être reporté.

Voici les préférences que nous aimerions créer pour commencer:

  • Autoriser les participants à ajouter des lieux.
  • Autoriser les participants à ajouter des dates et des heures.
  • Autoriser les participants à choisir des lieux.
  • Autoriser les participants à choisir les dates et heures.
  • Autoriser les participants à finaliser la réunion.

Comme nous revenons tous à la série après un certain temps en raison de mon absence pour raisons de santé, je vais vous donner un peu plus de détails sur certains travaux..

Tout d'abord, nous allons créer la migration des paramètres de réunion:

$ ./yii migrate / create meeting_setting_table Outil de migration Yii (basé sur Yii v2.0.7) Créer une nouvelle migration '/Users/Jeff/Sites/mp/console/migrations/m160401_203412_meeting_setting_table.php'? (oui | non) [non]: oui Nouvelle migration créée avec succès.

Cela crée le fichier de migration dont nous avons besoin pour écrire le code qui construit la table de base de données en fonction de notre schéma:

db-> nomDuPort === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> createTable ('% meeting_setting', ['id' => Schema :: TYPE_PK, 'meeting_id' => Schema :: TYPE_INTEGER. 'NOT NULL', 'participant_add_place' => Schema :: TYPE_SMALLINT. 'NOT NULL DEFAULT 0', 'participant_add_date_time' => Schéma :: TYPE_SMALLINT. 'NOT NULL DEFAULT 0', 'participant_choose_place' => Schéma :: TYPE_SMALLINT. 'NON NULL DEFAUT 0', 'participant_choose_time' => Schéma : TYPE_SMALLINT. 'NOT NULL DEFAULT 0', 'participant_finalize' => Schéma :: TYPE_SMALLINT. 'NOT NULL DEFAULT 0', 'created_at' => Schéma :: TYPE_INTEGER. 'NOT NULL', 'updated_at' => Schéma :: TYPE_INTEGER. 'NOT NULL',], $ tableOptions); $ this-> addForeignKey ('fk_meeting_setting', '% meeting_setting', 'id_reunion', '% meeting', 'id', 'CASCADE', 'CASCADE');  public function down () $ this-> dropForeignKey ('fk_meeting_setting', '% meeting_setting'); $ this-> dropTable ('% meeting_setting');  

Chaque réunion comporte essentiellement une rangée de MeetingSettings avec des propriétés booléennes pour les différentes options de participant que j'ai présentées ci-dessus..

Ensuite, nous demandons à Yii de migrer et de créer la table:

$ ./yii migrate / up Outil de migration Yii (basé sur Yii v2.0.7) Total 1 nouvelle migration à appliquer: m160401_203412_meeting_setting_table Appliquer la migration ci-dessus? (yes | no) [no]: yes *** application de m160401_203412_meeting_setting_table> créer une table % meeting_setting… done (time: 0.010s)> ajouter une clé étrangère fk_meeting_setting: % meeting_setting (meeting_id)  % meeting (id)… fait (heure: 0.011s) *** appliqué m160401_203412_meeting_setting_table (heure: 0.040s) 1 migration a été appliquée. Migré avec succès.

Notre clé étrangère crée une relation entre la table de réunion et la table MeetingSetting.

Ensuite, nous utiliserons Giii de Yii pour générer automatiquement du code permettant d'afficher et de mettre à jour les paramètres. Pour commencer, je retourne à http: // localhost: 8888 / mp / index.php / gii /. Nous allons commencer par générer le modèle:

Ensuite, nous générerons le code Créer, Lire, Mettre à jour, Supprimer (CRUD):

Puisque nous n’avons pas besoin de tout ce code pour le moment, Gii nous permet de sélectionner uniquement les fonctions dont nous avons besoin: manette, vue, _form et mettre à jour:

Gii vous montre une liste des fichiers qu’elle crée à chaque étape:

Mais qu'en est-il des paramètres de réunion par défaut de l'utilisateur? Essentiellement, leurs préférences de réunion typiques?

Extension des préférences de l'utilisateur

Pour cela, nous allons ajouter les propriétés de paramétrage de réunion parallèle à la paramètre d'utilisateur table. Encore une fois, nous allons créer une migration:

$ ./yii migrate / create extend_user_setting_table Outil de migration Yii (basé sur Yii v2.0.7) Créer une nouvelle migration '/Users/Jeff/Sites/mp/console/migrations/m160401_210852_extend_user_setting_table.php'? (oui | non) [non]: oui Nouvelle migration créée avec succès.

Voici les colonnes que nous devons ajouter:

La classe m160401_210852_extend_user_setting_table étend la migration fonction publique up () $ tableOptions = null; if ($ this-> db-> driverName === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> addColumn ('% user_setting', 'participant_add_place', Schema :: TYPE_SMALLINT. 'NOT NULL'); $ this-> addColumn ('% user_setting', 'participant_add_date_time', Schema :: TYPE_SMALLINT. 'NOT NULL'); $ this-> addColumn ('% user_setting', 'participant_choose_place', Schema :: TYPE_SMALLINT. 'NOT NULL'); $ this-> addColumn ('% user_setting', 'participant_choose_date_time', Schema :: TYPE_SMALLINT. 'NOT NULL'); $ this-> addColumn ('% user_setting', 'participant_finalize', Schema :: TYPE_SMALLINT. 'NOT NULL');  public function down () $ this-> dropColumn ('% user_setting', 'participant_finalize'); $ this-> dropColumn ('% user_setting', 'participant_choose_date_time'); $ this-> dropColumn ('% user_setting', 'participant_choose_place'); $ this-> dropColumn ('% user_setting', 'participant_add_date_time'); $ this-> dropColumn ('% user_setting', 'participant_add_place');  

Ensuite, nous lancerons la migration:

$ ./yii migrate / up Yii Outil de migration (basé sur Yii v2.0.7) Total 1 nouvelle migration à appliquer: m160401_210852_extend_user_setting_table Appliquer la migration ci-dessus? (yes | no) [no]: yes *** application de m160401_210852_extend_user_setting_table> ajouter une colonne participant_add_place smallint NON NULL à la table % user_setting… done (heure: 0.012s)> ajouter une colonne participant_add_date_time smallint NON NULL à la table  user_setting… done (time: 0.007s)> ajouter une colonne participant_choose_place smallint NOT NULL à la table % user_setting… done (heure: 0.010s)> ajouter une colonne participant_choose_date_time smallint NOT NULL à la table % user_setting… done (heure: 0.009s)> ajouter une colonne participant_finalize smallint NON NULL à la table % user_setting… done (heure: 0.009s) *** appliqué m160401_210852_extend_user_setting_table (heure: 0.061s) 1 migration a été appliquée. Migré avec succès.

Plutôt que de forcer un écrasement de notre modèle UserSetting.php avec Gii, nous utiliserons celui de Gii. diff option:

Et, à partir de là, nous choisirons les nouveaux ajouts au fichier et les collerons dans:

Fonctionnellement, nous allons ajouter un onglet de paramètres de réunion au Mettre à jour vos paramètres page de propriété:

Nous ajouterons le code suivant à /frontend/views/user-setting/_form.php pour soutenir nos nouvelles propriétés:

champ ($ modèle, 'participant_add_place') -> case à cocher (['décochez' => $ modèle :: SETTING_NO, 'vérifié' => $ modèle :: SETTING_YES]); ?> champ ($ modèle, 'participant_add_date_time') -> case à cocher (['décocher' '=> $ modèle :: SETTING_NO,' vérifié '=> $ modèle :: SETTING_YES]); ?> champ ($ modèle, 'participant_choose_place') -> case à cocher (['décocher' => $ modèle :: SETTING_NO, 'vérifié' => $ modèle :: SETTING_YES]); ?> champ ($ modèle, 'participant_choose_date_time') -> case à cocher (['décocher' => $ modèle :: SETTING_NO, 'vérifié' => $ modèle :: SETTING_YES]); ?> champ ($ modèle, 'participant_finalize') -> case à cocher (['décocher' => $ modèle :: SETTING_NO, 'vérifié' => $ modèle :: SETTING_YES]); ?>

Voici le formulaire mis à jour:

Initialisation de nouvelles sessions de réunion

Chaque fois que l'utilisateur crée une nouvelle réunion, nous devons charger ses paramètres par défaut et les copier dans les paramètres de la réunion.. initializeMeetingSetting est appelé quand une nouvelle réunion est créée pour faire ceci:

 fonction publique initializeMeetingSetting ($ meeting_id, $ owner_id) // charger les paramètres utilisateur du créateur de la réunion (propriétaire) pour initialiser meeting_settings $ user_setting = UserSetting :: find () -> where (['user_id' => $ owner_id]) -> one (); $ meeting_setting = new MeetingSetting (); $ meeting_setting-> meeting_id = $ meeting_id; $ meeting_setting-> participant_add_place = $ user_setting-> participant_add_place; $ meeting_setting-> participant_add_date_time = $ user_setting-> participant_add_date_time; $ meeting_setting-> participant_choose_place = $ user_setting-> participant_choose_place; $ meeting_setting-> participant_choose_date_time = $ user_setting-> participant_choose_date_time; $ meeting_setting-> participant_finalize = $ user_setting-> participant_finalize; $ meeting_setting-> save (); 

Avec les paramètres de réunion en place, nous sommes prêts à passer à l'essentiel du travail d'aujourd'hui, en personnalisant les vues de la réunion pour le propriétaire et le participant..

Examen de la vue du propriétaire de la réunion

Examinons maintenant l'état de notre vue de réunion en fonction du créateur ou du propriétaire de la réunion. Voici une invitation à une réunion que j'ai récemment créée pour inviter mon ami Rob à prendre un verre:

La barre de commande

Avant Envoyer et Finaliser doit être activé, il doit y avoir une personne invitée et au moins un lieu et une heure. S'il y a plus d'un lieu et d'une heure, il faut en choisir une pour que la réunion soit finalisée..

le Annuler (Icône X) et modifier (icône de crayon) les boutons de réunion sont également activés pour les créateurs.

Personnes

Pour le MVP, nous limitons les invitations à des réunions à un seul participant. Ainsi, une fois qu'une personne a été invitée, le Ajouter Le bouton (icône plus) est désactivé. 

Lieux et dates et heures

Le créateur peut ajouter des lieux, des dates et des heures au maximum de notre site (par exemple, sept par réunion) et indiquer leur disponibilité et son acceptation. Et, enfin, quand il y en a plus d'un, ils peuvent choisir quel endroit et quelle heure seront utilisés.

Remarques

Le créateur peut toujours ajouter des notes à la réunion. Les notes permettent au créateur et aux participants de communiquer entre eux.

En fin de compte, nous consacrerons l’essentiel de notre travail à l’amélioration de la fonctionnalité AJAX afin que, lorsque le propriétaire choisit des lieux et des heures, les boutons Envoyer et Finaliser soient correctement activés (ou désactivés dans certains cas)..

Voici un exemple de réunion avec deux heures possibles. le Finaliser Le bouton ne peut pas être activé tant qu’une seule fois n’a pas été choisie:

Une fois le choix effectué, nous aimerions activer le Finaliser bouton via AJAX, épargnant à l'utilisateur un rafraîchissement de la page.

Revoir la vue des participants

Lorsque nous considérons l'invitation du point de vue du participant, la capacité initiale est beaucoup moins grande:

Le participant peut annuler (icône X) sa participation à la réunion et il peut spécifier si les lieux et les heures sont acceptables pour lui, mais il ne peut pas choisir le lieu final. Finaliser la réunion. En outre, les données dans le Vous et Leur les colonnes sont maintenant commutées. Et, le panneau des participants est masqué car il n'est pas nécessaire.

En outre, supposons que la réunion ait été créée avec des paramètres permettant au participant de choisir l'emplacement, la date et l'heure, mais pas de finaliser la réunion. Cela devrait ressembler à ceci:

Puisqu'il n'y a qu'un seul endroit, Café Herkimer, il n'y a pas besoin d'un sélecteur de choix. Mais, là où il y a deux fois possibles, vous pouvez maintenant voir le Choisir sélecteurs. Pourtant, il n'y a pas de bouton Finaliser.

Il s'est avéré que supporter tout cela nécessitait beaucoup de nouveau code pour mettre à jour le système, mais cela commence à plonger au cœur du produit: l'expérience utilisateur des réunions de planification. Je vais vous expliquer quelques changements nécessaires.

Codage des exigences de réunion

Implémentation des paramètres de réunion

Dans les panneaux Heure de la réunion et Lieu de la réunion, nous devons utiliser les paramètres de la réunion pour déterminer si nous devons afficher le sélecteur de choix. Dans la vue _panel.php, cela ressemble à ceci:

 $ timeProvider, 'itemOptions' => ['class' => 'item'], 'layout' => 'items', 'itemView' => '_list', 'viewParams' => ['timeCount' => $ timeProvider-> count, 'isOwner' => $ isOwner, 'participant_choose_date_time' => $ model-> meetingSettings ['participant_choose_date_time']],])?> 
count> 1 && ($ isOwner || $ model-> meetingSettings-> participant_choose_date_time)) echo Yii :: t ('frontend', 'Choose'); ?>

Nous vérifions les paramètres du participant et les transmettons en tant que paramètre à la vue suivante _list.php, qui ressemble à ceci:

 1) if ($ model-> status == $ model :: STATUS_SELECTED) $ value = $ model-> id;  else $ value = 0;  if ($ isOwner || $ participant_choose_date_time) // la valeur doit correspondre pour que switch soit activé echo SwitchInput :: widget (['type' => SwitchInput :: RADIO, 'nom' => 'sélecteur de temps', 'items' => [['value' => $ model-> id],], 'value' => $ value, 'pluginOptions' => ['size' => 'mini', 'handleWidth' => 60 , 'onText' => '',' offText '=>''],' labelOptions '=> [' style '=>' taille de police: 12px '],]); ?> 

Si la vue est le créateur ou si le participant est autorisé à choisir la dernière fois, il verra quelque chose comme ceci, la possibilité de Choisir dans la colonne de droite:

Le spectateur peut-il envoyer et finaliser la réunion

j'ai crée peut envoyer() et canFinalize () fonctions, qui supportent le code en général et les requêtes AJAX pour déterminer l'état actif des boutons Send et Finalize. 

Voici peut envoyer():

fonction publique canSend ($ sender_id) // vérifie si une invitation peut être envoyée // req: un participant, au moins une place, au moins une fois si ($ this-> owner_id == $ sender_id && count ($ this- > participants)> 0 && count ($ this-> meetingPlaces)> 0 && count ($ this-> meetingTimes)> 0) $ this-> isReadyToSend = true;  else $ this-> isReadyToSend = false;  return $ this-> isReadyToSend; 

L'organisateur ne peut pas envoyer l'invitation à la réunion tant qu'il n'y a pas de participant (s), lieux et heures..

Voici canFinalize ():

fonction publique canFinalize ($ user_id) $ this-> isReadyToFinalize = false; // vérifie si le téléspectateur peut finaliser la réunion // vérifie si le propriétaire de la réunion peut être envoyé par le propriétaire si (! $ this-> canSend ($ this-> owner_id)) return false; $ selectedPlace = false; if (nombre ($ this-> meetingPlaces) == 1) $ selectedPlace = true;  else foreach ($ this-> meetingPlaces as $ mp) if ($ mp-> status == MeetingPlace :: STATUS_SELECTED) $ selectedPlace = true; Pause;  $ selectedTime = false; if (count ($ this-> meetingTimes) == 1) $ selectedTime = true;  else foreach ($ this-> meetingTimes en tant que $ mt) if ($ mt-> status == MeetingTime :: STATUS_SELECTED) $ selectedTime = true; Pause;  if ($ this-> owner_id == $ user_id || $ this-> meetingSettings-> participant_finalize) if ($ selectedPlace && $ selectedTime) $ this-> isReadyToFinalize = true;  return $ this-> isReadyToFinalize;  

Cette première vérifie si la réunion peut être envoyée, sinon, elle ne pourra pas être finalisée. Ensuite, il vérifie que le lieu et l’heure ont bien été choisis. Et puis, il vérifie si le spectateur est l'organisateur ou si les paramètres de la réunion permettent à un participant de finaliser la réunion..

En gros, au fur et à mesure que des modifications sont apportées, vous verrez l'état de Envoyer et Finaliser les boutons changent:

Dans la vue view.php de la réunion, j'ai intégré JavaScript pour prendre en charge les mises à jour AJAX dans l'état des boutons Envoyer et Finaliser lorsque les utilisateurs modifient les paramètres de leur réunion. Lorsque des sélections de lieux et d’heures sont effectuées, refreshSend () et refreshFinalize () sont appelés et les boutons sont modifiés de manière appropriée:

params ['urlPrefix'])) $ urlPrefix = Yii :: $ app-> params ['urlPrefix'];  else $ urlPrefix = "; $ script = <<< JS function refreshSend()  $.ajax( url: '$urlPrefix/meeting/cansend', data: id: $model->id, 'viewer_id': $ viewer, succès: function (data) if (data) $ ('# actionSend'). removeClass ("disabled"); else $ ('# actionSend'). addClass ("disabled"); retourne vrai; );  function refreshFinalize () $ .ajax (url: '$ préfixe url / meeting / canfinalize' ', données: id: $ modèle-> id,' id_utilisateur ': $ spectateur, succès: fonction (données) if ( data) $ ('# actionFinalize'). removeClass ("disabled"); sinon $ ('# actionFinalize'). addClass ("disabled"); return true;);  JS; $ position = \ yii \ web \ View :: POS_READY; $ this-> registerJs ($ script, $ position); ?>

Inverser les sélecteurs d'état de lieu et d'heure

Dans l'interface utilisateur actuelle, nous affichons les sélections de lieu et d'heure du spectateur dans la première colonne ou la plus à gauche. Le code doit être personnalisé pour inverser cela lorsque les participants regardent:

Pour prendre en charge l'affichage de différentes données dans les colonnes Vous et Them de la vue de réunion pour les heures et les lieux, les fichiers _list.php et les lieux de réunion devaient être mis à jour pour déterminer de manière dynamique les données à afficher:

     

Pour l'instant, j'ai placé ces fonctions dans la vue _panel.php, qui appelle _list.php, car elles reposent sur l'inclusion du widget SwitchInput dans le contexte:

meetingTimeChoices as $ mtc) if ($ mtc-> id_utilisateur == $ modèle-> meeting-> id_propriétaire) if ($ mtc-> état == $ mtc :: STATUS_YES) $ valeur = 1; sinon $ valeur = 0; echo SwitchInput :: widget (['type' => SwitchInput :: CHECKBOX, 'nom' => 'choix de l'heure de la réunion', 'id' => 'mtc -'. $ mtc-> id, 'valeur' ​​= > $ valeur, 'disabled' =>! $ isOwner, 'pluginOptions' => ['size' => 'mini', 'onText' => '',' offText '=>'',' onColor '=>' success ',' offColor '=>' danger ',],]);  function showTimeParticipantStatus ($ model, $ isOwner) foreach ($ model-> meetingTimeChoices as $ mtc) if (nombre ($ model-> meeting-> participants) == 0) break; if ($ mtc-> user_id == $ modèle-> réunion-> participants [0] -> participant_id) if ($ mtc-> état == $ mtc :: STATUS_YES) $ valeur = 1; else if ($ mtc-> status == $ mtc :: STATUS_NO) $ value = 0; else if ($ mtc-> status == $ mtc :: STATUS_UNKNOWN) $ value = -1; echo SwitchInput :: widget (['type' => SwitchInput :: CHECKBOX, 'nom' => 'choix de l'heure de la réunion', 'id' => 'mtc -'. $ mtc-> id, 'tristate' = > true, 'indeterminateValue' => - 1, 'indeterminateToggle' => false, 'disabled' => $ isOwner, 'value' => $ value, 'pluginOptions' => ['taille' => 'mini', ' onText '=>'',' offText '=>'',' onColor '=>' success ',' offColor '=>' danger ',],]); ?>

Ajustements à venir

En fin de compte, de nombreuses améliorations doivent être apportées à ce code. À certains endroits, je fais des appels AJAX sur le serveur deux ou trois fois, alors que je pouvais les coder plus efficacement en une seule demande. Dans d'autres endroits, je peux faire plus localement avec JavaScript. Et l'interface utilisateur devra continuer à s'améliorer, et le code devra être modifié pour s'adapter à cela. Mais, d’un point de vue fonctionnel, les travaux d’aujourd’hui représentent beaucoup de progrès vers le MVP..

Et après?

Avec les paramètres de réunion et les exigences d'affichage en place pour les organisateurs et les participants, je suis prêt à envoyer la première invitation. Le prochain épisode explorera l'envoi de l'invitation par courrier électronique au participant et l'implémentation de l'apparence du contenu, des liens de commande fonctionnels au sein de l'email et la gestion des autorisations pour les utilisateurs non encore enregistrés. Surveillez les prochains tutoriels dans notre série Construire votre démarrage avec PHP - cela devient passionnant!

N'hésitez pas à ajouter vos questions et commentaires ci-dessous; Je participe généralement aux discussions. Vous pouvez également me joindre sur Twitter @reifman.