DEV Community

Cover image for Latio Team: A community for tech hackers building together
Freddy González
Freddy González Subscriber

Posted on

Latio Team: A community for tech hackers building together

This is a submission for the Wix Studio Challenge: Community Edition.

My Community Platform

Latio Team is a community built for tech builders based in LATAM, it's a place to interact, learn, grow, and connect together while participating at hackathons. The community page includes the next features:

  1. A talent pool: members get their profile listed on a public page which aims to be seen by recruiters or other entrepreneurs.
  2. Job opportunities: a job board that showcases the latest remote jobs for our members (API provided by RemoteOK), members can see and apply to job posts within the community page.
  3. Hackathon Listings: the place to share and post new hackathon opportunities for our members.
  4. Connect: a space to talk with other members, post work updates, and also find new collaborators.
  5. Work Inquiries: each member profile features a contact button where recruiters can send them a message or ask for a work inquiry. Members then can see the received messages inside a custom listing page without having to expose their private details.

Demo

Project link: https://fredoist.wixstudio.io/latio-team

Homepage:
Image description

Talent Pool:
Image description

Job Board and Post
Image description
Image description

Hackathon Listings:
Image description

Connect:
Image description

Member Profile:
Image description

Work Inquiry form and listings:
Image description
Image description

Development Journey

Building with Wix's Studio and Velo API's was quite easy if you already know JavaScript.

All the documentation for Velo APIs is clear and very complete, also, the editor inside Wix Studio has some great autocomplete features which made very easy to use. Once you start building and testing the editor you understand how it works and you can implement new APIs quickly.

As an additional point, Wix's templates let you build a stunning website very fast, the design adapts to each new App for element you add which it's pretty cool since you don't need to touch anything else.

This is the code blocks for some of the features so you can replicate them:

Job postings

import { Permissions, webMethod } from "wix-web-module";
import { getJSON } from "wix-fetch";

const formatPrice = (p) =>
    new Intl.NumberFormat('en-US', {
        notation: 'compact',
        maximumFractionDigits: p < 1 ? 3 : 1,
    }).format(Number(p));

// GET call using getJSON
export const getJobs = webMethod(Permissions.Anyone, async () => {
    const response = await getJSON(
        "https://remoteok.com/api",
    );
    const jobs = response.slice(1).map(job => {
        job._id = job.id;
        job.salary_range = `\$ ${formatPrice(job.salary_min)}-${formatPrice(job.salary_max)}`
        job.company_logo = job.company_logo ? `https://remoteok.com/cdn-cgi/image/format=auto,fit=contain,width=100,height=100,quality=50/${job.company_logo}` : null;
        job.logo = job.logo ? `https://remoteok.com/cdn-cgi/image/format=auto,fit=contain,width=100,height=100,quality=50/${job.logo}` : null;
        job.image = job.company_logo ?? job.logo ?? `https://ui-avatars.com/api/?name=${job.company}`
        return job;
    })
    return jobs;
});
Enter fullscreen mode Exit fullscreen mode

Job page

import { ok, notFound, WixRouterSitemapEntry } from "wix-router";
import { getJobs } from "backend/fetch-jobs.web"

export async function job_Router(request) {

    // Get item name from URL request
    const slug = request.path[0];

    // Get the item data by name
    const jobs = await getJobs();
    const data = jobs.filter(job => job.slug === slug)

    if (data.length) {
        const job = data[0];

        // Define SEO tags 
        const seoData = {
            title: job.position,
            description: "This is a description of " + job.position + " page",
            noIndex: false,
            metaTags: [{
                "property": "og:title",
                "content": job.position
            }, ]
        };

        // Render item page 
        return ok("job-page", job, seoData);
    }

    // Return 404 if item is not found 
    return notFound();
}

export async function job_SiteMap(sitemapRequest) {
    const jobs = await getJobs()

    // Convert the data to site map entries
    const siteMapEntries = jobs.map((job) => {
        const data = job;
        const entry = new WixRouterSitemapEntry(job.slug);
        entry.pageName = "job-page"; // The name of the page in the Wix editor to render
        entry.url = "/job/" + job.slug; // Relative URL of the page
        entry.title = data.position; // For better SEO - Help Google
        return entry;
    });

    // Return the site map entries
    return siteMapEntries;
}
Enter fullscreen mode Exit fullscreen mode

Sending inquiries for any member

import { Permissions, webMethod } from "wix-web-module";
import wixData from "wix-data";

export const sendInquiry = webMethod(
    Permissions.Anyone,
    async (username, email, details, budget) => {
        const results = await wixData.query("Members/PrivateMembersData").eq('slug', username).find()
        const member = results.items.length > 0 ? results.items[0] : null;
        if(member) {
          const memberId = member._id;
          const result = await wixData.save("WorkInquiries", {
            recipientId: memberId,
            contactEmail: email,
            details,
            budget
          })
          if(result) {
            return true
          }
        }
        return false;
    }
);
Enter fullscreen mode Exit fullscreen mode

Fetching member inquiries

import { Permissions, webMethod } from "wix-web-module";
import { query } from "wix-data";
import { currentMember } from "wix-members-backend"

export const getInquiries = webMethod(
  Permissions.SiteMember, 
  async () => { 
    const member = await currentMember.getMember();
    const data = await query("WorkInquiries").eq('recipientId', member._id).find();

    return data.items;
  }
);

Enter fullscreen mode Exit fullscreen mode

Velo APIs

  1. wix-data: it is used to store, fetch, and render custom collections data and also member's data in public/private features.
  2. wix-fetch: job posts are provided by RemoteOK's API and these are fetched using Wix's fetching methods, then jobs are rendered into repeaters blocks.
  3. wix-router: job posts also are rendered into its own page for which Wix's router is used.
  4. wix-members-backend: it is used to link the inquiries form to a custom collection, once data is sent the memberId is retrieved using this API by matching the profile slug, it then is passed to the collection with the form data.
  5. wix-location-frontend and wix-window-frontend: these are simply used to get URL data such as the path or member slug.

Wix Apps

  1. Wix Members Area: used for user profiles and authentication.
  2. Wix Groups: used for the connect feature.
  3. Wix FAQ: to include a FAQ into the homepage.
  4. CMS: I used some CMS connections to display data inside pages.

Top comments (2)

Collapse
 
programmerraja profile image
Boopathi

This is a fantastic project! It's impressive how you leveraged Wix's Velo APIs to build such a robust community platform. I especially like the integration of RemoteOK's API for job postings.

Collapse
 
fredoist profile image
Freddy González

Thank you! I appreciate your feedback. It was fun to build it within 10 hours.