UNPKG

gaf-mobile

Version:

GAF mobile Web site

375 lines (354 loc) 30.3 kB
<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>