gaf-mobile
Version:
GAF mobile Web site
375 lines (354 loc) • 30.3 kB
HTML
<div class="post-project-template scroll-container" ng-class="{'is-modal-active': ctrl.showPaymentReleaseModal}" fl-analytics-section="PostProject">
<!-- PAGE VIEW -->
<!-- Opt out banner. Displayed only with a template -->
<aside class="post-project-template-banner" ng-if="!ctrl.modal.hideOptOutBanner && ctrl.template.questions.length && ctrl.state === 'start'">
<div class="section-inner">
<span class="post-project-template-banner-details">
<strong class="post-project-template-banner-title">Not after a {{ ctrl.template.description.toLowerCase() }} project?</strong>
<a class="post-project-template-banner-link" ng-click="ctrl.optOutTemplate()" fl-analytics="OptOutTemplate">Tell us about your project</a>
</span>
<button class="post-project-template-banner-close btn btn-text btn-text-alt" title="Close" ng-click="ctrl.modal.hideOptOutBanner = true" fl-analytics="CloseOptOutBanner">
<span class="icon-circled-cross"></span>
</button>
</div>
</aside>
<section class="post-project-template-form" ng-if="ctrl.state === 'start'" fl-analytics-subsection="ProjectTemplate">
<div class="section-inner" fl-pagination="progress.current" fl-pagination-container=".scroll-container">
<fl-form name="form" class="paginated-form" action="ctrl.create(ctrl.project)">
<div ng-repeat="q in ctrl.template.dynamic_questions" fl-pagination-page="$index">
<!-- Multiple choice template question -->
<fieldset class="paginated-form-fieldset" ng-if="q.project_template_question_text.style === 'radio'">
<legend class="paginated-form-legend">{{ q.project_template_question_text.question_text }}</legend>
<div class="paginated-form-field-group paginated-form-radio">
<label class="paginated-form-radio-input" for="input-{{$parent.$index}}-{{$index}}" ng-repeat="a in q.answers" ng-class="{ 'is-selected': (ctrl.project.answers[$parent.$index] === a) }">
<input type="radio" id="input-{{$parent.$index}}-{{$index}}" ng-change="ctrl.electAnswer(q, ctrl.project.answers)" ng-value="a" ng-model="ctrl.project.answers[$parent.$index]" fl-pagination-goto="$parent.$index + 1" fl-analytics="Question{{$parent.$index}}Answer{{$index}}" fl-analytics-value="$index" fl-analytics-label="{{a.label}}">
{{ a.answer }}
</label>
</div>
</fieldset>
<!-- Free form template question -->
<!-- Clean up when RequireProjectDescription A/B test is done -->
<fieldset class="paginated-form-fieldset" ng-if="q.project_template_question_text.style === 'freeform'">
<legend class="paginated-form-legend"> {{ q.project_template_question_text.question_text }}</legend>
<div class="paginated-form-textarea">
<form name="freeForm" class="form" novalidate>
<textarea class="post-project-template-description"
name="freeformanswer"
ng-model="ctrl.project.freeform_answers[$parent.$index]"
fl-autoresize
placeholder="This helps freelancers bid more accurately."
fl-analytics="FreeformQuestion{{$parent.$index}}"
required
ng-minlength="10"
ng-if="ctrl.isFromNonFiveEye && ctrl.project.type !== 'contest'">
</textarea>
<textarea class="post-project-template-description"
name="freeformanswer"
ng-model="ctrl.project.freeform_answers[$parent.$index]"
fl-autoresize
placeholder="This helps freelancers bid more accurately."
fl-analytics="FreeformQuestion{{$parent.$index}}"
ng-if="!ctrl.isFromNonFiveEye || ctrl.project.type === 'contest'">
</textarea>
<div ng-if="freeForm.$dirty || freeForm.$submitted" ng-messages="freeForm.freeformanswer.$error">
<span class="validation validation-error" ng-message="required">
<span class="icon-notification"> </span>
Please enter a valid description
</span>
<span class="validation validation-error" ng-message="minlength">
<span class="icon-notification"> </span>
Your description must be at least 10 characters
</span>
</div>
<button type="submit" class="btn btn-primary" ng-if="ctrl.isFromNonFiveEye && ctrl.project.type !== 'contest' && (!freeForm.$dirty || freeForm.$invalid)" ng-click="freeForm.$setSubmitted()">Next Question</button>
<button type="button" class="btn btn-primary" ng-if="freeForm.$valid && ctrl.showProjectOption && ctrl.project.type !== 'contest'" ng-class="{'btn-primary': !contestBudgetForm.$invalid}" fl-pagination-goto="$parent.$index + 1" ng-click="ctrl.electFreeFormAnswer(q, $parent.$index, ctrl.project.freeform_answers[$parent.$index])" fl-analytics="GoToNextQuestionFromFreeForm">Next Question</button>
<button type="button" class="btn paginated-form-cancel-btn" ng-if="!ctrl.isFromNonFiveEye && ctrl.showProjectOption && ctrl.project.type !== 'contest'" fl-pagination-goto="$parent.$index + 1" fl-analytics="SkipFreeForm">Skip</button>
<button type="button" class="btn btn-primary" ng-if="freeForm.$valid && !ctrl.showProjectOption" fl-pagination-goto="ctrl.template.dynamic_questions.length + 1" ng-click="ctrl.electFreeFormAnswer(q, $parent.$index, ctrl.project.freeform_answers[$parent.$index])" fl-analytics="GoToNextQuestionFromFreeForm">Next Question</button>
<button type="button" class="btn paginated-form-cancel-btn" ng-if="!ctrl.isFromNonFiveEye && !ctrl.showProjectOption" fl-pagination-goto="ctrl.template.dynamic_questions.length + 1" fl-analytics="SkipFreeForm">Skip</button>
<button type="button" class="btn btn-primary" ng-if="ctrl.showProjectOption && ctrl.project.type === 'contest'" fl-pagination-goto="$parent.$index + 2" ng-click="ctrl.electFreeFormAnswer(q, $parent.$index, ctrl.project.freeform_answers[$parent.$index])" fl-analytics="GoToNextQuestionFromFreeForm">Next Question</button>
<button type="button" class="btn paginated-form-cancel-btn" ng-if="ctrl.showProjectOption && ctrl.project.type === 'contest'" fl-pagination-goto="$parent.$index + 2" fl-analytics="SkipFreeForm">Skip</button>
</form>
</div>
</fieldset>
</div>
<fieldset id="type" class="paginated-form-fieldset" fl-pagination-page="ctrl.template.dynamic_questions.length" ng-if="ctrl.showProjectOption">
<legend class="paginated-form-legend">How would you like to get the project done?</legend>
<div class="paginated-form-field-group">
<div class="paginated-form-radio">
<label class="paginated-form-radio-input" for="type-project" ng-class="{ 'is-selected': ctrl.project.type === 'project' }">
<input type="radio" name="type" id="type-project"
ng-model="ctrl.project.type"
value="project"
fl-pagination-reset
fl-pagination-goto="ctrl.template.dynamic_questions.length + 1"
fl-analytics="ChangedType" fl-value="project">
Project
</label>
<label class="paginated-form-radio-input" for="type-contest" ng-class="{ 'is-selected': ctrl.project.type === 'contest' }">
<input type="radio" name="type" id="type-contest"
ng-model="ctrl.project.type"
value="contest"
fl-pagination-reset
fl-pagination-goto="ctrl.template.dynamic_questions.length + 1"
fl-analytics="ChangedType" fl-value="contest">
Contest
</label>
</div>
<p class="post-project-template-form-note"><strong>NOTE:</strong> Running a contest allows you to get designs from multiple freelancers. You only pay for the one you love!</p>
</div>
</fieldset>
<!-- Budget section -->
<fieldset id="budget" class="paginated-form-fieldset" fl-pagination-page="ctrl.template.dynamic_questions.length + 1" ng-if="ctrl.project.type !== 'contest'">
<legend class="paginated-form-legend">What budget do you have in mind?</legend>
<div class="paginated-form-field-group">
<select class="post-project-currency-select" id="currency" name="currency" required ng-model="ctrl.project.currency" ng-options="c.code for c in ctrl.currencies | orderBy:'code' track by c.id" ng-change="ctrl.changeCurrency()" fl-analytics="ChangedCurrency" fl-analytics-value="ctrl.project.currency.id"></select>
<div class="paginated-form-radio">
<label class="paginated-form-radio-input" for="budget-{{$index}}" ng-repeat="b in ctrl.budgets['fixed'] | filter:{currency_id: ctrl.project.currency.id}:true track by b.id" ng-class="{ 'is-selected': (ctrl.project.budget.id === b.id), 'is-default': (ctrl.getDefaultBudget('fixed').id === b.id) }">
<input type="radio" name="budget" id="budget-{{$index}}"
ng-model="ctrl.project.budget"
ng-value="b"
fl-pagination-reset
fl-pagination-goto="ctrl.template.questions.length + 3"
fl-analytics="ChangedBudget">
{{ b.name }} ({{ ctrl.formatBudget(b, ctrl.project.currency) }})
</label>
</div>
</div>
</fieldset>
<fieldset id="budget" class="paginated-form-fieldset" fl-pagination-page="ctrl.template.dynamic_questions.length + 1" ng-if="ctrl.project.type === 'contest'">
<legend class="paginated-form-legend">What budget do you have in mind?</legend>
<div class="paginated-form-field-group">
<select class="post-project-currency-select" id="currency" name="currency" required ng-model="ctrl.project.currency" ng-options="c.code for c in ctrl.currencies | orderBy:'code' track by c.id" ng-change="ctrl.changeCurrency()" fl-analytics="ChangedCurrency" fl-analytics-value="ctrl.project.currency.id"></select>
<form name="contestBudgetForm" class="form" >
<label>Budget</label>
<input name="budget" type="number" required ng-min="ctrl.minimumBudget()" ng-model="ctrl.project.customBudget">
<div ng-messages="contestBudgetForm.budget.$error">
<span class="validation validation-error" ng-message="number">
<span class="icon-notification"> </span>
Please enter a valid number
</span>
<span class="validation validation-error" ng-message="required">
<span class="icon-notification"> </span>
Please enter the budget amount
</span>
<span class="validation validation-error" ng-message="min">
<span class="icon-notification"> </span>
Your budget must be above {{ ctrl.minimumBudget() | currency: ctrl.project.currency.sign}} {{ctrl.project.currency.code}}
</span>
</div>
<button type="button" class="btn" fl-analytics="GoToNextQuestion" ng-class="{'btn-primary': !contestBudgetForm.$invalid}" ng-disabled="contestBudgetForm.$invalid"
ng-click="ctrl.template.dynamic_questions.length + 1"
fl-pagination-goto="
ctrl.template.questions.length + 3">Next Question</button>
</form>
</div>
</fieldset>
<!-- Summary section only shown for the non-generic templates -->
<section ng-if="ctrl.template.questions.length + 1" fl-pagination-page="ctrl.template.questions.length + 3" fl-analytics-subsection="ProjectTemplateSummary">
<span class="post-project-template-summary" ng-if="ctrl.project.type === 'contest'">Contest Summary</span>
<span class="post-project-template-summary" ng-if="ctrl.project.type !== 'contest'">Project Summary</span>
<div class="summary-block summary-block-full-width">
<span class="summary-block-title">Title</span>
<span name="title" class="summary-block-content editable-text has-icon needsfocus" contenteditable="true"
fl-contenteditable required ng-minlength="4" ng-maxlength="150"
ng-model="ctrl.project.title"
fl-analytics="ChangedTitle">
</span>
<div class="paginated-form-validation" ng-messages="form.title.$error">
<span class="validation validation-error" ng-message="required">
<span class="icon-notification"> </span>
Please enter a title for your project
</span>
<span class="validation validation-error" ng-message="minlength">
<span class="icon-notification"> </span>
Your project title must be at least 4 characters
</span>
<span class="validation validation-error" ng-message="maxlength">
<span class="icon-notification"> </span>
Your project title must be at most 150 characters
</span>
</div>
</div>
<div class="summary-block summary-block-full-width">
<span class="summary-block-title">Description</span>
<span name="description" class="summary-block-content editable-text has-icon needsfocus" contenteditable="true" fl-contenteditable required ng-minlength="10" ng-model="ctrl.project.description" fl-analytics="ChangedDescription"></span>
<div class="paginated-form-validation" ng-messages="form.description.$error">
<span class="validation validation-error" ng-message="required">
<span class="icon-notification"> </span>
Please enter a description
</span>
<span class="validation validation-error" ng-message="minlength">
<span class="icon-notification"> </span>
Your description must be at least 10 characters
</span>
</div>
</div>
<div class="summary-block summary-block-full-width" fl-smooth-scroll="#budget">
<span class="summary-block-title">Budget</span>
<span ng-if="ctrl.project.type !== 'contest'"class="summary-block-content editable-text has-icon" fl-analytics="ChangedBudget">{{ ctrl.formatBudget(ctrl.project.budget, ctrl.project.currency) }}
<span class="summary-block-detail" fl-analytics="CurrencySummary">{{ ctrl.project.currency.code }}</span>
</span>
<span ng-if="ctrl.project.type === 'contest'"class="summary-block-content editable-text has-icon" fl-analytics="ChangedBudget">{{ ctrl.project.currency.sign }}{{ ctrl.project.customBudget || ctrl.projectBudget }}
<span class="summary-block-detail" fl-analytics="CurrencySummary">{{ ctrl.project.currency.code }}</span>
</span>
</div>
<div ng-if="ctrl.project.type === 'contest'" class="summary-block summary-block-full-width" fl-smooth-scroll="#duration">
<span class="summary-block-title">Duration (days)</span>
<input name="duration" type="number" class="summary-block-content" required min="3" max="31" ng-model="ctrl.project.duration" fl-analytics="ChangedDuration">
<div class="paginated-form-validation" ng-messages="form.duration.$error">
<span class="validation validation-error" ng-message="required">
<span class="icon-notification"> </span>
Please enter a duration for your contest
</span>
<span class="validation validation-error" ng-message="number">
<span class="icon-notification"> </span>
Please enter a a valid number for the duration
</span>
<span class="validation validation-error" ng-message="min">
<span class="icon-notification"> </span>
Your duration must be at least 3 days
</span>
<span class="validation validation-error" ng-message="max">
<span class="icon-notification"> </span>
Your duration must be at most 31 days
</span>
</div>
</div>
<div class="paginated-form-validation">
<span class="validation validation-error" ng-if="ctrl.error.unverifiedPayment">
<span class="icon-notification"> </span>
You need to <a href="https://www.freelancer.com/payments/verify.php" fl-gaf-link target="_blank" fl-analytics="GoToVerifyPayment">verify your payment source</a> before posting another project.
</span>
<span class="validation validation-error" ng-if="ctrl.error.negativeBalance">
<span class="icon-notification"> </span>
You have a negative balance. Please <a href="/deposit" fl-analytics="GoToMakeDeposit">add funds to your account</a> before posting a project.
</span>
<span class="validation validation-error" ng-if="ctrl.error.internalError">
<span class="icon-notification"> </span>
An internal error occurred: {{ ctrl.error.internalError }}
</span>
</div>
<fl-button type="submit" class="btn btn-primary post-project-button" fl-analytics="GoToPostProject" ng-if="ctrl.project.type !== 'contest'">Post a project</fl-button>
<fl-button type="submit" class="btn btn-primary post-project-button" fl-analytics="GoToPostProject" ng-if="ctrl.project.type === 'contest'">Post Contest</fl-button>
</section>
<!-- Description section only shown for the generic template -->
<fieldset class="paginated-form-fieldset" ng-if="!ctrl.template.questions.length && !ctrl.noTemplate" fl-pagination-page="2">
<legend class="paginated-form-legend">Describe what you need done:</legend>
<div class="paginated-form-textarea">
<textarea class="post-project-template-description"
name="description"
placeholder="I need..."
required
ng-minlength="10"
ng-model="ctrl.project.description"
fl-autoresize
fl-analytics="Description">
</textarea>
<div ng-if="form.$submitted || form.description.$touched" class="paginated-form-validation" ng-messages="form.description.$error">
<span class="validation validation-error" ng-message="required">
<span class="icon-notification"> </span>
Please enter a description for your project
</span>
<span class="validation validation-error" ng-message="minlength">
<span class="icon-notification"> </span>
Your description must be at least 10 characters
</span>
</div>
</div>
<div ng-if="ctrl.project.local" class="summary-block summary-block-full-width">
<span class="summary-block-title">Location</span>
<span ng-show="ctrl.isFetchingLocation()" class="summary-block-content">Fetching your location...</span>
<span ng-show="!ctrl.isFetchingLocation()" class="summary-block-content editable-text has-icon needsfocus"
name="location"
contenteditable="true" required
fl-contenteditable
g-places-autocomplete
fl-invalid-if="!ctrl.project.place || !ctrl.locationValid()"
ng-model="ctrl.project.place">
</span>
<div class="paginated-form-validation">
<span class="validation validation-error" ng-if="ctrl.project.local && ctrl.error.locationError && ctrl.project.place === undefined && !ctrl.locationValid()">
<span class="icon-notification"> </span>
We were unable to fetch your location. Please enter it manually.
</span>
<span class="validation validation-error" ng-if="!ctrl.error.locationError && ctrl.project.local && !ctrl.isFetchingLocation() && ctrl.project.place === undefined">
<span class="icon-notification"> </span>
You need to enter a location for a local project.
</span>
<span class="validation validation-error" ng-if="ctrl.project.local && !ctrl.isFetchingLocation() && ctrl.project.place !== undefined && !ctrl.locationValid()">
<span class="icon-notification"></span>
The location you entered is not valid. Please select a valid location for your local project.
</span>
</div>
</div>
<div class="paginated-form-validation">
<span class="validation validation-error" ng-if="ctrl.error.unverifiedPayment">
<span class="icon-notification"> </span>
You need to <a href="https://www.freelancer.com/payments/verify.php" fl-gaf-link target="_blank" fl-analytics="GoToVerifyPayment">verify your payment source</a> before posting another project.
</span>
<span class="validation validation-error" ng-if="ctrl.error.negativeBalance">
<span class="icon-notification"> </span>
You have a negative balance. Please <a href="/deposit" fl-analytics="GoToMakeDeposit">add funds to your account</a> before posting a project.
</span>
<span class="validation validation-error" ng-if="ctrl.error.internalError">
<span class="icon-notification"> </span>
An internal error occurred: {{ ctrl.error.internalError }}
</span>
</div>
<fl-button type="submit" class="btn btn-primary post-project-button" fl-analytics="GoToPostProject" fl-analytics-label="FreeQuotes">Get Free Quotes</fl-button>
</fieldset>
</fl-form>
</div>
</section>
<!-- PAGE VIEW -->
<!-- Display on loading -->
<section class="post-project-loading scroll-container" ng-if="ctrl.state === 'success'">
<div class="section-inner">
<div class="first-project">
<div class="icon-roundy-square large-icon">
<span class="icon-file-powerpoint large-icon-inner"></span>
</div>
<p ng-if="ctrl.contestPostedLive">Your contest is now live! <a fl-gaf-link ng-href="https://www.freelancer.com/contest/contest.php?project_id={{ ctrl.project.id }}">Click here</a> to view it.</p>
<p ng-if="!ctrl.contestPostedLive && !ctrl.draftProjectPosted">Your draft contest has been successfully saved. <a fl-gaf-link ng-href="https://www.freelancer.com/contest/contest.php?project_id={{ ctrl.project.id }}">Click here</a> to view it.</p>
<p ng-if="!ctrl.contestPostedLive && ctrl.draftProjectPosted">Your draft contest has been successfully posted and is now online. <a fl-gaf-link ng-href="https://www.freelancer.com/dashboard/projects.php">Click here</a> to view your draft projects.</p>
</div>
</div>
</section>
<!-- Hireme modal -->
<aside class="modal bid-info-modal" ng-if="ctrl.showPaymentReleaseModal" fl-analytics-subsection="PostContestModal">
<div class="modal-inner">
<div class="modal-header">
<div class="section-inner">
<h2 class="modal-heading">Fund Contest</h2>
</div>
</div>
<div class="section-inner">
<p ng-if="!ctrl.repostContest">To start getting entries for your contest, please select Continue to make a payment</p>
<p ng-if="ctrl.repostContest">To start getting entries for your contest, please resolve the following:</p>
<div ng-if="ctrl.error.code">
<span class="validation validation-error" ng-if="ctrl.error.notVerified">
<span class="icon-notification"> </span>
You must first verify a payment method before posting a contest.
</span>
<span class="validation validation-error" ng-if="ctrl.error.notEnoughFunds">
<span class="icon-notification"> </span>
You do not have enough funds to publish this contest. Please <a href="/deposit?type=direct">deposit funds</a> first. <span ng-show="!ctrl.repostContest">You can save it as a draft instead.</span>
</span>
<span class="validation validation-error" ng-if="ctrl.error.duplicateContest">
<span class="icon-notification"> </span>
Duplicate project. You have already posted a project with this name.
</span>
<span class="validation validation-error" ng-if="ctrl.error.internalError">
<span class="icon-notification"> </span>
An internal error occurred: {{ ctrl.error.internalError }}
</span>
</div>
<fl-button class="btn btn-primary" action="ctrl.postContest(ctrl.project)" fl-analytics="PostContest" ng-if="!ctrl.error.notEnoughFunds && !ctrl.error.duplicateContest">Continue</fl-button>
<fl-button class="btn btn-primary" action="ctrl.postContest(ctrl.project, true)" fl-analytics="PostDraftContest" ng-if="ctrl.error.notEnoughFunds">Save as draft</fl-button>
<div class="modal-close">
<a ng-click="ctrl.showPaymentReleaseModal=false" fl-analytics="ClosePaymentReleaseModal">Cancel</a>
</div>
</div>
</div>
</aside>
</div>