Migrate public profile search
This commit is contained in:
parent
6e2a40e436
commit
415cbbf650
|
@ -1,78 +0,0 @@
|
|||
<template>
|
||||
<form class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<continent-list v-model="criteria.continentId" topLabel="Any" @update:modelValue="updateContinent" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" id="region" class="form-control form-control-sm" maxlength="1000"
|
||||
placeholder="(free-form text)" :value="criteria.region"
|
||||
@input="updateValue('region', $event.target.value)">
|
||||
<label for="region">Region</label>
|
||||
</div>
|
||||
<div class="form-text">(free-form text)</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-offset-md-2 col-lg-3 col-offset-lg-0">
|
||||
<label class="jjj-label">Seeking Remote Work?</label><br>
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" id="remoteNull" class="form-check-input" name="remoteWork"
|
||||
:checked="criteria.remoteWork === ''" @click="updateValue('remoteWork', '')">
|
||||
<label class="form-check-label" for="remoteNull">No Selection</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" id="remoteYes" class="form-check-input" name="remoteWork"
|
||||
:checked="criteria.remoteWork === 'yes'" @click="updateValue('remoteWork', 'yes')">
|
||||
<label class="form-check-label" for="remoteYes">Yes</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input type="radio" id="remoteNo" class="form-check-input" name="remoteWork"
|
||||
:checked="criteria.remoteWork === 'no'" @click="updateValue('remoteWork', 'no')">
|
||||
<label class="form-check-label" for="remoteNo">No</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-lg-3">
|
||||
<div class="form-floating">
|
||||
<input type="text" id="skillSearch" class="form-control form-control-sm" maxlength="1000"
|
||||
placeholder="(free-form text)" :value="criteria.skill"
|
||||
@input="updateValue('skill', $event.target.value)">
|
||||
<label for="skillSearch">Skill</label>
|
||||
</div>
|
||||
<div class="form-text">(free-form text)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<br>
|
||||
<button class="btn btn-outline-primary" type="submit" @click.prevent="$emit('search')">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import { PublicSearch } from "@/api"
|
||||
import ContinentList from "../ContinentList.vue"
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: PublicSearch
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "search") : void
|
||||
(e: "update:modelValue", value : PublicSearch) : void
|
||||
}>()
|
||||
|
||||
/** The initial search criteria passed; this is what we'll update and emit when data changes */
|
||||
const criteria = ref({ ...props.modelValue })
|
||||
|
||||
/** Emit a value update */
|
||||
const updateValue = (key : string, value : string) => {
|
||||
criteria.value = { ...criteria.value, [key]: value }
|
||||
emit("update:modelValue", criteria.value)
|
||||
}
|
||||
|
||||
/** Update the continent ID */
|
||||
const updateContinent = (c : string) => updateValue("continentId", c)
|
||||
</script>
|
|
@ -36,18 +36,6 @@ const routes: Array<RouteRecordRaw> = [
|
|||
component: () => import(/* webpackChunkName: "help" */ "../views/HowItWorks.vue"),
|
||||
meta: { auth: false, title: "How It Works" }
|
||||
},
|
||||
{
|
||||
path: "/privacy-policy",
|
||||
name: "PrivacyPolicy",
|
||||
component: () => import(/* webpackChunkName: "legal" */ "../views/PrivacyPolicy.vue"),
|
||||
meta: { auth: false, title: "Privacy Policy" }
|
||||
},
|
||||
{
|
||||
path: "/terms-of-service",
|
||||
name: "TermsOfService",
|
||||
component: () => import(/* webpackChunkName: "legal" */ "../views/TermsOfService.vue"),
|
||||
meta: { auth: false, title: "Terms of Service" }
|
||||
},
|
||||
// Citizen URLs
|
||||
{
|
||||
path: "/citizen/account",
|
||||
|
@ -86,13 +74,6 @@ const routes: Array<RouteRecordRaw> = [
|
|||
component: () => import(/* webpackChunkName: "joblist" */ "../views/listing/MyListings.vue"),
|
||||
meta: { auth: true, title: "My Job Listings" }
|
||||
},
|
||||
// Profile URLs
|
||||
{
|
||||
path: "/profile/seeking",
|
||||
name: "PublicSearchProfiles",
|
||||
component: () => import(/* webpackChunkName: "seeking" */ "../views/profile/Seeking.vue"),
|
||||
meta: { auth: false, title: "People Seeking Work" }
|
||||
},
|
||||
// "So Long" URLs
|
||||
{
|
||||
path: "/so-long/options",
|
||||
|
|
|
@ -1,430 +0,0 @@
|
|||
<template>
|
||||
<article>
|
||||
<h3>Privacy Policy</h3>
|
||||
<p class="fst-italic">(as of August 30<sup>th</sup>, 2021)</p>
|
||||
|
||||
<p>
|
||||
{{name}} (“we,” “our,” or “us”) is committed to protecting your privacy. This
|
||||
Privacy Policy explains how your personal information is collected, used, and disclosed by {{name}}.
|
||||
</p>
|
||||
<p>
|
||||
This Privacy Policy applies to our website, and its associated subdomains (collectively, our
|
||||
“Service”) alongside our application, {{name}}. By accessing or using our Service, you signify that
|
||||
you have read, understood, and agree to our collection, storage, use, and disclosure of your personal information
|
||||
as described in this Privacy Policy and our Terms of Service.
|
||||
</p>
|
||||
|
||||
<h4>Definitions and key terms</h4>
|
||||
<p>
|
||||
To help explain things as clearly as possible in this Privacy Policy, every time any of these terms are referenced,
|
||||
are strictly defined as:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Cookie: small amount of data generated by a website and saved by your web browser. It is used to identify your
|
||||
browser, provide analytics, remember information about you such as your language preference or login
|
||||
information.
|
||||
</li>
|
||||
<li>
|
||||
Company: when this policy mentions “Company,” “we,” “us,” or
|
||||
“our,” it refers to {{name}}, that is responsible for your information under this Privacy Policy.
|
||||
</li>
|
||||
<li>Country: where {{name}} or the owners/founders of {{name}} are based, in this case is US.</li>
|
||||
<li>
|
||||
Customer: refers to the company, organization or person that signs up to use the {{name}} Service to manage the
|
||||
relationships with your consumers or service users.
|
||||
</li>
|
||||
<li>
|
||||
Device: any internet connected device such as a phone, tablet, computer or any other device that can be used to
|
||||
visit {{name}} and use the services.
|
||||
</li>
|
||||
<li>
|
||||
IP address: Every device connected to the Internet is assigned a number known as an Internet protocol (IP)
|
||||
address. These numbers are usually assigned in geographic blocks. An IP address can often be used to identify
|
||||
the location from which a device is connecting to the Internet.
|
||||
</li>
|
||||
<li>
|
||||
Personnel: refers to those individuals who are employed by {{name}} or are under contract to perform a service
|
||||
on behalf of one of the parties.
|
||||
</li>
|
||||
<li>
|
||||
Personal Data: any information that directly, indirectly, or in connection with other information — including a
|
||||
personal identification number — allows for the identification or identifiability of a natural person.
|
||||
</li>
|
||||
<li>
|
||||
Service: refers to the service provided by {{name}} as described in the relative terms (if available) and on
|
||||
this platform.
|
||||
</li>
|
||||
<li>
|
||||
Third-party service: refers to advertisers, contest sponsors, promotional and marketing partners, and others who
|
||||
provide our content or whose products or services we think may interest you.
|
||||
</li>
|
||||
<li>
|
||||
Website: {{name}}’s site, which can be accessed via this URL:
|
||||
<router-link to="/">https://noagendacareers.com/</router-link>
|
||||
</li>
|
||||
<li>You: a person or entity that is registered with {{name}} to use the Services.</li>
|
||||
</ul>
|
||||
|
||||
<h4>What Information Do We Collect?</h4>
|
||||
<p>We collect information from you when you visit our website, register on our site, or fill out a form.</p>
|
||||
<ul>
|
||||
<li>Name / Username</li>
|
||||
<li>Coarse Geographic Location</li>
|
||||
<li>Employment History</li>
|
||||
<li>Job Listing Information</li>
|
||||
</ul>
|
||||
|
||||
<h4>How Do We Use The Information We Collect?</h4>
|
||||
<p>Any of the information we collect from you may be used in one of the following ways:</p>
|
||||
<ul>
|
||||
<li>To personalize your experience (your information helps us to better respond to your individual needs)</li>
|
||||
<li>
|
||||
To improve our website (we continually strive to improve our website offerings based on the information and
|
||||
feedback we receive from you)
|
||||
</li>
|
||||
<li>
|
||||
To improve customer service (your information helps us to more effectively respond to your customer service
|
||||
requests and support needs)
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>When does {{name}} use end user information from third parties?</h4>
|
||||
<p>{{name}} will collect End User Data necessary to provide the {{name}} services to our customers.</p>
|
||||
<p>
|
||||
End users may voluntarily provide us with information they have made available on social media websites. If you
|
||||
provide us with any such information, we may collect publicly available information from the social media websites
|
||||
you have indicated. You can control how much of your information social media websites make public by visiting
|
||||
these websites and changing your privacy settings.
|
||||
</p>
|
||||
|
||||
<h4>When does {{name}} use customer information from third parties?</h4>
|
||||
<p>We do not utilize third party information apart from the end-user data described above.</p>
|
||||
|
||||
<h4>Do we share the information we collect with third parties?</h4>
|
||||
<p>
|
||||
We may disclose personal and non-personal information about you to government or law enforcement officials or
|
||||
private parties as we, in our sole discretion, believe necessary or appropriate in order to respond to claims,
|
||||
legal process (including subpoenas), to protect our rights and interests or those of a third party, the safety of
|
||||
the public or any person, to prevent or stop any illegal, unethical, or legally actionable activity, or to
|
||||
otherwise comply with applicable court orders, laws, rules and regulations.
|
||||
</p>
|
||||
|
||||
<h4>Where and when is information collected from customers and end users?</h4>
|
||||
<p>
|
||||
{{name}} will collect personal information that you submit to us. We may also receive personal information about you
|
||||
from third parties as described above.
|
||||
</p>
|
||||
|
||||
<h4>How Do We Use Your E-mail Address?</h4>
|
||||
<p>
|
||||
{{name}} uses your e-mail address to identify you, along with your password, as an authorized user of this site.
|
||||
E-mail addresses are verified via a time-sensitive link, and may also be used to send password reset authorization
|
||||
codes. We do not display this e-mail address to users. If you choose to add an e-mail address as a contact type,
|
||||
that e-mail address will be visible to other authorized users.
|
||||
</p>
|
||||
|
||||
<h4>How Long Do We Keep Your Information?</h4>
|
||||
<p>
|
||||
We keep your information only so long as we need it to provide {{name}} to you and fulfill the purposes described
|
||||
in this policy. When we no longer need to use your information and there is no need for us to keep it to comply
|
||||
with our legal or regulatory obligations, we’ll either remove it from our systems or depersonalize it so that we
|
||||
can’t identify you.
|
||||
</p>
|
||||
|
||||
<h4>How Do We Protect Your Information?</h4>
|
||||
<p>
|
||||
We implement a variety of security measures to maintain the safety of your personal information when you enter,
|
||||
submit, or access your personal information. We mandate the use of a secure server. We cannot, however, ensure or
|
||||
warrant the absolute security of any information you transmit to {{name}} or guarantee that your information on
|
||||
the Service may not be accessed, disclosed, altered, or destroyed by a breach of any of our physical, technical,
|
||||
or managerial safeguards.
|
||||
</p>
|
||||
|
||||
<h4>Could my information be transferred to other countries?</h4>
|
||||
<p>
|
||||
{{name}} is hosted in the US. Information collected via our website may be viewed and hosted anywhere in the
|
||||
world, including countries that may not have laws of general applicability regulating the use and transfer of
|
||||
such data. To the fullest extent allowed by applicable law, by using any of the above, you voluntarily consent to
|
||||
the trans-border transfer and hosting of such information.
|
||||
</p>
|
||||
|
||||
<h4>Is the information collected through the {{name}} Service secure?</h4>
|
||||
<p>
|
||||
We take precautions to protect the security of your information. We have physical, electronic, and managerial
|
||||
procedures to help safeguard, prevent unauthorized access, maintain data security, and correctly use your
|
||||
information. However, neither people nor security systems are foolproof, including encryption systems. In
|
||||
addition, people can commit intentional crimes, make mistakes, or fail to follow policies. Therefore, while we
|
||||
use reasonable efforts to protect your personal information, we cannot guarantee its absolute security. If
|
||||
applicable law imposes any non-disclaimable duty to protect your personal information, you agree that intentional
|
||||
misconduct will be the standards used to measure our compliance with that duty.
|
||||
</p>
|
||||
|
||||
<h4>Can I update or correct my information?</h4>
|
||||
<p>
|
||||
The rights you have to request updates or corrections to the information {{name}} collects depend on your
|
||||
relationship with {{name}}.
|
||||
</p>
|
||||
<p>
|
||||
Customers have the right to request the restriction of certain uses and disclosures of personally identifiable
|
||||
information as follows. You can contact us in order to (1) update or correct your personally identifiable
|
||||
information, or (3) delete the personally identifiable information maintained about you on our systems (subject to
|
||||
the following paragraph), by cancelling your account. Such updates, corrections, changes and deletions will have
|
||||
no effect on other information that we maintain in accordance with this Privacy Policy prior to such update,
|
||||
correction, change, or deletion. You are responsible for maintaining the secrecy of your unique password and
|
||||
account information at all times.
|
||||
</p>
|
||||
<p>
|
||||
{{name}} also provides ways for users to modify or remove the information we have collected from them from the
|
||||
application; these actions will have the same effect as contacting us to modify or remove data.
|
||||
</p>
|
||||
<p>
|
||||
You should be aware that it is not technologically possible to remove each and every record of the information you
|
||||
have provided to us from our system. The need to back up our systems to protect information from inadvertent loss
|
||||
means that a copy of your information may exist in a non-erasable form that will be difficult or impossible for us
|
||||
to locate. Promptly after receiving your request, all personal information stored in databases we actively use,
|
||||
and other readily searchable media will be updated, corrected, changed, or deleted, as appropriate, as soon as and
|
||||
to the extent reasonably and technically practicable.
|
||||
</p>
|
||||
<p>
|
||||
If you are an end user and wish to update, delete, or receive any information we have about you, you may do so by
|
||||
contacting the organization of which you are a customer.
|
||||
</p>
|
||||
|
||||
<h4>Governing Law</h4>
|
||||
<p>
|
||||
This Privacy Policy is governed by the laws of US without regard to its conflict of laws provision. You consent to
|
||||
the exclusive jurisdiction of the courts in connection with any action or dispute arising between the parties
|
||||
under or in connection with this Privacy Policy except for those individuals who may have rights to make claims
|
||||
under Privacy Shield, or the Swiss-US framework.
|
||||
</p>
|
||||
<p>
|
||||
The laws of US, excluding its conflicts of law rules, shall govern this Agreement and your use of the website.
|
||||
Your use of the website may also be subject to other local, state, national, or international laws.
|
||||
</p>
|
||||
<p>
|
||||
By using {{name}} or contacting us directly, you signify your acceptance of this Privacy Policy. If you do not
|
||||
agree to this Privacy Policy, you should not engage with our website, or use our services. Continued use of the
|
||||
website, direct engagement with us, or following the posting of changes to this Privacy Policy that do not
|
||||
significantly affect the use or disclosure of your personal information will mean that you accept those changes.
|
||||
</p>
|
||||
|
||||
<h4>Your Consent</h4>
|
||||
<p>
|
||||
We’ve updated our Privacy Policy to provide you with complete transparency into what is being set when you
|
||||
visit our site and how it’s being used. By using our website, registering an account, or making a purchase,
|
||||
you hereby consent to our Privacy Policy and agree to its terms.
|
||||
</p>
|
||||
|
||||
<h4>Links to Other Websites</h4>
|
||||
<p>
|
||||
This Privacy Policy applies only to the Services. The Services may contain links to other websites not operated or
|
||||
controlled by {{name}}. We are not responsible for the content, accuracy or opinions expressed in such websites,
|
||||
and such websites are not investigated, monitored or checked for accuracy or completeness by us. Please remember
|
||||
that when you use a link to go from the Services to another website, our Privacy Policy is no longer in effect.
|
||||
Your browsing and interaction on any other website, including those that have a link on our platform, is subject
|
||||
to that website’s own rules and policies. Such third parties may use their own cookies or other methods to collect
|
||||
information about you.
|
||||
</p>
|
||||
|
||||
<h4>Cookies</h4>
|
||||
<p>{{name}} does not use Cookies.</p>
|
||||
|
||||
<h4>Kids’ Privacy</h4>
|
||||
<p>
|
||||
We do not address anyone under the age of 13. We do not knowingly collect personally identifiable information from
|
||||
anyone under the age of 13. If You are a parent or guardian and You are aware that Your child has provided Us with
|
||||
Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the
|
||||
age of 13 without verification of parental consent, We take steps to remove that information from Our servers.
|
||||
</p>
|
||||
|
||||
<h4>Changes To Our Privacy Policy</h4>
|
||||
<p>
|
||||
We may change our Service and policies, and we may need to make changes to this Privacy Policy so that they
|
||||
accurately reflect our Service and policies. Unless otherwise required by law, we will notify you (for example,
|
||||
through our Service) before we make changes to this Privacy Policy and give you an opportunity to review them
|
||||
before they go into effect. Then, if you continue to use the Service, you will be bound by the updated Privacy
|
||||
Policy. If you do not want to agree to this or any updated Privacy Policy, you can delete your account.
|
||||
</p>
|
||||
|
||||
<h4>Third-Party Services</h4>
|
||||
<p>
|
||||
We may display, include or make available third-party content (including data, information, applications and other
|
||||
products services) or provide links to third-party websites or services (“Third-Party Services”).
|
||||
</p>
|
||||
<p>
|
||||
You acknowledge and agree that {{name}} shall not be responsible for any Third-Party Services, including their
|
||||
accuracy, completeness, timeliness, validity, copyright compliance, legality, decency, quality or any other aspect
|
||||
thereof. {{name}} does not assume and shall not have any liability or responsibility to you or any other person or
|
||||
entity for any Third-Party Services.
|
||||
</p>
|
||||
<p>
|
||||
Third-Party Services and links thereto are provided solely as a convenience to you and you access and use them
|
||||
entirely at your own risk and subject to such third parties’ terms and conditions.
|
||||
</p>
|
||||
|
||||
<h4>Tracking Technologies</h4>
|
||||
<p>
|
||||
{{name}} does not use any tracking technologies. When a user signs in, a token is issued; that token is stored in
|
||||
the browser’s memory, and the Service uses it on each request for data. If the page is refreshed or the
|
||||
browser window/tab is closed, this token disappears, and a new one must be generated before the application can be
|
||||
used again.
|
||||
</p>
|
||||
|
||||
<h4>Information about General Data Protection Regulation (GDPR)</h4>
|
||||
<p>
|
||||
We may be collecting and using information from you if you are from the European Economic Area (EEA), and in this
|
||||
section of our Privacy Policy we are going to explain exactly how and why is this data collected, and how we
|
||||
maintain this data under protection from being replicated or used in the wrong way.
|
||||
</p>
|
||||
|
||||
<h5>What is GDPR?</h5>
|
||||
<p>
|
||||
GDPR is an EU-wide privacy and data protection law that regulates how EU residents’ data is protected by
|
||||
companies and enhances the control the EU residents have, over their personal data.
|
||||
</p>
|
||||
<p>
|
||||
The GDPR is relevant to any globally operating company and not just the EU-based businesses and EU residents. Our
|
||||
customers’ data is important irrespective of where they are located, which is why we have implemented GDPR
|
||||
controls as our baseline standard for all our operations worldwide.
|
||||
</p>
|
||||
|
||||
<h5>What is personal data?</h5>
|
||||
<p>
|
||||
Any data that relates to an identifiable or identified individual. GDPR covers a broad spectrum of information
|
||||
that could be used on its own, or in combination with other pieces of information, to identify a person. Personal
|
||||
data extends beyond a person’s name or email address. Some examples include financial information, political
|
||||
opinions, genetic data, biometric data, IP addresses, physical address, sexual orientation, and ethnicity.
|
||||
</p>
|
||||
<p>The Data Protection Principles include requirements such as:</p>
|
||||
<ul>
|
||||
<li>
|
||||
Personal data collected must be processed in a fair, legal, and transparent way and should only be used in a way
|
||||
that a person would reasonably expect.
|
||||
</li>
|
||||
<li>
|
||||
Personal data should only be collected to fulfil a specific purpose and it should only be used for that purpose.
|
||||
Organizations must specify why they need the personal data when they collect it.
|
||||
</li>
|
||||
<li>Personal data should be held no longer than necessary to fulfil its purpose.</li>
|
||||
<li>
|
||||
People covered by the GDPR have the right to access their own personal data. They can also request a copy of
|
||||
their data, and that their data be updated, deleted, restricted, or moved to another organization.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5>Why is GDPR important?</h5>
|
||||
<p>
|
||||
GDPR adds some new requirements regarding how companies should protect individuals’ personal data that they
|
||||
collect and process. It also raises the stakes for compliance by increasing enforcement and imposing greater fines
|
||||
for breach. Beyond these facts, it’s simply the right thing to do. At {{name}} we strongly believe that your
|
||||
data privacy is very important and we already have solid security and privacy practices in place that go beyond
|
||||
the requirements of this regulation.
|
||||
</p>
|
||||
|
||||
<h5>Individual Data Subject’s Rights - Data Access, Portability, and Deletion</h5>
|
||||
<p>
|
||||
We are committed to helping our customers meet the data subject rights requirements of GDPR. {{name}} processes or
|
||||
stores all personal data in fully vetted, DPA compliant vendors. We do store all conversation and personal data
|
||||
for up to 6 years unless your account is deleted. In which case, we dispose of all data in accordance with our
|
||||
Terms of Service and Privacy Policy, but we will not hold it longer than 60 days.
|
||||
</p>
|
||||
<p>
|
||||
We are aware that if you are working with EU customers, you need to be able to provide them with the ability to
|
||||
access, update, retrieve and remove personal data. We got you! We’ve been set up as self service from the
|
||||
start and have always given you access to your data. Our customer support team is here for you to answer any
|
||||
questions you might have about working with the API.
|
||||
</p>
|
||||
|
||||
<h4>California Residents</h4>
|
||||
<p>
|
||||
The California Consumer Privacy Act (CCPA) requires us to disclose categories of Personal Information we collect
|
||||
and how we use it, the categories of sources from whom we collect Personal Information, and the third parties with
|
||||
whom we share it, which we have explained above.
|
||||
</p>
|
||||
<p>
|
||||
We are also required to communicate information about rights California residents have under California law. You
|
||||
may exercise the following rights:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Right to Know and Access. You may submit a verifiable request for information regarding the: (1) categories of
|
||||
Personal Information we collect, use, or share; (2) purposes for which categories of Personal Information are
|
||||
collected or used by us; (3) categories of sources from which we collect Personal Information; and (4) specific
|
||||
pieces of Personal Information we have collected about you.
|
||||
</li>
|
||||
<li>Right to Equal Service. We will not discriminate against you if you exercise your privacy rights.</li>
|
||||
<li>
|
||||
Right to Delete. You may submit a verifiable request to close your account and we will delete Personal
|
||||
Information about you that we have collected.
|
||||
</li>
|
||||
<li>
|
||||
Request that a business that sells a consumer’s personal data, not sell the consumer’s personal
|
||||
data.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
If you make a request, we have one month to respond to you. If you would like to exercise any of these rights,
|
||||
please contact us.
|
||||
</p>
|
||||
<p>We do not sell the Personal Information of our users.</p>
|
||||
<p>For more information about these rights, please contact us.</p>
|
||||
|
||||
<h5>California Online Privacy Protection Act (CalOPPA)</h5>
|
||||
<p>
|
||||
CalOPPA requires us to disclose categories of Personal Information we collect and how we use it, the categories of
|
||||
sources from whom we collect Personal Information, and the third parties with whom we share it, which we have
|
||||
explained above.
|
||||
</p>
|
||||
<p>CalOPPA users have the following rights:</p>
|
||||
<ul>
|
||||
<li>
|
||||
Right to Know and Access. You may submit a verifiable request for information regarding the: (1) categories of
|
||||
Personal Information we collect, use, or share; (2) purposes for which categories of Personal Information are
|
||||
collected or used by us; (3) categories of sources from which we collect Personal Information; and (4) specific
|
||||
pieces of Personal Information we have collected about you.
|
||||
</li>
|
||||
<li>Right to Equal Service. We will not discriminate against you if you exercise your privacy rights.</li>
|
||||
<li>
|
||||
Right to Delete. You may submit a verifiable request to close your account and we will delete Personal
|
||||
Information about you that we have collected.
|
||||
</li>
|
||||
<li>
|
||||
Right to request that a business that sells a consumer’s personal data, not sell the consumer’s
|
||||
personal data.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
If you make a request, we have one month to respond to you. If you would like to exercise any of these rights,
|
||||
please contact us.
|
||||
</p>
|
||||
<p>We do not sell the Personal Information of our users.</p>
|
||||
<p>For more information about these rights, please contact us.</p>
|
||||
|
||||
<h4>Contact Us</h4>
|
||||
<p>Don’t hesitate to contact us if you have any questions.</p>
|
||||
<ul>
|
||||
<li>Via this Link: <router-link to="/how-it-works">https://noagendacareers.com/how-it-works</router-link></li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="fst-italic">
|
||||
Changes on August 30<sup>th</sup>, 2022
|
||||
</p>
|
||||
<ul>
|
||||
<li class="fst-italic">Removed references to Mastodon</li>
|
||||
<li class="fst-italic">Added references to job listings</li>
|
||||
<li class="fst-italic">Changed information regarding e-mail addresses</li>
|
||||
</ul>
|
||||
<p class="fst-italic">
|
||||
Change on September 6<sup>th</sup>, 2021 – replaced “No Agenda Social” with generic terms for
|
||||
any authorized Mastodon instance.
|
||||
</p>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/** The name of the application */
|
||||
const name = "Jobs, Jobs, Jobs"
|
||||
</script>
|
|
@ -1,44 +0,0 @@
|
|||
<template>
|
||||
<article>
|
||||
<h3>Terms of Service</h3>
|
||||
<p class="fst-italic">(as of August 30<sup>th</sup>, 2022)</p>
|
||||
<h4>Acceptance of Terms</h4>
|
||||
<p>
|
||||
By accessing this web site, you are agreeing to be bound by these Terms and Conditions, and that you are
|
||||
responsible to ensure that your use of this site complies with all applicable laws. Your continued use of this
|
||||
site implies your acceptance of these terms.
|
||||
</p>
|
||||
<h4>Description of Service and Registration</h4>
|
||||
<p>
|
||||
Jobs, Jobs, Jobs is a service that allows individuals to enter and amend employment profiles and job listings,
|
||||
restricting access to the details of these to other users of this site, unless the individual specifies that this
|
||||
information should be visible publicly. See our <router-link to="/privacy-policy">privacy policy</router-link> for
|
||||
details on the personal (user) information we maintain.
|
||||
</p>
|
||||
<h4>Liability</h4>
|
||||
<p>
|
||||
This service is provided “as is”, and no warranty (express or implied) exists. The service and its
|
||||
developers may not be held liable for any damages that may arise through the use of this service.
|
||||
</p>
|
||||
<h4>Updates to Terms</h4>
|
||||
<p>
|
||||
These terms and conditions may be updated at any time. When these terms are updated, users will be notified via a
|
||||
notice on the dashboard page. Additionally, the date at the top of this page will be updated, and any substantive
|
||||
updates will also be accompanied by a summary of those changes.
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
You may also wish to review our <router-link to="/privacy-policy">privacy policy</router-link> to learn how we
|
||||
handle your data.
|
||||
</p>
|
||||
<hr>
|
||||
<p class="fst-italic">
|
||||
Change on August 30<sup>th</sup>, 2022 – added references to job listings, removed references to Mastodon
|
||||
instances.
|
||||
</p>
|
||||
<p class="fst-italic">
|
||||
Change on September 6<sup>th</sup>, 2021 – replaced “No Agenda Social” with a list of all No
|
||||
Agenda-affiliated Mastodon instances.
|
||||
</p>
|
||||
</article>
|
||||
</template>
|
|
@ -1,126 +0,0 @@
|
|||
<template>
|
||||
<article>
|
||||
<h3 class="pb-3">People Seeking Work</h3>
|
||||
<p v-if="!searched">
|
||||
Enter one or more criteria to filter results, or just click “Search” to list all profiles.
|
||||
</p>
|
||||
<collapse-panel headerText="Search Criteria" :collapsed="isCollapsed" @toggle="toggleCollapse">
|
||||
<profile-public-search-form v-model="criteria" @search="doSearch" />
|
||||
</collapse-panel>
|
||||
<error-list :errors="errors">
|
||||
<p v-if="searching">Searching profiles…</p>
|
||||
<template v-else>
|
||||
<template v-if="results.length > 0">
|
||||
<p class="py-3">
|
||||
These profiles match your search criteria. To learn more about these people, join the merry band of human
|
||||
resources in the <a href="https://noagendashow.net" target="_blank" rel="noopener">No Agenda</a> tribe!
|
||||
</p>
|
||||
<table class="table table-sm table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Continent</th>
|
||||
<th class="text-center" scope="col">Region</th>
|
||||
<th class="text-center" scope="col">Remote?</th>
|
||||
<th class="text-center" scope="col">Skills</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(profile, idx) in results" :key="idx">
|
||||
<td>{{profile.continent}}</td>
|
||||
<td>{{profile.region}}</td>
|
||||
<td class="text-center">{{yesOrNo(profile.remoteWork)}}</td>
|
||||
<td><template v-for="(skill, idx) in profile.skills" :key="idx">{{skill}}<br></template></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
<p v-else-if="searched" class="pt-3">No results found for the specified criteria</p>
|
||||
</template>
|
||||
</error-list>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Ref, ref, watch } from "vue"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
import { yesOrNo } from "@/App.vue"
|
||||
import api, { PublicSearch, PublicSearchResult } from "@/api"
|
||||
import { queryValue } from "@/router"
|
||||
|
||||
import CollapsePanel from "@/components/CollapsePanel.vue"
|
||||
import ErrorList from "@/components/ErrorList.vue"
|
||||
import ProfilePublicSearchForm from "@/components/profile/PublicSearchForm.vue"
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
/** Whether a search has been performed */
|
||||
const searched = ref(false)
|
||||
|
||||
/** Indicates whether a request for matching profiles is in progress */
|
||||
const searching = ref(false)
|
||||
|
||||
/** Error messages encountered while searching for profiles */
|
||||
const errors : Ref<string[]> = ref([])
|
||||
|
||||
/** An empty set of search criteria */
|
||||
const emptyCriteria = {
|
||||
continentId: "",
|
||||
region: undefined,
|
||||
skill: undefined,
|
||||
remoteWork: ""
|
||||
}
|
||||
|
||||
/** The search criteria being built from the page */
|
||||
const criteria : Ref<PublicSearch> = ref(emptyCriteria)
|
||||
|
||||
/** The search results */
|
||||
const results : Ref<PublicSearchResult[]> = ref([])
|
||||
|
||||
/** Whether the search results are collapsed */
|
||||
const isCollapsed = ref(searched.value && results.value.length > 0)
|
||||
|
||||
/** Set up the page to match its requested state */
|
||||
const setUpPage = async () => {
|
||||
if (queryValue(route, "searched") === "true") {
|
||||
searched.value = true
|
||||
try {
|
||||
searching.value = true
|
||||
const contId = queryValue(route, "continentId")
|
||||
const searchParams : PublicSearch = {
|
||||
continentId: contId === "" ? undefined : contId,
|
||||
region: queryValue(route, "region"),
|
||||
skill: queryValue(route, "skill"),
|
||||
remoteWork: queryValue(route, "remoteWork") ?? ""
|
||||
}
|
||||
const searchResult = await api.profile.publicSearch(searchParams)
|
||||
if (typeof searchResult === "string") {
|
||||
errors.value.push(searchResult)
|
||||
} else if (searchResult === undefined) {
|
||||
errors.value.push(`The server returned a "Not Found" response (this should not happen)`)
|
||||
} else {
|
||||
results.value = searchResult
|
||||
searchParams.continentId = searchParams.continentId ?? ""
|
||||
criteria.value = searchParams
|
||||
}
|
||||
} finally {
|
||||
searching.value = false
|
||||
}
|
||||
isCollapsed.value = searched.value && results.value.length > 0
|
||||
} else {
|
||||
searched.value = false
|
||||
criteria.value = emptyCriteria
|
||||
errors.value = []
|
||||
results.value = []
|
||||
}
|
||||
}
|
||||
|
||||
/** Refresh the page when the query string changes */
|
||||
watch(() => route.query, setUpPage, { immediate: true })
|
||||
|
||||
/** Open and closed the search parameter panel */
|
||||
const toggleCollapse = (it : boolean) => { isCollapsed.value = it }
|
||||
|
||||
/** Execute a search */
|
||||
const doSearch = () => router.push({ query: { searched: "true", ...criteria.value } })
|
||||
</script>
|
|
@ -483,29 +483,29 @@ module Profiles =
|
|||
}
|
||||
|
||||
// Search profiles (public)
|
||||
let publicSearch (search : PublicSearch) =
|
||||
let publicSearch (search : PublicSearchForm) =
|
||||
let searches = [
|
||||
match search.ContinentId with
|
||||
| Some contId -> "p.data ->> 'continentId' = @continentId", [ "@continentId", Sql.string contId ]
|
||||
| None -> ()
|
||||
match search.Region with
|
||||
| Some region -> "p.data ->> 'region' ILIKE @region", [ "@region", like region ]
|
||||
| None -> ()
|
||||
if search.ContinentId <> "" then
|
||||
"p.data ->> 'continentId' = @continentId", [ "@continentId", Sql.string search.ContinentId ]
|
||||
if search.Region <> "" then
|
||||
"p.data ->> 'region' ILIKE @region", [ "@region", like search.Region ]
|
||||
if search.RemoteWork <> "" then
|
||||
"p.data ->> 'remoteWork' = @remote", [ "@remote", jsonBool (search.RemoteWork = "yes") ]
|
||||
match search.Skill with
|
||||
| Some skl ->
|
||||
"p.data -> 'skills' ->> 'description' ILIKE @description", [ "@description", like skl ]
|
||||
| None -> ()
|
||||
"p.data ->> 'isRemote' = @remote", [ "@remote", jsonBool (search.RemoteWork = "yes") ]
|
||||
if search.Skill <> "" then
|
||||
"EXISTS (
|
||||
SELECT 1 FROM jsonb_array_elements(p.data['skills']) x(elt)
|
||||
WHERE x ->> 'description' ILIKE @description)",
|
||||
[ "@description", like search.Skill ]
|
||||
]
|
||||
connection ()
|
||||
|> Sql.query $"
|
||||
SELECT p.*, c.data AS cont_data
|
||||
FROM {Table.Profile} p
|
||||
INNER JOIN {Table.Continent} c ON c.id = p.data ->> 'continentId'
|
||||
WHERE p.data ->> 'isPublic' = 'true'
|
||||
AND p.data ->> 'isLegacy' = 'false'
|
||||
WHERE p.data ->> 'isPubliclySearchable' = 'true'
|
||||
AND p.data ->> 'isLegacy' = 'false'
|
||||
{searchSql searches}"
|
||||
|> Sql.parameters (searches |> List.collect snd)
|
||||
|> Sql.executeAsync (fun row ->
|
||||
let profile = toDocument<Profile> row
|
||||
let continent = toDocumentFrom<Continent> "cont_data" row
|
||||
|
|
|
@ -218,31 +218,20 @@ type ProfileForView =
|
|||
|
||||
/// The parameters for a public job search
|
||||
[<CLIMutable>]
|
||||
type PublicSearch =
|
||||
type PublicSearchForm =
|
||||
{ /// Retrieve citizens from this continent
|
||||
ContinentId : string option
|
||||
ContinentId : string
|
||||
|
||||
/// Retrieve citizens from this region
|
||||
Region : string option
|
||||
Region : string
|
||||
|
||||
/// Text for a search within a citizen's skills
|
||||
Skill : string option
|
||||
Skill : string
|
||||
|
||||
/// Whether to retrieve citizens who do or do not want remote work
|
||||
RemoteWork : string
|
||||
}
|
||||
|
||||
/// Support functions for public searches
|
||||
module PublicSearch =
|
||||
/// Is the search empty?
|
||||
let isEmptySearch (search : PublicSearch) =
|
||||
[ search.ContinentId
|
||||
search.Region
|
||||
search.Skill
|
||||
if search.RemoteWork = "" then Some search.RemoteWork else None
|
||||
]
|
||||
|> List.exists Option.isSome
|
||||
|
||||
|
||||
/// A public profile search result
|
||||
type PublicSearchResult =
|
||||
|
|
|
@ -663,6 +663,22 @@ module Profile =
|
|||
return! Profile.search form continents (timeZone ctx) results |> render "Profile Search" next ctx
|
||||
}
|
||||
|
||||
// GET: /profile/seeking
|
||||
let seeking : HttpHandler = fun next ctx -> task {
|
||||
let! continents = Continents.all ()
|
||||
let form =
|
||||
match ctx.TryBindQueryString<PublicSearchForm> () with
|
||||
| Ok f -> f
|
||||
| Error _ -> { ContinentId = ""; Region = ""; RemoteWork = ""; Skill = "" }
|
||||
let! results = task {
|
||||
if string ctx.Request.Query["searched"] = "true" then
|
||||
let! it = Profiles.publicSearch form
|
||||
return Some it
|
||||
else return None
|
||||
}
|
||||
return! Profile.publicSearch form continents results |> render "Profile Search" next ctx
|
||||
}
|
||||
|
||||
// GET: /profile/[id]/view
|
||||
let view citizenId : HttpHandler = fun next ctx -> task {
|
||||
let citId = CitizenId.ofString citizenId
|
||||
|
@ -732,13 +748,6 @@ module ProfileApi =
|
|||
do! Profiles.deleteById (currentCitizenId ctx)
|
||||
return! ok next ctx
|
||||
}
|
||||
|
||||
// GET: /api/profile/public-search
|
||||
let publicSearch : HttpHandler = fun next ctx -> task {
|
||||
let search = ctx.BindQueryString<PublicSearch> ()
|
||||
let! results = Profiles.publicSearch search
|
||||
return! json results next ctx
|
||||
}
|
||||
|
||||
|
||||
/// Handlers for /api/success routes
|
||||
|
@ -815,6 +824,7 @@ let allEndpoints = [
|
|||
routef "/%s/view" Profile.view
|
||||
route "/edit" Profile.edit
|
||||
route "/search" Profile.search
|
||||
route "/seeking" Profile.seeking
|
||||
]
|
||||
POST [ route "/save" Profile.save ]
|
||||
]
|
||||
|
@ -848,8 +858,6 @@ let allEndpoints = [
|
|||
route "" ProfileApi.current
|
||||
route "/count" ProfileApi.count
|
||||
routef "/%O" ProfileApi.get
|
||||
routef "/%O/view" ProfileApi.view
|
||||
route "/public-search" ProfileApi.publicSearch
|
||||
]
|
||||
PATCH [ route "/employment-found" ProfileApi.employmentFound ]
|
||||
]
|
||||
|
|
|
@ -127,6 +127,90 @@ let edit (m : EditProfileViewModel) continents isNew citizenId csrf =
|
|||
]
|
||||
|
||||
|
||||
/// The public search page
|
||||
let publicSearch (m : PublicSearchForm) continents (results : PublicSearchResult list option) =
|
||||
article [] [
|
||||
h3 [ _class "pb-3" ] [ rawText "People Seeking Work" ]
|
||||
if Option.isNone results then
|
||||
p [] [
|
||||
rawText "Enter one or more criteria to filter results, or just click “Search” to list all "
|
||||
rawText "publicly searchable profiles."
|
||||
]
|
||||
collapsePanel "Search Criteria" [
|
||||
form [ _class "container"; _method "GET"; _action "/profile/seeking" ] [
|
||||
input [ _type "hidden"; _name "searched"; _value "true" ]
|
||||
div [ _class "row" ] [
|
||||
div [ _class "col-12 col-sm-6 col-md-4 col-lg-3" ] [
|
||||
continentList [] "ContinentId" continents (Some "Any") m.ContinentId false
|
||||
]
|
||||
div [ _class "col-12 col-sm-6 col-md-4 col-lg-3" ] [
|
||||
textBox [ _maxlength "1000" ] (nameof m.Region) m.Region "Region" false
|
||||
div [ _class "form-text" ] [ rawText "(free-form text)" ]
|
||||
]
|
||||
div [ _class "col-12 col-sm-6 col-offset-md-2 col-lg-3 col-offset-lg-0" ] [
|
||||
label [ _class "jjj-label" ] [ rawText "Seeking Remote Work?" ]; br []
|
||||
div [ _class "form-check form-check-inline" ] [
|
||||
input [ _type "radio"; _id "remoteNull"; _name (nameof m.RemoteWork); _value ""
|
||||
_class "form-check-input"; if m.RemoteWork = "" then _checked ]
|
||||
label [ _class "form-check-label"; _for "remoteNull" ] [ rawText "No Selection" ]
|
||||
]
|
||||
div [ _class "form-check form-check-inline" ] [
|
||||
input [ _type "radio"; _id "remoteYes"; _name (nameof m.RemoteWork); _value "yes"
|
||||
_class "form-check-input"; if m.RemoteWork = "yes" then _checked ]
|
||||
label [ _class "form-check-label"; _for "remoteYes" ] [ rawText "Yes" ]
|
||||
]
|
||||
div [ _class "form-check form-check-inline" ] [
|
||||
input [ _type "radio"; _id "remoteNo"; _name (nameof m.RemoteWork); _value "no"
|
||||
_class "form-check-input"; if m.RemoteWork = "no" then _checked ]
|
||||
label [ _class "form-check-label"; _for "remoteNo" ] [ rawText "No" ]
|
||||
]
|
||||
]
|
||||
div [ _class "col-12 col-sm-6 col-lg-3" ] [
|
||||
textBox [ _maxlength "1000" ] (nameof m.Skill) m.Skill "Skill" false
|
||||
div [ _class "form-text" ] [ rawText "(free-form text)" ]
|
||||
]
|
||||
]
|
||||
div [ _class "row" ] [
|
||||
div [ _class "col" ] [
|
||||
br []
|
||||
button [ _type "submit"; _class "btn btn-outline-primary" ] [ rawText "Search" ]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
match results with
|
||||
| Some r when List.isEmpty r -> p [ _class "pt-3" ] [ rawText "No results found for the specified criteria" ]
|
||||
| Some r ->
|
||||
p [ _class "py-3" ] [
|
||||
rawText "These profiles match your search criteria. To learn more about these people, join the merry "
|
||||
rawText "band of human resources in the "
|
||||
a [ _href "https://noagendashow.net"; _target "_blank"; _rel "noopener" ] [ rawText "No Agenda" ]
|
||||
rawText " tribe!"
|
||||
]
|
||||
table [ _class "table table-sm table-hover" ] [
|
||||
thead [] [
|
||||
tr [] [
|
||||
th [ _scope "col" ] [ rawText "Continent" ]
|
||||
th [ _scope "col"; _class "text-center" ] [ rawText "Region" ]
|
||||
th [ _scope "col"; _class "text-center" ] [ rawText "Remote?" ]
|
||||
th [ _scope "col"; _class "text-center" ] [ rawText "Skills" ]
|
||||
]
|
||||
]
|
||||
r |> List.map (fun profile ->
|
||||
tr [] [
|
||||
td [] [ str profile.Continent ]
|
||||
td [] [ str profile.Region ]
|
||||
td [ _class "text-center" ] [ rawText (yesOrNo profile.RemoteWork) ]
|
||||
profile.Skills
|
||||
|> List.collect (fun skill -> [ str skill; br [] ])
|
||||
|> td []
|
||||
])
|
||||
|> tbody []
|
||||
]
|
||||
| None -> ()
|
||||
]
|
||||
|
||||
|
||||
/// Logged-on search page
|
||||
let search (m : ProfileSearchForm) continents tz (results : ProfileSearchResult list option) =
|
||||
article [] [
|
||||
|
|
Loading…
Reference in New Issue
Block a user