Modal state angularjs - javascript

I want set modal state using ui-router.I make state:
.state('adminUsers.new', {
url: '/new',
controller: 'adminUsersCtrl',
onEnter: ['$uibModal', '$state', function($uibModal, $state){
$uibModal.open({templateUrl: "administration/users/new.html"})
.result.then(
function(){
$state.go('^');
},
function(){
$state.go('adminUsers');
},
function(){
$state.go('adminUsers');
}
).finally(function(){$state.go('^')});
}]
})
when I go to adminUsers.new state, template normal loaded and showing. In template I have two buttons:
<span class="btn btn-success" ng-click="addUser()">Add user</span>
<a class="btn btn-danger" ui-sref="adminUsers" href="#/admin/users">Cancel</a>
adminUsersController
var adminUsersController = function($scope, Restangular, $stateParams, $state) {
$scope.store = Restangular.all('users');
console.log("adminUsersController");
$scope.store
.getList()
.then(
function(users){
$scope.users = users;
},
function()
{
alertify.log("Не удалось получить список пользователей");
}
)
$scope.addUser = function() {
alert('hello');
}
};
angular
.module('mofs')
.controller('adminUsersCtrl', [
'$scope',
'Restangular',
'$stateParams',
'$state',
adminUsersController
]);
when I clicked to "addUser" button I don't get alert, but when I clicked to "cancel" button modal window not closed, but in browser url changed to #/admin/users. What am i doing wrong? Thank you.
full template code
<div class="modal-content" uib-modal-transclude=""><div class="row no-margin ng-scope">
<h3>
Новый пользователь
</h3>
<form class="form-horizontal ng-pristine ng-valid" id="userForm">
<div class="form-group">
<label class="col-sm-3 control-label" for="user[surname]">
Фамилия
</label>
<div class="col-sm-9">
<input class="form-control" id="user[surname]" name="user[surname]" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[name]">
Имя
</label>
<div class="col-sm-9">
<input class="form-control" id="user[name]" name="user[name]" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[patronimyc]">
Отчество
</label>
<div class="col-sm-9">
<input class="form-control" id="user[patronimyc]" name="user[patronimyc]" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[login]">
Логин
</label>
<div class="col-sm-9">
<input class="form-control" id="user[login]" name="user[login]" type="password">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[password]">
Пароль
</label>
<div class="col-sm-9">
<input class="form-control" id="user[password]" name="user[password]" type="password">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[password_confirmation]">
Подтверждение пароля
</label>
<div class="col-sm-9">
<input class="form-control" id="user[password_confirmation]" name="user[password_confirmation]" type="password">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[role]">
Роль
</label>
<div class="col-sm-9">
<select class="form-control" id="user[role]" name="user[role]">
<option value="1">Администратор</option>
<option value="2">Главный врач</option>
<option value="3">Врач</option>
<option value="4">Сотрудник регистратуры</option>
</select>
</div>
</div>
</form>
</div>
<div class="row no-margin ng-scope">
<div class="pull-right">
<span class="btn btn-success" ng-click="addUser()">Добавить</span>
<a class="btn btn-danger" ui-sref="adminUsers" href="#/admin/users">Отменить</a>
</div>
</div></div>

Along with teplateUrl, you provide controller as property.Like as fallows
$uibModal.open({
animation: true,
templateUrl: 'Your template URL',
controller: 'Your controller',
size: undefined,
resolve : {
// If you have anything to resolve
embedLink : function (){
return embedLink;
}
}
});
Inside your controller add a method which will call on click of cancel button as fallows.
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
Don't forget to have a dependency of uibModalInstance in you controller.
The same you can do inside the same controller on click of addUser button.
Please refer Plunker

Related

Error: [ng:areq] Argument 'UsersSettingsController' is not a function, got undefined

I'm trying to create a edit profile section in angularjs. For that i create in my users controller a section to make a rest api call to get info to inject on the page and later i will do the parte of changePassword also.
At the moment i'm getting the error "Error: [ng:areq] Argument 'UsersSettingsController' is not a function, got undefined" and I cant undestand why.
editAccount view:
<div class="row" ng-controller="UsersSettingsController as usersSettingsCtrl" >
{{userInfo}}
<!-- edit form column -->
<div class="col-md-9 personal-info">
<h3>Personal info</h3>
<form class="form-horizontal" role="form">
<div class="form-group">
<label class="col-md-3 control-label">Username:</label>
<div class="col-md-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.username}}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Organization:</label>
<div class="col-lg-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.organization_name}}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Permission Group:</label>
<div class="col-lg-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.permission_group_name}}" readonly>
</div>
</div>
<div class="form-group" nf-ig="user.organization_permission_group_id=='df0417e3-ce36-41ca-9f13-f58c1a3a96f5'">
<label class="col-lg-3 control-label">Root:</label>
<div class="col-lg-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.data.root}}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Email:</label>
<div class="col-lg-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.username}}" readonly>
</div>
</div>
<hr>
<h4>Change Password</h4>
<br>
<form name="newPasswordForm" role="form" ng-submit="newPasswordForm.$valid && ok()" novalidate>
<div class="form-group">
<label class="col-md-3 control-label">Change Password:</label>
<div class="col-md-8">
<input type="password" name="newPassword" ng-model="password.new"
ng-minlength="6" required />
<span class="help-block"
ng-show="newPasswordForm.newPassword.$dirty && newPasswordForm.newPassword.$invalid">
Please enter a new password, it must be at least 6 characters long.
</span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Confirm password:</label>
<div class="col-md-8">
<input type="password" name="newPasswordConfirm"
ng-model="password.confirm" ng-minlength="6"
value-matches="password.new" required />
<span class="help-block"
ng-show="newPasswordForm.newPasswordConfirm.$dirty && newPasswordForm.newPasswordConfirm.$invalid">
Please enter the same password again to confirm.
</span>
</div>
</div>
</form>
<div class="form-group">
<label class="col-md-3 control-label"></label>
<div class="col-md-8">
<input type="button" class="btn btn-primary" style="float:right" value="Save Changes">
<div ng-messages="registrationForm.confirmPassword.$error" ng-messages-include="messages.html"></div>
</div>
</div>
</form>
</div>
</div>
usersController:
app.controller('UsersSettingsController',['$scope', 'user', function ($scope, user) {
$http.get('/api/users/userInfo/'+user.id).success(function (data) {
console.log("user info ",data);
$scope.userInfo = data;
});
//changePassword call to rest api
}]);
usersDirective:
(function() {
var app = angular.module('userSettings', []);
app.directive('valueMatches', ['$parse', function ($parse) {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ngModel) {
var originalModel = $parse(attrs.valueMatches),
secondModel = $parse(attrs.ngModel);
// Watch for changes to this input
scope.$watch(attrs.ngModel, function (newValue) {
ngModel.$setValidity(attrs.name, newValue === originalModel(scope));
});
// Watch for changes to the value-matches model's value
scope.$watch(attrs.valueMatches, function (newValue) {
ngModel.$setValidity(attrs.name, newValue === secondModel(scope));
});
}
};
}]);
})();

How do I clear or reset data in a form in angularjs?

Been finding how to clear form data with the use of angular and $setPristine Function but still no results always gives me an error saying $setPristine is not a function. Can anyone kindly help me for a solution?
here's my angular.controller
$scope.AddCustomer = function () {
var CustDetails = {
cname: $scope.CusDetails.cname,
comname: $scope.CusDetails.comname,
tel: $scope.CusDetails.tel,
email: $scope.CusDetails.email
};
CustService.Customer(CustDetails, function (res) {
console.log(res);
$.extend($.gritter.options, {
position: 'bottom-right',
});
if (res.data == 'success') {
$.gritter.add({
title: 'Success!',
text: 'Successfully added the new customer ' + '<h4><span class="label label-primary">' + CustDetails.cname + '</span></h4>',
time: '5000',
close_icon: 'l-arrows-remove s16',
icon: 'glyphicon glyphicon-ok-circle',
class_name: 'success-notice'
});
//CustDetails = {};
customerForm.$setPristine(true);
}
else {
$.gritter.add({
title: 'Failed!',
text: 'Failed to add a new customer',
time: '5000',
close_icon: 'l-arrows-remove s16',
icon: 'glyphicon glyphicon-remove-circle',
class_name: 'error-notice'
});
}
});
}
Here's the Html code
<div ng-controller="AddCustomerController">
<div class="page-content-wrapper">
<div class="page-content-inner">
<div id="page-header" class="clearfix">
<div class="page-header">
<h2>Add Customer</h2>
<span class="txt">Create and add new customer.</span>
</div>
</div>
<!--Start .row-->
<div class="row">
<div class="col-md-1">
</div>
<div class="col-lg-9 col-sm-9 col-xs-12">
<!--col-lg-9 starts here-->
<div class="panel panel-default toggle panelMove panelClose panelRefresh">
<div class="panel-heading">
<h4 class="panel-title">Customer Details</h4>
</div>
<div class="panel-body pt0 pb0">
<form class="form-horizontal group-border stripped" id="customerForm">
<div class="form-group">
<label class="col-lg-2 col-md-3 control-label">Customer Name</label>
<div class="col-lg-10 col-md-9">
<input type="text" required id="cname" ng-model="CusDetails.cname" class="form-control" name="cname" />
</div>
</div>
<!--end of .form-group-->
<div class="form-group">
<label class="col-lg-2 col-md-3 control-label">Company Name</label>
<div class="col-lg-10 col-md-9">
<input type="text" required id="comname" ng-model="CusDetails.comname" class="form-control" name="comname" />
</div>
</div>
<!--end of .form-group-->
<div class="form-group">
<label class="col-lg-2 col-md-3 control-label" for="">Telephone Number</label>
<div class="col-lg-10 col-md-9">
<div class="input-group input-icon">
<span class="input-group-addon"><i class="fa fa-phone s16"></i></span>
<input ng-model="CusDetails.tel" class="form-control" id="ctel" type="text" placeholder="(999) 999-9999">
</div>
</div>
</div>
<!-- End .form-group -->
<div class="form-group">
<label class="col-lg-2 col-md-3 control-label" for="">Email address</label>
<div class="col-lg-10 col-md-9">
<input id="email" ng-model="CusDetails.email" type="text" class="form-control" name="placeholder" placeholder="someone#example.com">
</div>
</div>
<!-- End .form-group -->
</form>
</div>
</div>
<!--End .panel-->
</div>
<!--.col-9 ends here-->
</div>
<!--End .row-->
<!--Start .row-->
<div class="row">
<div class="col-md-1"></div>
<div class="col-lg-9 col-sm-9 col-xs-12">
<button id="btnSubmit" type="submit" ng-click="AddCustomer()" class="btn btn-info pad"><span class="fa fa-user-plus"></span> Add Customer</button>
<button type="submit" class="btn btn-default pad">Cancel</button>
</div>
</div>
</diV>
</div>
</div>
You can remove form field value by removing value of ng-model like
Your code
var CustDetails = {
cname: $scope.CusDetails.cname,
comname: $scope.CusDetails.comname,
tel: $scope.CusDetails.tel,
email: $scope.CusDetails.email
};
Replace with this
$scope.CustDetails = {
cname: $scope.CusDetails.cname,
comname: $scope.CusDetails.comname,
tel: $scope.CusDetails.tel,
email: $scope.CusDetails.email
};
Your code
customerForm.$setPristine(true);
Replace with this
$scope.CustDetails={};
use:
$scope.$destroy
as it removes all the children associated to the parent scope and will clear all the data associated with it.
Use
$scope.customerForm.$setPristine(true);
Give the form a name like
name= "CusDetails"
Then It will solve the problem.
Use name attr instead of id. name="forName"
The form reference inside Controller will be $scope.formName
You can set the form with the code below:
$scope.customerForm.$setPristine();
$scope.customerForm.$setUntouched();
$scope.CustDetails={};

Load data to form using AngularJS

I am trying to load data from a Service to a form but is not binding to the field value the data loaded from the service/server:
The data from service is coming OK, the problem is after setting here in this code, I load a route to my form but the form keeps with the old values, this code is in my controller:
$scope.cadastro = {
email: '',
name: 'the name to put in the field',
city: ''
};
$scope.editar = function () {
myAppServices.getUserData($rootScope.uid).then(function (data) {
if (data !== null) {
$scope.cadastro = data;
$scope.cadastro.name = data.name;
$location.path('cadastro');
}
});
};
the HTML form:
<form name="myDataForm" class="form-horizontal" role="form">
<div class="form-group">
<label class="col-sm-5 control-label no-padding-right" for="email">Email</label>
<div class="col-sm-7">
<span class="block input-icon input-icon-right">
<input type="text" class="form-control" placeholder="Email" name="email" ng-model="cadastro.email" focus/>
<span ng-show="myDataForm.email.$error.email" class="help-inline">Email is not valid</span>
</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-5 control-label no-padding-right" for="name">Nome Completo</label>
<div class="col-sm-7">
<span class="block input-icon input-icon-right">
<input type="text" name="name" class="form-control" placeholder="Nome" ng-model="cadastro.name" />
<small class="errorMessage" data-ng-show="myDataForm.name.$dirty && myDataForm.name.$error.required"> Informe seu nome completo.</small>
</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-5 control-label no-padding-right" for="address">Cidade</label>
<div class="col-sm-7">
<span class="block input-icon input-icon-right">
<input type="text" class="form-control" placeholder="Cidade" ng-model="cadastro.city" />
</span>
</div>
</div>
<div class="form-group">
<span class="lbl col-sm-5"> </span>
<div class="col-sm-7">
<button type="submit" class="width-35 pull-right btn btn-sm btn-primary" ng-click="salvarcadastroForm(cadastro)" data-ng-disabled="myDataForm.$invalid">
<i class="fa fa-floppy-o"></i> Save
</button>
</div>
</div>
</form>
What should I do?
SOLUTION:
Load user data in a init method in the controller:
$scope.init = function () {
$scope.reset();
// if user logged then load data
if ($rootScope.uid !== undefined) {
myAppServices.getUserData($rootScope.uid).then(function (data) {
if (data !== null) {
$scope.formData = data;
}
});
}
};

Angular-UI routing reloading template

I'm using the angular-ui Routing, but when nesting it keeps loading the main index file over and over again I think, I'm working in Visual Studio and it starts lagging when I go to that page, but the other ones are no problem
this is the code in routing:
$stateProvider
.state("stateOne", {
url: "/stateOne",
templateUrl: "/routesDemo/one"
})
.state("stateTwo", {
url: "/stateTwo?donuts",
templateUrl: function(params) { return "/routesDemo/two?donuts=" + params.donuts; }
})
.state("stateThree", {
url: "/stateThree",
templateUrl: "/routesDemo/three"
})
.state("stateAllProducts", {
url: "/Products",
templateUrl: "/product/all",
controller: ProductJsController
})
.state("loginRegister", {
url: "/loginRegister?returnUrl",
views: {
"": {
templateUrl: "/Account/LoginRegister",
},
"login#loginRegister": {
templateUrl: "/Account/Login",
controller: LoginController
},
"register#loginRegister": {
templateUrl: "/Account/Register",
controller: RegisterController
}
}
});
The content of LoginRegister is as following:
<div ui-view="login"></div>
<div ui-view="register"></div>
Login
<div class="col-lg-6">
<div class="bs-component">
<form class="form-horizontal" ng-submit="login()">
<fieldset>
<legend>Login</legend>
<div class="form-group">
<label for="emailAddress" class="col-lg-2 control-label">Email</label>
<div class="col-lg-10">
<div class="form-control-wrapper">
<input type="email" class="form-control empty" ng-model="loginForm.emailAddress" id="emailAddress" placeholder="Email"><span class="material-input"></span></div>
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label">Password</label>
<div class="col-lg-10">
<div class="form-control-wrapper">
<input type="password" class="form-control empty" ng-model="loginForm.password" id="password" placeholder="Password"><span class="material-input"></span></div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="loginForm.rememberMe"><span class="ripple"></span><span class="check"></span> Remember me?
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</fieldset>
</form>
<div id="source-button" class="btn btn-primary btn-xs" style="display: none;">
< >
<div class="ripple-wrapper"></div>
</div>
</div>
<div class="alert alert-dismissable alert-danger" ng-if="loginForm.loginFailure">
<button type="button" class="close" data-dismiss="alert" ng-click="closeError()">×</button>
<strong>Oh snap!</strong> Change a few things up and try submitting again.
</div>
</div>
Register
<form ng-submit="register()">
<label for="emailAddress">Email Address:</label>
<input id="emailAddress" type="text" ng-model="registerForm.emailAddress" required/>
<label for="password">Password:</label>
<input id="password" type="password" ng-model="registerForm.password" required/>
<label for="confirmPassword">Confirm Password:</label>
<input id="confirmPassword" type="password" ng-model="registerForm.confirmPassword" required/>
<button type="submit">Register</button>
</form>
<div ng-if="loginForm.registrationFailure">
D'oh!
</div>
Please provide the index HTML file. Your view may not be able to be rendered if you controller is not loading. Please also provide one of your controller files.
You need to enclose your controller names in quotes, the same way they are in the controller.
.state("stateAllProducts", {
url: "/Products",
templateUrl: "/product/all",
controller: ProductJsController
Looks like it should be:
.state("stateAllProducts", {
url: "/Products",
templateUrl: "/product/all",
controller: 'ProductJsController'
Without seeing more code, this is the best I can provide.

Trouble posting data to web api using Angularjs

Learning Angular by redoing an app I've built. I am trying to post some data from a collection of text boxes to my production api. When I click the submit button, I get no response. No flicker, no error message, nothing. I'm curious if I don't have my Angular wired up properly. If anyone could help me figure this one out, I'd greatly appreciate it.
MainController.js
(function () {
var app = angular.module("app", [])
app.controller('MainController', function($scope, $http) {
var onUpdatesComplete = function (response) {
$scope.updates = response.data;
};
$http.get("productionApiAddress")
.then(onUpdatesComplete);
$scope.demoInquiry = function(){
var data = $.param({
json: JSON.stringify({
firstName : $scope.firstName,
lastName : $scope.lastName,
companyName : $scope.companyName,
email : $scope.email,
phone : $scope.phone
})
});
$http.post("http://productionApiAddress", data).success(function() {
$.('#demoSuccessResult').removeClass('hidden');
})
};
});
}());
index.html
<html ng-app="app">
...
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.min.js"></script>
<script type="text/javascript" src="js/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="js/MainController.js"></script>
...
<body ng-controller="MainController">
...
<div class="row">
<div class="col-lg-6 col-xs-12">
<div class="form-group">
<label>First Name*</label>
<input type="text" id="txtFirstName" ng-model="firstName" class="form-control" required/>
</div>
</div>
<div class="col-lg-6 col-xs-12">
<div class="form-group">
<label>Last Name*</label>
<input type="text" id="txtLastName" ng-model="lastName" class="form-control" required/>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-12">
<div class="form-group">
<label>Company Name*</label>
<input type="text" id="txtCompanyName" ng-model="companyName" class="form-control" required/>
</div>
</div>
<div class="col-lg-6 col-xs-12">
<div class="form-group">
<label>Your Work Email*</label>
<input type="text" id="txtEmail" ng-model="email" class="form-control" required/>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-lg-offset-3 col-xs-12">
<div class="form-group">
<label>Office Phone Number*</label>
<input type="text" id="txtPhone" ng-model="phone" class="form-control" required/>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-lg-offset-3 col-xs-12">
<div class="form-group">
<input type="submit" id="btnDemoSubmit" ng-click="demoInquiry()" class="btn btn-default form-control"
style="background-color: #053A54; color: #ffffff;"
value="Submit For Trial"/>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-9 col-lg-offset-3 col-xs-12">
<p>* - required</p>
</div>
</div>
<div class="row">
<div class="col-lg-9 col-lg-offset-3 col-xs-12 hidden">
<span id="demoSuccessResult" style="color: blue;">Thank you for registering!</span>
</div>
</div>
Please see below. You don't have to use jquery to show/hide dive elements ng-show hide will do this same work for you.
var app = angular.module('app', []);
app.controller('firstCtrl', function($scope, $http) {
$scope.demoInquiry = function() {
var data = {
firstName: $scope.firstName,
lastName: $scope.lastName,
companyName: $scope.companyName,
email: $scope.email,
phone: $scope.phone
};
console.log(data);
$http.post("http://productionApiAddress", data).success(function() {
$scope.postSucess = true
}).error(function() {
$scope.postError = true;
});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<div ng-controller="firstCtrl">
<div class="row">
<div class="col-lg-6 col-xs-12">
<div class="form-group">
<label>First Name*</label>
<input type="text" id="txtFirstName" ng-model="firstName" class="form-control" required/>
</div>
</div>
<div class="col-lg-6 col-xs-12">
<div class="form-group">
<label>Last Name*</label>
<input type="text" id="txtLastName" ng-model="lastName" class="form-control" required/>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-12">
<div class="form-group">
<label>Company Name*</label>
<input type="text" id="txtCompanyName" ng-model="companyName" class="form-control" required/>
</div>
</div>
<div class="col-lg-6 col-xs-12">
<div class="form-group">
<label>Your Work Email*</label>
<input type="text" id="txtEmail" ng-model="email" class="form-control" required/>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-lg-offset-3 col-xs-12">
<div class="form-group">
<label>Office Phone Number*</label>
<input type="text" id="txtPhone" ng-model="phone" class="form-control" required/>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-lg-offset-3 col-xs-12">
<div class="form-group">
<input type="submit" id="btnDemoSubmit" ng-click="demoInquiry()" class="btn btn-default form-control" style="background-color: #053A54; color: #ffffff;" value="Submit For Trial" />
</div>
</div>
</div>
<div class="row">
<div class="col-lg-9 col-lg-offset-3 col-xs-12">
<p>* - required</p>
</div>
</div>
<div class="row" ng-show="postSucess">
<div class="col-lg-9 col-lg-offset-3 col-xs-12 ">
<span id="demoSuccessResult" style="color: blue;">Thank you for registering!</span>
</div>
</div>
<div class="row" ng-show="postError">
<div class="col-lg-9 col-lg-offset-3 col-xs-12 ">
<span id="demoErrorResult" style="color: red;">Wooowa can't post </span>
</div>
</div>
</div>
</body>

Categories

Resources