From c6376ca479a2c924d8ac0af7ec8b34bf5f65b49b Mon Sep 17 00:00:00 2001 From: Chris Detsch Date: Fri, 13 May 2016 15:28:40 -0400 Subject: [PATCH] Reactified the rlc assignment page. --- class/FakeSoapTable.php | 5 + class/RlcApplicationFactory.php | 15 + class/RlcAssignmentView.php | 111 --- .../command/AjaxDenyRlcApplicationCommand.php | 38 + class/command/AjaxGetCommunitiesCommand.php | 35 + class/command/AjaxGetRLCApplicantsCommand.php | 130 +++ .../command/AjaxGetRLCApplicationCommand.php | 61 ++ class/command/AjaxSetRlcAssignmentCommand.php | 38 + class/command/ExportRlcAppsCommand.php | 24 +- javascript/AssignRlcApplicants/ModalApp.jsx | 104 ++ .../assignRlcApplicants.jsx | 920 ++++++++++++++++++ node_modules/classnames/CONTRIBUTING.md | 21 + node_modules/classnames/HISTORY.md | 81 ++ node_modules/classnames/LICENSE | 21 + node_modules/classnames/README.md | 188 ++++ node_modules/classnames/bind.js | 48 + node_modules/classnames/bower.json | 37 + node_modules/classnames/dedupe.js | 109 +++ node_modules/classnames/index.js | 48 + node_modules/classnames/package.json | 89 ++ package.json | 26 + templates/admin/make_new_rlc_assignments.tpl | 31 +- 22 files changed, 2042 insertions(+), 138 deletions(-) create mode 100644 class/command/AjaxDenyRlcApplicationCommand.php create mode 100644 class/command/AjaxGetCommunitiesCommand.php create mode 100644 class/command/AjaxGetRLCApplicantsCommand.php create mode 100644 class/command/AjaxGetRLCApplicationCommand.php create mode 100644 class/command/AjaxSetRlcAssignmentCommand.php create mode 100644 javascript/AssignRlcApplicants/ModalApp.jsx create mode 100644 javascript/AssignRlcApplicants/assignRlcApplicants.jsx create mode 100644 node_modules/classnames/CONTRIBUTING.md create mode 100644 node_modules/classnames/HISTORY.md create mode 100644 node_modules/classnames/LICENSE create mode 100644 node_modules/classnames/README.md create mode 100644 node_modules/classnames/bind.js create mode 100644 node_modules/classnames/bower.json create mode 100644 node_modules/classnames/dedupe.js create mode 100644 node_modules/classnames/index.js create mode 100644 node_modules/classnames/package.json create mode 100644 package.json diff --git a/class/FakeSoapTable.php b/class/FakeSoapTable.php index ac76c28a..5d24ed6d 100644 --- a/class/FakeSoapTable.php +++ b/class/FakeSoapTable.php @@ -219,4 +219,9 @@ public function getBannerIdByBuildingRoom($building, $room, $term) return null; } + public function addRoomDamageToStudentAccount($bannerId, $term, $amount, $damageDescription) + { + return true; + } + } diff --git a/class/RlcApplicationFactory.php b/class/RlcApplicationFactory.php index f485b925..b52e2c65 100644 --- a/class/RlcApplicationFactory.php +++ b/class/RlcApplicationFactory.php @@ -20,4 +20,19 @@ public static function getApplication(Student $student, $term) return $stmt->fetch(); } + + public static function getApplicationById($id, $term) + { + $db = PdoFactory::getPdoInstance(); + + $query = "SELECT * FROM hms_learning_community_applications where id = :id and term = :term"; + + $stmt = $db->prepare($query); + $stmt->execute(array('id' => $id, + 'term' => $term)); + + $stmt->setFetchMode(PDO::FETCH_CLASS, 'RlcApplicationRestored'); + + return $stmt->fetch(); + } } diff --git a/class/RlcAssignmentView.php b/class/RlcAssignmentView.php index b9c5a363..2cdbe996 100644 --- a/class/RlcAssignmentView.php +++ b/class/RlcAssignmentView.php @@ -35,119 +35,8 @@ public function show() { $tags = array(); $tags['TERM'] = Term::toString(Term::getSelectedTerm()); - $tags['FILTERS'] = $this->getFilters(); - $tags['ASSIGNMENTS_PAGER'] = $this->rlcApplicationPager(); - - $exportForm = new PHPWS_Form('export_form'); - $exportCmd = CommandFactory::getCommand('ExportRlcApps'); - $exportCmd->initForm($exportForm); - - $exportForm->addDropBox('rlc_list', HMS_Learning_Community::getRlcList()); - $exportForm->setClass('rlc_list', 'form-control'); - $exportForm->addSubmit('submit', 'Export'); - $exportForm->setClass('submit', 'btn btn-primary'); - - $exportForm->mergeTemplate($tags); - $tags = $exportForm->getTemplate(); return PHPWS_Template::process($tags, 'hms', 'admin/make_new_rlc_assignments.tpl'); } - /** - * Generates a template for the rlc sort dropdown box - * - * @return string HTML for community selector drop down - */ - public function getFilters() - { - javascript('jquery'); - javascript('modules/hms/page_refresh'); - - // Get the list of communities - $communities = RlcFactory::getRlcList($this->term); - - $communityList = array('0' => 'All'); - - foreach ($communities as $key => $val) { - $communityList[$key] = $val; - } - - // Initialize form and submit command - $submitCmd = CommandFactory::getCommand('ShowAssignRlcApplicants'); - $form = new PHPWS_Form('dropdown_selector'); - $submitCmd->initForm($form); - $form->setMethod('get'); - - - // Community drop down - $form->addSelect('rlc', $communityList); - if (isset($this->rlc) && !is_null($this->rlc)) { - $form->setMatch('rlc', $this->rlc->getId()); - } - $form->setClass('rlc', 'form-control'); - $form->setExtra('rlc', 'onChange="refresh_page(\'dropdown_selector\')"'); - - - // Student Type drop down - $form->addSelect('student_type', array(0 => 'All', TYPE_CONTINUING => 'Continuing', TYPE_FRESHMEN => 'Freshmen')); - if (isset($this->studentType)) { - $form->setMatch('student_type', $this->studentType); - } - $form->setClass('student_type', 'form-control'); - $form->setExtra('student_type', 'onChange="refresh_page(\'dropdown_selector\')"'); - - return PHPWS_Template::process($form->getTemplate(), 'hms', 'admin/rlcApplicationListFilters.tpl'); - } - - /** - * RLC Application pager for the RLC admin panel - * - * @return string HTML for application pager - */ - public function rlcApplicationPager() - { - PHPWS_Core::initCoreClass('DBPager.php'); - - $submitCmd = CommandFactory::getCommand('AssignRlcApplicants'); - $form = new PHPWS_Form; - $submitCmd->initForm($form); - $form->addSubmit('submit', 'Submit Changes'); - $form->setClass('submit', 'btn btn-primary'); - $tags = $form->getTemplate(); - - $pager = new DBPager('hms_learning_community_applications', 'HMS_RLC_Application'); - $pager->db->addColumn('hms_learning_community_applications.*'); - - $pager->db->addJoin('LEFT OUTER', 'hms_learning_community_applications', 'hms_learning_community_assignment', 'id', 'application_id'); - $pager->db->addWhere('hms_learning_community_assignment.application_id', 'NULL', '='); - $pager->db->addWhere('term', $this->term); - $pager->db->addWhere('denied', 0); // Only show non-denied applications in this pager - // If community filter is set, use it - if (isset($this->rlc)) { - $pager->db->addWhere('hms_learning_community_applications.rlc_first_choice_id', $this->rlc->getId(), '='); - } - - // If student type filter is set, use it - if (isset($this->studentType)) { - if ($this->studentType == TYPE_FRESHMEN) { - $pager->db->addWhere('hms_learning_community_applications.application_type', 'freshmen'); - } else if ($this->studentType == TYPE_CONTINUING) { - // TODO fix this so 'returning' is consistent with 'continuing'.. really just use student types - $pager->db->addWhere('hms_learning_community_applications.application_type', 'returning'); - } - } - - $pager->setModule('hms'); - $pager->setLink('index.php?module=hms&action=SubmitRlcAssignments'); - $pager->setTemplate('admin/rlc_assignments_pager.tpl'); - $pager->setEmptyMessage("No pending RLC applications."); - $pager->addPageTags($tags); - $pager->addRowTags('getAdminPagerTags'); - $pager->setReportRow('applicantsReport'); - - Layout::addPageTitle("RLC Assignments"); - - return $pager->get(); - } - } diff --git a/class/command/AjaxDenyRlcApplicationCommand.php b/class/command/AjaxDenyRlcApplicationCommand.php new file mode 100644 index 00000000..a858a10a --- /dev/null +++ b/class/command/AjaxDenyRlcApplicationCommand.php @@ -0,0 +1,38 @@ +applicationId = $id; + } + + public function getRequestVars(){ + return array('action'=>'AjaxDenyRlcApplication', 'applicationId'=>$this->applicationId); + } + + public function execute(CommandContext $context) + { + if(!Current_User::allow('hms', 'approve_rlc_applications')){ + echo json_encode(array('success' => false, + 'message' => 'You do not have permission to approve/deny RLC applications.' + )); + exit; + } + + PHPWS_Core::initModClass('hms', 'HMS_RLC_Application.php'); + + $app = HMS_RLC_Application::getApplicationById($context->get('applicationId')); + $app->denied = 1; + $app->save(); + + PHPWS_Core::initModClass('hms', 'HMS_Activity_Log.php'); + HMS_Activity_Log::log_activity($app->username, 28, Current_User::getUsername(), 'Application Denied'); + + echo json_encode(array('success' => true, + 'message' => 'Successfully denied application' + )); + exit; + } +} diff --git a/class/command/AjaxGetCommunitiesCommand.php b/class/command/AjaxGetCommunitiesCommand.php new file mode 100644 index 00000000..bc0a9a60 --- /dev/null +++ b/class/command/AjaxGetCommunitiesCommand.php @@ -0,0 +1,35 @@ +'AjaxGetCommunities'); + } + + public function execute(CommandContext $context) + { + PHPWS_Core::initModClass('hms', 'HMS_Learning_Community.php'); + + $term = Term::getSelectedTerm(); + + $communities = RlcFactory::getRlcList($term); + + $keys = array_keys($communities); + + $communityNodes = array(); + + + foreach($keys as $cId) + { + $communityName = $communities[$cId]; + $node = array('cId' => $cId, + 'cName' => $communityName); + $communityNodes[] = $node; + } + + echo json_encode($communityNodes); + exit; + } +} diff --git a/class/command/AjaxGetRLCApplicantsCommand.php b/class/command/AjaxGetRLCApplicantsCommand.php new file mode 100644 index 00000000..188ebc69 --- /dev/null +++ b/class/command/AjaxGetRLCApplicantsCommand.php @@ -0,0 +1,130 @@ +'AjaxGetRLCApplicants'); + } + + public function execute(CommandContext $context) + { + $studentTypeFilter = $context->get('studentTypeFilter'); + $communityFilter = $context->get('communityFilter'); + $firstChoice = filter_var($context->get('firstChoice'), FILTER_VALIDATE_BOOLEAN); + $secondChoice = filter_var($context->get('secondChoice'), FILTER_VALIDATE_BOOLEAN); + $thirdChoice = filter_var($context->get('thirdChoice'), FILTER_VALIDATE_BOOLEAN); + $term = Term::getSelectedTerm(); + + $db = PdoFactory::getPdoInstance(); + + $query = "SELECT hms_learning_community_applications.id, + hms_learning_community_applications.username, + hms_learning_community_applications.date_submitted, + hms_learning_community_applications.rlc_first_choice_id, + hms_learning_community_applications.rlc_second_choice_id, + hms_learning_community_applications.rlc_third_choice_id + FROM hms_learning_community_applications + LEFT OUTER JOIN hms_learning_community_assignment + ON hms_learning_community_applications.id = hms_learning_community_assignment.application_id + WHERE hms_learning_community_assignment.application_id IS NULL + AND hms_learning_community_applications.term = :term + AND hms_learning_community_applications.denied = 0"; + + $params = array('term' => $term); + + if($communityFilter != 0) + { + $query .= " AND ("; + + if($firstChoice) // Default to first choice + { + $query .= "hms_learning_community_applications.rlc_first_choice_id = :rlc"; + if($secondChoice || $thirdChoice) + { + $query .= " OR "; + } + } + if($secondChoice) + { + + $query .= "hms_learning_community_applications.rlc_second_choice_id = :rlc"; + if($thirdChoice) + { + $query .= " OR "; + } + } + if($thirdChoice) + { + $query .= "hms_learning_community_applications.rlc_third_choice_id = :rlc"; + } + + if(!($firstChoice || $secondChoice || $thirdChoice)) + { + $query .= "hms_learning_community_applications.rlc_first_choice_id = :rlc + OR hms_learning_community_applications.rlc_second_choice_id = :rlc + OR hms_learning_community_applications.rlc_third_choice_id = :rlc"; + } + + $query .= ")"; + + $params['rlc'] = $communityFilter; + } + + if($studentTypeFilter != '0') + { + if ($studentTypeFilter == TYPE_FRESHMEN) { + $params['sType'] = "freshmen"; + } else if ($studentTypeFilter == TYPE_CONTINUING) { + $params['sType'] = "returning"; + } + + $query .= " AND hms_learning_community_applications.application_type = :sType"; + } + + + $stmt = $db->prepare($query); + $stmt->execute($params); + + $results = $stmt->fetchAll(PDO::FETCH_ASSOC); + + $output = array(); + $communities = RlcFactory::getRlcList($term); + + foreach ($results as $applicant) + { + $node = array(); + $student = StudentFactory::getStudentByUsername($applicant['username'], $term); + $node['app_id'] = $applicant['id']; + $node['first_name'] = $student->getFirstName(); + $node['last_name'] = $student->getLastName(); + $node['name'] = $student->getName(); + $node['bannerId'] = $student->getBannerId(); + $node['first_choice'] = $communities[$applicant['rlc_first_choice_id']]; + if(isset($applicant['rlc_second_choice_id'])) + { + $node['second_choice'] = $communities[$applicant['rlc_second_choice_id']]; + if(isset($applicant['rlc_third_choice_id'])) + { + $node['third_choice'] = $communities[$applicant['rlc_third_choice_id']]; + } + } + $node['gender'] = $student->getGender() ? 'Male':'Female'; + $node['app_date'] = date('d-M-y', $applicant['date_submitted']); + $node['unix_date'] = $applicant['date_submitted']; + $output[] = $node; + } + + echo json_encode($output); + exit; + } +} diff --git a/class/command/AjaxGetRLCApplicationCommand.php b/class/command/AjaxGetRLCApplicationCommand.php new file mode 100644 index 00000000..64e137ac --- /dev/null +++ b/class/command/AjaxGetRLCApplicationCommand.php @@ -0,0 +1,61 @@ +'AjaxGetRLCApplication'); + } + + public function execute(CommandContext $context) + { + $applicationId = $context->get('applicationId'); + $term = Term::getSelectedTerm(); + + $application = HMS_RLC_Application::getApplicationById($applicationId, $term); + + + $output = array(); + + $student = StudentFactory::getStudentByUsername($application->getUsername(), $term); + + $firstChoice = RlcFactory::getRlcById($application->getFirstChoice()); + if($application->getSecondChoice() != null) + { + $secondChoice = RlcFactory::getRlcById($application->getSecondChoice()); + if($application->getThirdChoice() != null) + { + $thirdChoice = RlcFactory::getRlcById($application->getThirdChoice()); + } + } + + $output['name'] = $student->getName(); + $node['app_date'] = date('d-M-y', $application->getDateSubmitted()); + $output['specificCommQuestion'] = $application->getWhySpecificCommunities(); + $output['strenthsWeaknesses'] = $application->getStrengthsWeaknesses(); + $output['firstChoice'] = $firstChoice->getName(); + $output['firstChoiceAnswer'] = $application->getRLCQuestion0(); + if($application->getSecondChoice() != null) + { + $output['secondChoice'] = $secondChoice->getName(); + $output['secondChoiceAnswer'] = $application->getRLCQuestion1(); + if($application->getThirdChoice() != null) + { + $output['thirdChoice'] = $thirdChoice->getName(); + $output['thirdChoiceAnswer'] = $application->getRLCQuestion2(); + } + } + + echo json_encode($output); + exit; + } +} diff --git a/class/command/AjaxSetRlcAssignmentCommand.php b/class/command/AjaxSetRlcAssignmentCommand.php new file mode 100644 index 00000000..bca4b030 --- /dev/null +++ b/class/command/AjaxSetRlcAssignmentCommand.php @@ -0,0 +1,38 @@ +'AjaxSetRlcAssignment'); + } + + public function execute(CommandContext $context) + { + if(!Current_User::allow('hms', 'approve_rlc_applications')){ + echo json_encode(array('success' => false, + 'message' => 'You do not have permission to approve/deny RLC applications.' + )); + exit; + } + + PHPWS_Core::initModClass('hms', 'HMS_RLC_Application.php'); + + $app = HMS_RLC_Application::getApplicationById($context->get('applicationId')); + $student = StudentFactory::getStudentByUsername($app->username, $app->term); + + $assign = new HMS_RLC_Assignment(); + $assign->rlc_id = $context->get('rlcId'); + $assign->gender = $student->getGender(); + $assign->assigned_by = UserStatus::getUsername(); + $assign->application_id = $app->id; + $assign->state = 'new'; + $assign->save(); + + PHPWS_Core::initModClass('hms', 'HMS_Activity_Log.php'); + HMS_Activity_Log::log_activity($app->username, 28, Current_User::getUsername(), 'Application Denied'); + + echo json_encode(array("success" => true, + 'message' => 'Successfully assigned student' + )); + exit; + } +} diff --git a/class/command/ExportRlcAppsCommand.php b/class/command/ExportRlcAppsCommand.php index d96200cd..3aee3d82 100644 --- a/class/command/ExportRlcAppsCommand.php +++ b/class/command/ExportRlcAppsCommand.php @@ -2,11 +2,11 @@ class ExportRlcAppsCommand extends Command { - + public function getRequestVars(){ return array('action'=>'ExportRlcApps'); } - + // TODO: rewrite this public function execute(CommandContext $context) { @@ -19,14 +19,17 @@ public function execute(CommandContext $context) $db = new PHPWS_DB('hms_learning_communities'); $db->addColumn('community_name'); - $db->addWhere('id',$_REQUEST['rlc_list']); + if($context->get('communityId')!= 0) + { + $db->addWhere('id',$context->get('communityId')); + } $title = $db->select('one'); $filename = $title . '-applications-' . date('Ymd') . ".csv"; // setup the title and headings $buffer = $title . "\n"; - $buffer .= '"last_name","first_name","middle_name","gender","roommate","email","second_choice","third_choice","major","application_date","denied"' . "\n"; + $buffer .= '"Last name","First Name","Middle Name","Gender","Roommate","Email","Second Choice","Third Choice","Major","Application Date","Denied"' . "\n"; // get the userlist $db = new PHPWS_DB('hms_learning_community_applications'); @@ -34,7 +37,10 @@ public function execute(CommandContext $context) $db->addColumn('rlc_second_choice_id'); $db->addColumn('rlc_third_choice_id'); $db->addColumn('date_submitted'); - $db->addWhere('rlc_first_choice_id', $_REQUEST['rlc_list']); + if($context->get('communityId')!= 0) + { + $db->addWhere('rlc_first_choice_id', $context->get('communityId')); + } $db->addWhere('term', Term::getSelectedTerm()); $db->addOrder('denied asc'); //$db->addWhere('denied', 0); // Only show non-denied applications @@ -51,12 +57,12 @@ public function execute(CommandContext $context) } $student = StudentFactory::getStudentByUsername($user['username'], Term::getSelectedTerm()); - + $buffer .= '"' . $student->getLastName() . '",'; $buffer .= '"' . $student->getFirstName() . '",'; $buffer .= '"' . $student->getMiddleName() . '",'; $buffer .= '"' . $student->getPrintableGender() . '",'; - + if($roomie != NULL) { $buffer .= '"' . $roomie->getFullName() . '",'; } else { @@ -106,7 +112,7 @@ public function execute(CommandContext $context) //HERES THE QUERY: //select hms_learning_community_applications.user_id, date_submitted, rlc_first_choice.abbreviation as first_choice, rlc_second_choice.abbreviation as second_choice, rlc_third_choice.abbreviation as third_choice FROM (SELECT hms_learning_community_applications.user_id, hms_learning_communities.abbreviation FROM hms_learning_communities,hms_learning_community_applications WHERE hms_learning_communities.id = hms_learning_community_applications.rlc_first_choice_id) as rlc_first_choice, (SELECT hms_learning_community_applications.user_id, hms_learning_communities.abbreviation FROM hms_learning_communities,hms_learning_community_applications WHERE hms_learning_communities.id = hms_learning_community_applications.rlc_second_choice_id) as rlc_second_choice, (SELECT hms_learning_community_applications.user_id, hms_learning_communities.abbreviation FROM hms_learning_communities,hms_learning_community_applications WHERE hms_learning_communities.id = hms_learning_community_applications.rlc_third_choice_id) as rlc_third_choice, hms_learning_community_applications WHERE rlc_first_choice.user_id = hms_learning_community_applications.user_id AND rlc_second_choice.user_id = hms_learning_community_applications.user_id AND rlc_third_choice.user_id = hms_learning_community_applications.user_id; - + //Download file if(ob_get_contents()) print('Some data has already been output, can\'t send file'); @@ -122,5 +128,3 @@ public function execute(CommandContext $context) die(); } } - - diff --git a/javascript/AssignRlcApplicants/ModalApp.jsx b/javascript/AssignRlcApplicants/ModalApp.jsx new file mode 100644 index 00000000..68a0ccad --- /dev/null +++ b/javascript/AssignRlcApplicants/ModalApp.jsx @@ -0,0 +1,104 @@ +/** + IMPORTANT! + ****************************** + * The following component * + * uses ReactBootstrap * + ****************************** +**/ +var Modal = ReactBootstrap.Modal; +var Button = ReactBootstrap.Button; + + +var ModalApp = React.createClass({ + getInitialState: function() { + return { + appData: [] + }; + }, + componentWillMount: function() + { + this.getAppData(); + }, + getAppData: function() + { + var inputData = {applicationId: this.props.appId}; + + $.ajax({ + url: 'index.php?module=hms&action=AjaxGetRLCApplication', + type: 'POST', + dataType: 'json', + data: inputData, + success: function(data) + { + this.setState({appData: data}); + }.bind(this), + error: function(xhr, status, err) + { + + }.bind(this) + }); + }, + render: function() + { + var secondChoiceListItem = (
); + var secondChoice = (
); + var thirdChoiceListItem = (
); + var thirdChoice = (
); + + if(this.state.appData.secondChoice != undefined) + { + secondChoice = (
+ +

{this.state.appData.secondChoiceAnswer}

+
); + secondChoiceListItem = (
  • {this.state.appData.secondChoice}
  • ) + } + if(this.state.appData.secondChoice != undefined) + { + thirdChoice = (
    + +

    {this.state.appData.thirdChoiceAnswer}

    +
    ); + thirdChoiceListItem = (
  • {this.state.appData.thirdChoice}
  • ) + } + + return ( +
    + + + {this.state.appData.name}'s Application + + +
    + +
      +
    1. {this.state.appData.firstChoice}
    2. + {secondChoiceListItem} + +
    +
    +
    + +

    {this.state.appData.specificCommQuestion}

    +
    +
    + +

    {this.state.appData.strenthsWeaknesses}

    +
    +
    + +

    {this.state.appData.firstChoiceAnswer}

    +
    + {secondChoice} + + +
    + + + + +
    +
    + ); + } +}); diff --git a/javascript/AssignRlcApplicants/assignRlcApplicants.jsx b/javascript/AssignRlcApplicants/assignRlcApplicants.jsx new file mode 100644 index 00000000..87c2a4ed --- /dev/null +++ b/javascript/AssignRlcApplicants/assignRlcApplicants.jsx @@ -0,0 +1,920 @@ + +var RlcApplicantsBox = React.createClass({ + getInitialState: function() + { + return {communities : [], + communityFilter : 0, + studentTypeFilter : '0', + firstChoice : true, + secondChoice : true, + thirdChoice : true, + response : undefined, + showModal : false, + modalAppId : -1 + }; + }, + componentWillMount: function() + { + this.getCommunities(); + }, + getCommunities: function() + { + $.ajax({ + url: 'index.php?module=hms&action=AjaxGetCommunities', + type: 'GET', + dataType: 'json', + success: function(data) + { + this.setState({communities: data}); + }.bind(this), + error: function(xhr, status, err) + { + + }.bind(this) + }); + }, + changeCFilter: function(newFilter) + { + this.setState({communityFilter: newFilter}); + }, + changeSTFilter: function(newFilter) + { + console.log(newFilter) + this.setState({studentTypeFilter: newFilter}); + }, + toggleChoice: function(choice) + { + if(choice == 'first') + { + this.setState({firstChoice: !this.state.firstChoice}) + } + else if(choice == 'second') + { + this.setState({secondChoice: !this.state.secondChoice}) + } + else if(choice == 'third') + { + this.setState({thirdChoice: !this.state.thirdChoice}) + } + }, + showModal: function(app_id) + { + this.setState({showModal : true, + modalAppId : app_id}); + }, + closeModal: function() + { + this.setState({showModal : false}); + }, + render: function() + { + var choiceToggles = (
    ); + var modalApp = (
    ); + + console.log(this.state.showModal) + var thisTerm = term; + if(this.state.communityFilter != 0) + { + choiceToggles = ( + ); + } + if(this.state.showModal) + { + modalApp = (); + } + + + return( +
    + {modalApp} +
    + +
    +

    RLC Assignments - {thisTerm}

    +

    Applicants

    +
    +
    + +
    +
    + +
    +
    +
    + {choiceToggles} +
    +
    +
    + +
    +
    + +
    +
    + ); + } +}); + +var NotificationBox = React.createClass({ + render: function() + { + if(this.props.response == undefined) + { + return (
    ); + } + var error = !this.props.response.success; + var success = this.props.response.success; + var message = this.props.response.message; + + var notificationClasses = classNames({ + 'alert' : true, + 'alert-danger' : error, + 'alert-success' : success + }) + return ( +
    + {message} +
    + ); + } +}); + +var CommunityFilter = React.createClass({ + changeFilter: function() + { + var newFilter = this.refs.communityFilter.getDOMNode().value; + this.props.changeCFilter(newFilter); + }, + render: function() + { + var communities = this.props.communities; + var data = Array({cId: 0, cName: 'All'}); + var i = 0; + for(i; i < communities.length; i++) + { + data.push(communities[i]); + } + + var communityOptions = data.map(function(node){ + return( + + ); + }); + return( +
    + + +
    + ); + } +}); + +var StudentTypeFilter = React.createClass({ + changeFilter: function() + { + var newFilter = this.refs.studentTypeFilter.getDOMNode().value; + this.props.changeSTFilter(newFilter); + }, + render: function() + { + return( +
    + + +
    + ); + } +}); + +var ChoiceFilter = React.createClass({ + firstToggle: function() + { + this.props.toggleChoice('first'); + }, + secondToggle: function() + { + this.props.toggleChoice('second'); + }, + thirdToggle: function() + { + this.props.toggleChoice('third'); + }, + render: function() + { + var first = this.props.firstChoice; + var second = this.props.secondChoice; + var third = this.props.thirdChoice; + + // Set the list toggle class via classNames + var firstClasses = classNames({ + 'btn' : true, + 'btn-default' : true, + 'active' : first + }); + + // Set the add toggle class via classNames + var secondClasses = classNames({ + 'btn' : true, + 'btn-default' : true, + 'active' : second + }); + + // Set the remove toggle class via classNames + var thirdClasses = classNames({ + 'btn' : true, + 'btn-default' : true, + 'active' : third + }); + + return( +
    + +
    +
    + + + +
    +
    +
    + ); + } +}) + +var ApplicantsTable = React.createClass({ + getInitialState: function() + { + return {applicants: [], currentSort: '', sortDirection: ''}; + }, + componentWillMount: function() + { + this.getApplicants(this.props); + }, + componentWillReceiveProps: function(nextProps) + { + this.getApplicants(nextProps); + }, + denyApplicant: function(appId) + { + $.ajax({ + url: 'index.php?module=hms&action=AjaxDenyRlcApplication&applicationId=' + appId, + type: 'POST', + success: function() + { + this.getApplicants(this.props); + }.bind(this), + error: function(xhr, status, err) + { + + }.bind(this) + }); + }, + + // The ajax request gets different props based on whether it is initial mount or + // if the props are changing, if they are changing then this.props returns the old props + // so it needs to be passed as a param from the componentWillReceiveProps function which + // has access to the new props. + getApplicants: function(props) + { + var inputData = {communityFilter : props.communityFilter, + studentTypeFilter : props.studentTypeFilter, + firstChoice : props.firstChoice, + secondChoice : props.secondChoice, + thirdChoice : props.thirdChoice + }; + + $.ajax({ + url: 'index.php?module=hms&action=AjaxGetRLCApplicants', + type: 'POST', + dataType: 'json', + data: inputData, + success: function(data) + { + this.setState({applicants: data}); + }.bind(this), + error: function(xhr, status, err) + { + + }.bind(this) + }); + }, + nameSort: function() + { + var applicantsArr = this.state.applicants; + var currentSort = this.state.currentSort; + var sortDirection = this.state.sortDirection; + var newSortDirection = ''; + + if (sortDirection == 'DESCENDING' || currentSort != 'names') + { + applicantsArr.sort(function(a, b) + { + var lastNameA = a.last_name.toLowerCase(); + var lastNameB = b.last_name.toLowerCase(); + if (lastNameA < lastNameB) + { //sort string ascending + return -1; + } + else if (lastNameA > lastNameB) + { + return 1; + } + else { + var firstNameA = a.first_name.toLowerCase(); + var firstNameB = b.first_name.toLowerCase(); + if(firstNameA < firstNameB) + { + return -1; + } + else if(firstNameA > firstNameB) + { + return 1; + } + else + { + return 0; + } + } + }); + + newSortDirection = 'ASCENDING'; + } + else + { + applicantsArr.sort(function(a, b) + { + var lastNameA = a.last_name.toLowerCase(); + var lastNameB = b.last_name.toLowerCase(); + if (lastNameA > lastNameB) + { //sort string descending + return -1; + } + else if (lastNameA < lastNameB) + { + return 1; + } + else { + var firstNameA = a.first_name.toLowerCase(); + var firstNameB = b.first_name.toLowerCase(); + if(firstNameA > firstNameB) + { + return -1; + } + else if(firstNameA < firstNameB) + { + return 1; + } + else + { + return 0; + } + } + }); + newSortDirection = 'DESCENDING'; + } + + this.setState({applicants: applicantsArr, currentSort: 'names', sortDirection: newSortDirection}); + }, + firstChoiceSort: function() + { + var applicantsArr = this.state.applicants; + var currentSort = this.state.currentSort; + var sortDirection = this.state.sortDirection; + var newSortDirection = ''; + + if (sortDirection == 'DESCENDING' || currentSort != 'firstChoice') + { + applicantsArr.sort(function(a, b) + { + var firstChoiceA = a.first_choice.toLowerCase(); + var firstChoiceB = b.first_choice.toLowerCase(); + if (firstChoiceA < firstChoiceB) + { //sort string ascending + return -1; + } + else if (firstChoiceA > firstChoiceB) + { + return 1; + } + else { + return 0; + } + }); + + newSortDirection = 'ASCENDING'; + } + else + { + applicantsArr.sort(function(a, b) + { + var firstChoiceA = a.first_choice.toLowerCase(); + var firstChoiceB = b.first_choice.toLowerCase(); + if (firstChoiceA > firstChoiceB) + { //sort string descending + return -1; + } + else if (firstChoiceA < firstChoiceB) + { + return 1; + } + else { + return 0; + } + }); + newSortDirection = 'DESCENDING'; + } + + this.setState({applicants: applicantsArr, currentSort: 'firstChoice', sortDirection: newSortDirection}); + }, + secondChoiceSort: function() + { + var applicantsArr = this.state.applicants; + var currentSort = this.state.currentSort; + var sortDirection = this.state.sortDirection; + var newSortDirection = ''; + + if (sortDirection == 'DESCENDING' || currentSort != 'secondChoice') + { + applicantsArr.sort(function(a, b) + { + var secondChoiceA = a.second_choice.toLowerCase(); + var secondChoiceB = b.second_choice.toLowerCase(); + if (secondChoiceA < secondChoiceB) + { //sort string ascending + return -1; + } + else if (secondChoiceA > secondChoiceB) + { + return 1; + } + else { + return 0; + } + }); + + newSortDirection = 'ASCENDING'; + } + else + { + applicantsArr.sort(function(a, b) + { + var secondChoiceA = a.second_choice.toLowerCase(); + var secondChoiceB = b.second_choice.toLowerCase(); + if (secondChoiceA > secondChoiceB) + { //sort string descending + return -1; + } + else if (secondChoiceA < secondChoiceB) + { + return 1; + } + else { + return 0; + } + }); + newSortDirection = 'DESCENDING'; + } + + this.setState({applicants: applicantsArr, currentSort: 'secondChoice', sortDirection: newSortDirection}); + }, + thirdChoiceSort: function() + { + var applicantsArr = this.state.applicants; + var currentSort = this.state.currentSort; + var sortDirection = this.state.sortDirection; + var newSortDirection = ''; + + if (sortDirection == 'DESCENDING' || currentSort != 'thirdChoice') + { + applicantsArr.sort(function(a, b) + { + var thirdChoiceA = a.third_choice.toLowerCase(); + var thirdChoiceB = b.third_choice.toLowerCase(); + if (thirdChoiceA < thirdChoiceB) + { //sort string ascending + return -1; + } + else if (thirdChoiceA > thirdChoiceB) + { + return 1; + } + else { + return 0; + } + }); + + newSortDirection = 'ASCENDING'; + } + else + { + applicantsArr.sort(function(a, b) + { + var thirdChoiceA = a.third_choice.toLowerCase(); + var thirdChoiceB = b.third_choice.toLowerCase(); + if (thirdChoiceA > thirdChoiceB) + { //sort string descending + return -1; + } + else if (thirdChoiceA < thirdChoiceB) + { + return 1; + } + else { + return 0; + } + }); + newSortDirection = 'DESCENDING'; + } + + this.setState({applicants: applicantsArr, currentSort: 'thirdChoice', sortDirection: newSortDirection}); + }, + genderSort: function() + { + var applicantsArr = this.state.applicants; + var currentSort = this.state.currentSort; + var sortDirection = this.state.sortDirection; + var newSortDirection = ''; + + if (sortDirection == 'DESCENDING' || currentSort != 'gender') + { + applicantsArr.sort(function(a, b) + { + var genderA = a.gender.toLowerCase(); + var genderB = b.gender.toLowerCase(); + if (genderA < genderB) + { //sort string ascending + return -1; + } + else if (genderA > genderB) + { + return 1; + } + else { + return 0; + } + }); + + newSortDirection = 'ASCENDING'; + } + else + { + applicantsArr.sort(function(a, b) + { + var genderA = a.gender.toLowerCase(); + var genderB = b.gender.toLowerCase(); + if (genderA > genderB) + { //sort string descending + return -1; + } + else if (genderA < genderB) + { + return 1; + } + else { + return 0; + } + }); + newSortDirection = 'DESCENDING'; + } + + this.setState({applicants: applicantsArr, currentSort: 'gender', sortDirection: newSortDirection}); + }, + appDateSort: function() + { + + var applicantsArr = this.state.applicants; + var currentSort = this.state.currentSort; + var sortDirection = this.state.sortDirection; + var newSortDirection = ''; + + + if (sortDirection == 'DESCENDING' || currentSort != 'appDate') + { + applicantsArr.sort(function(a, b){ + var dateA = new Date(a.unix_date); + var dateB = new Date(b.unix_date); + return dateA - dateB; //sort by date ascending + }); + + newSortDirection = 'ASCENDING'; + } + else + { + applicantsArr.sort(function(a, b){ + var dateA = new Date(a.unix_date); + var dateB = new Date(b.unix_date); + return dateB - dateA; //sort by date descending + }); + newSortDirection = 'DESCENDING'; + } + + this.setState({applicants: applicantsArr, currentSort: 'appDate', sortDirection: newSortDirection}); + }, + render: function() + { + var data = this.state.applicants; + + console.log(data) + + if(data.length == 0) + { + return (

    No applicants found using the current filters.

    ) + } + + var rlcs = this.props.communities; + var applicantRows = data.map(function(node){ + return ( + + ); + }.bind(this)); + + var nameSortLink = (); + if(this.state.currentSort == 'names') + { + if(this.state.sortDirection == 'ASCENDING') + { + var nameSortLink = (); + } + else if(this.state.sortDirection == 'DESCENDING') + { + var nameSortLink = (); + } + } + + var firstChoiceSortLink = (); + if(this.state.currentSort == 'firstChoice') + { + if(this.state.sortDirection == 'ASCENDING') + { + var firstChoiceSortLink = (); + } + else if(this.state.sortDirection == 'DESCENDING') + { + var firstChoiceSortLink = (); + } + } + + var secondChoiceSortLink = (); + if(this.state.currentSort == 'secondChoice') + { + if(this.state.sortDirection == 'ASCENDING') + { + var secondChoiceSortLink = (); + } + else if(this.state.sortDirection == 'DESCENDING') + { + var secondChoiceSortLink = (); + } + } + + var thirdChoiceSortLink = (); + if(this.state.currentSort == 'thirdChoice') + { + if(this.state.sortDirection == 'ASCENDING') + { + var thirdChoiceSortLink = (); + } + else if(this.state.sortDirection == 'DESCENDING') + { + var thirdChoiceSortLink = (); + } + } + + var genderSortLink = (); + if(this.state.currentSort == 'gender') + { + if(this.state.sortDirection == 'ASCENDING') + { + var genderSortLink = (); + } + else if(this.state.sortDirection == 'DESCENDING') + { + var genderSortLink = (); + } + } + + var appDateSortLink = (); + if(this.state.currentSort == 'appDate') + { + if(this.state.sortDirection == 'ASCENDING') + { + var appDateSortLink = (); + } + else if(this.state.sortDirection == 'DESCENDING') + { + var appDateSortLink = (); + } + } + + return( +
    + + + + + + + + + + + + + {applicantRows} + +
    Name {nameSortLink}1st {firstChoiceSortLink}2nd {secondChoiceSortLink}3rd {thirdChoiceSortLink}Sex {genderSortLink}Date {appDateSortLink}Final RLCAction
    +
    + ); + } +}); + +var ApplicantRow = React.createClass({ + getInitialState: function() + { + return {communityId: -1, response: undefined}; + }, + saveCommunityToApplicant: function(appId, communityId) + { + var inputData = {applicationId : appId, + rlcId : communityId + }; + + $.ajax({ + url: 'index.php?module=hms&action=AjaxSetRlcAssignment', + type: 'POST', + dataType: 'json', + data: inputData, + success: function(data) + { + this.setState({response: data}); + }.bind(this), + error: function() + { + + }.bind(this) + }); + }, + changeCommunity: function() + { + var newCommunity = this.refs.communityPicker.getDOMNode().value; + this.setState({communityId: newCommunity}); + }, + saveCommunity: function() + { + this.saveCommunityToApplicant(this.props.node.app_id, this.state.communityId); + }, + denyApp: function() + { + this.props.denyApp(this.props.node.app_id); + }, + showModal: function() + { + this.props.showModal(this.props.node.app_id); + }, + render: function() + { + var communities = this.props.communities; + var data = Array({cId: -1, cName: 'None'}); + var i = 0; + for(i; i < communities.length; i++) + { + data.push(communities[i]); + } + + var communityOptions = data.map(function(node){ + return( + + ); + }); + + var selectRlc = (
    ); + var denyLink = (
    ); + + if(this.state.response != undefined) + { + var success = this.state.response.success; + var error = !this.state.response.success; + var notificationClasses = classNames({ + 'text-success' : success, + 'text-danger' : error + }); + selectRlc = (

    {this.state.response.message}

    ) + } + else { + var saveBtn = (
    ); + if(this.state.communityId != -1) + { + saveBtn = (Save); + } + + var selectRlc = (
    + +
    + {saveBtn} + ) + + actions = ( + ); + } + + var profileLink = "index.php?module=hms&action=ShowStudentProfile&bannerId="+this.props.node.bannerId; + + return( + + {this.props.node.name} + {this.props.node.first_choice} + {this.props.node.second_choice} + {this.props.node.third_choice} + {this.props.node.gender} + {this.props.node.app_date} + {selectRlc} + {actions} + + ) + } +}); + +var ActionBox = React.createClass({ + openModal: function() { + this.props.showModal(); + }, + render: function() + { + return ( + + ) + } +}); + +var ApplicationExport = React.createClass({ + getInitialState: function() + { + return {communityId: 0}; + }, + changeCFilter: function(newFilter) + { + this.setState({communityId: newFilter}) + }, + render: function() + { + var btnStyle = {marginTop: '45px'} + var btnLink = "index.php?module=hms&action=ExportRlcApps&communityId="+this.state.communityId; + + return( +
    +

    Application Export

    +
    + +
    + Export +
    + ); + } +}); + + + + +React.render( + , + document.getElementById('rlcAssignments') +); diff --git a/node_modules/classnames/CONTRIBUTING.md b/node_modules/classnames/CONTRIBUTING.md new file mode 100644 index 00000000..5904061e --- /dev/null +++ b/node_modules/classnames/CONTRIBUTING.md @@ -0,0 +1,21 @@ +# Contributing + +Thanks for your interest in classNames. Issues, PRs and suggestions welcome :) + +Before working on a PR, please consider the following: + +* Speed is a serious concern for this package as it is likely to be called a +significant number of times in any project that uses it. As such, new features +will only be accepted if they improve (or at least do not negatively impact) +performance. +* To demonstrate performance differences please set up a +[JSPerf](http://jsperf.com) test and link to it from your issue / PR. +* Tests must be added for any change or new feature before it will be accepted. + +A benchmark utilitiy is included so that changes may be tested against the +current published version. To run the benchmarks, `npm install` in the +`./benchmarks` directory then run `npm run benchmarks` in the package root. + +Please be aware though that local benchmarks are just a smoke-signal; they will +run in the v8 version that your node/iojs uses, while classNames is _most_ +often run across a wide variety of browsers and browser versions. diff --git a/node_modules/classnames/HISTORY.md b/node_modules/classnames/HISTORY.md new file mode 100644 index 00000000..492952f1 --- /dev/null +++ b/node_modules/classnames/HISTORY.md @@ -0,0 +1,81 @@ +# Changelog + +## v2.2.5 / 2016-05-02 + +* Improved performance of `dedupe` variant even further, thanks [Andres Suarez](https://github.com/zertosh) + +## v2.2.4 / 2016-04-25 + +* Improved performance of `dedupe` variant by about 2x, thanks [Bartosz Gościński](https://github.com/bgoscinski) + +## v2.2.3 / 2016-01-05 + +* Updated `bind` variant to use `[].join(' ')` as per the main script in 2.2.2 + +## v2.2.2 / 2016-01-04 + +* Switched from string concatenation to `[].join(' ')` for a slight performance gain in the main function. + +## v2.2.1 / 2015-11-26 + +* Add deps parameter to the AMD module, fixes an issue using the Dojo loader, thanks [Chris Jordan](https://github.com/flipperkid) + +## v2.2.0 / 2015-10-18 + +* added a new `bind` variant for use with [css-modules](https://github.com/css-modules/css-modules) and similar abstractions, thanks to [Kirill Yakovenko](https://github.com/blia) + +## v2.1.5 / 2015-09-30 + +* reverted a new usage of `Object.keys` in `dedupe.js` that slipped through in the last release + +## v2.1.4 / 2015-09-30 + +* new case added to benchmarks +* safer `hasOwnProperty` check +* AMD module is now named, so you can do the following: + +``` +define(["classnames"], function (classNames) { + var style = classNames("foo", "bar"); + // ... +}); +``` + +## v2.1.3 / 2015-07-02 + +* updated UMD wrapper to support AMD and CommonJS on the same pacge + +## v2.1.2 / 2015-05-28 + +* added a proper UMD wrapper + +## v2.1.1 / 2015-05-06 + +* minor performance improvement thanks to type caching +* improved benchmarking and results output + +## v2.1.0 / 2015-05-05 + +* added alternate `dedupe` version of classNames, which is slower (10x) but ensures that if a class is added then overridden by a falsy value in a subsequent argument, it is excluded from the result. + +## v2.0.0 / 2015-05-03 + +* performance improvement; switched to `Array.isArray` for type detection, which is much faster in modern browsers. A polyfill is now required for IE8 support, see the Readme for details. + +## v1.2.2 / 2015-04-28 + +* license comment updates to simiplify certain build scenarios + +## v1.2.1 / 2015-04-22 + +* added safe exporting for requireJS usage +* clarified Bower usage and instructions + +## v1.2.0 / 2015-03-17 + +* added comprehensive support for array arguments, including nested arrays +* simplified code slightly + +## Previous + +Please see the git history for the details of previous versions. diff --git a/node_modules/classnames/LICENSE b/node_modules/classnames/LICENSE new file mode 100644 index 00000000..e6620b58 --- /dev/null +++ b/node_modules/classnames/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jed Watson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/classnames/README.md b/node_modules/classnames/README.md new file mode 100644 index 00000000..265a2ba7 --- /dev/null +++ b/node_modules/classnames/README.md @@ -0,0 +1,188 @@ +Classnames +=========== + +[![Version](http://img.shields.io/npm/v/classnames.svg)](https://www.npmjs.org/package/classnames) +[![Build Status](https://travis-ci.org/JedWatson/classnames.svg?branch=master)](https://travis-ci.org/JedWatson/classnames) + +A simple javascript utility for conditionally joining classNames together. + +Install with npm or Bower. + +```sh +npm install classnames +``` + +Use with node.js, browserify or webpack: + +```js +var classNames = require('classnames'); +classNames('foo', 'bar'); // => 'foo bar' +``` + +Alternatively, you can simply include `index.js` on your page with a standalone ` + + + + + + + +