153 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
---
 | 
						|
import { Icon } from 'astro-icon/components';
 | 
						|
import { readItems } from '@directus/sdk';
 | 
						|
 | 
						|
import type { Experience } from '@lib/directusTypes';
 | 
						|
 | 
						|
import directus from '@lib/directus';
 | 
						|
 | 
						|
const experiences = await directus.request(
 | 
						|
  readItems('site_experience', {
 | 
						|
    fields: ['*'],
 | 
						|
    sort: ['-endDate'],
 | 
						|
  })
 | 
						|
);
 | 
						|
---
 | 
						|
 | 
						|
<section 
 | 
						|
  class:list={['flex flex-col gap-4', Astro.props.className]}
 | 
						|
 | 
						|
>
 | 
						|
  <h3 class="relative smooth-reveal-1 flex w-full items-center gap-3 pb-10 text-5xl text-neutral-800 dark:text-neutral-200">Experience</h3>
 | 
						|
  <ul class="ml-8 w-full flex flex-col">
 | 
						|
    {
 | 
						|
      experiences.map(
 | 
						|
        (experience: Experience) => {
 | 
						|
          const startYear = new Date(experience.startDate).getFullYear();
 | 
						|
          const endYear = experience.endDate != null ? new Date(experience.endDate).getFullYear() : 'Present';
 | 
						|
 | 
						|
          return (
 | 
						|
            <li class="relative">
 | 
						|
              <div class="group smooth-reveal-2 relative grid pb-1 transition-all sm:grid-cols-18 sm:gap-8 md:gap-6 lg:hover:!opacity-100">
 | 
						|
                <header class="relative mt-1 text-lg font-semibold sm:col-span-3 text-neutral-800 dark:text-neutral-200">
 | 
						|
                  <time datetime={experience.startDate} data-title={experience.startDate}>
 | 
						|
                    {startYear}
 | 
						|
                  </time>{' '}
 | 
						|
                  -{' '}
 | 
						|
                  <time datetime={experience.endDate} data-title={experience.endDate}>
 | 
						|
                    {endYear}
 | 
						|
                  </time>
 | 
						|
                </header>
 | 
						|
                <div class="relative flex flex-col pb-6 before:absolute before:mt-8 before:-ml-6 before:h-full before:w-px before:bg-stone-400 sm:col-span-12">
 | 
						|
                  <div class="absolute mt-4 h-2 w-2 -translate-x-[1.71rem] rounded-full bg-stone-400" />
 | 
						|
                  <h3>
 | 
						|
                    <div
 | 
						|
                      class="inline-flex items-center text-2xl leading-tight font-semibold"
 | 
						|
                      aria-label="{position} - {company}"
 | 
						|
                    >
 | 
						|
                      <span class="text-neutral-800 dark:text-neutral-200">
 | 
						|
                        {experience.position} <span>@</span>
 | 
						|
                        {experience.url ? (
 | 
						|
                          <a
 | 
						|
                            class="hover:text-steel dark:hover:text-bermuda"
 | 
						|
                            href={experience.url}
 | 
						|
                            title={`Ver ${experience.name}`}
 | 
						|
                            target="_blank"
 | 
						|
                          >
 | 
						|
                            {experience.name}
 | 
						|
                          </a>
 | 
						|
                        ) : (
 | 
						|
                          <span>{experience.name}</span>
 | 
						|
                        )}
 | 
						|
                      </span>
 | 
						|
                    </div>
 | 
						|
                  </h3>
 | 
						|
                  {(experience.location || experience.location_type) && (
 | 
						|
                    <div class="text-sm text-neutral-600 dark:text-neutral-400">
 | 
						|
                      {experience.location} {experience.location && experience.location_type && '-'} {experience.location_type}
 | 
						|
                    </div>
 | 
						|
                  )}
 | 
						|
                  <div class="text-md mt-4 flex flex-col gap-4" x-data="{ expanded: false }">
 | 
						|
                    {experience.summary && (
 | 
						|
                      <div class="flex flex-col gap-1">
 | 
						|
                        <h4 class="font-semibold text-neutral-800 dark:text-neutral-200">Summary:</h4>
 | 
						|
                        <ul class="flex list-disc flex-col gap-2 text-neutral-700 dark:text-neutral-400 [&>li]:ml-4">
 | 
						|
                          {Array.isArray(experience.summary) ? (
 | 
						|
                            experience.summary.map((item) => ({ item }))
 | 
						|
                          ) : (
 | 
						|
                            <li class="marker:text-steel dark:marker:text-bermuda">{experience.summary}</li>
 | 
						|
                          )}
 | 
						|
                        </ul>
 | 
						|
                      </div>
 | 
						|
                    )}
 | 
						|
 | 
						|
                    {(experience.responsibilities || experience.achievements) &&  (
 | 
						|
                      <div class="relative flex flex-col gap-4 max-sm:!h-auto md:after:absolute md:after:bottom-0 md:after:h-12 md:after:w-full md:after:bg-gradient-to-t md:after:from-neutral-200 dark:md:after:from-stone-700 md:after:content-[''] " :class="expanded ? 'after:hidden' : ''" x-show="expanded" x-collapse.min.50px>
 | 
						|
                      {experience.responsibilities && (
 | 
						|
                        <div class="flex flex-col gap-1">
 | 
						|
                          <h4 class="font-semibold text-neutral-800 dark:text-neutral-200">Responsibilities:</h4>
 | 
						|
                          <ul class="text-neutral-700 dark:text-neutral-400 [&>li]:ml-4 flex list-disc flex-col gap-2">
 | 
						|
                            {experience.responsibilities.map(responsibility => (
 | 
						|
                              <li class="marker:text-steel dark:marker:text-bermuda">{responsibility}</li>
 | 
						|
                            ))}
 | 
						|
                          </ul>
 | 
						|
                        </div>
 | 
						|
                      )}
 | 
						|
 | 
						|
                      {experience.achievements && (
 | 
						|
                        <div class="flex flex-col gap-1">
 | 
						|
                          <h4 class="font-semibold text-neutral-800 dark:text-neutral-200">Achievements:</h4>
 | 
						|
                          <ul class="text-neutral-700 dark:text-neutral-400 [&>li]:ml-4 flex list-disc flex-col gap-2">
 | 
						|
                            {experience.achievements.map(achievement => (
 | 
						|
                              <li class="marker:text-steel dark:marker:text-bermuda">{achievement}</li>
 | 
						|
                            ))}
 | 
						|
                          </ul>
 | 
						|
                        </div>
 | 
						|
                      )}
 | 
						|
                      </div>
 | 
						|
                      
 | 
						|
                      <button @click="expanded = ! expanded" class="group/more w-fit cursor-pointer items-center justify-center gap-1.5 text-xs underline text-neutral-700 dark:text-neutral-300 hover:text-neutral-900 dark:hover:text-neutral-400 transition-all flex">
 | 
						|
                        <span x-text="expanded ? 'Show less' : 'Show more'">Show more</span>
 | 
						|
                        <svg
 | 
						|
                          class="h-4 w-4 duration-200 ease-out group-hover/more:translate-y-0.5"
 | 
						|
                          :class="{ 'rotate-180': expanded }"
 | 
						|
                          viewBox="0 0 24 24"
 | 
						|
                          xmlns="http://www.w3.org/2000/svg"
 | 
						|
                          fill="none"
 | 
						|
                          stroke="currentColor"
 | 
						|
                          stroke-width="2"
 | 
						|
                          stroke-linecap="round"
 | 
						|
                          stroke-linejoin="round"
 | 
						|
                        >
 | 
						|
                          <polyline points="6 9 12 15 18 9" />
 | 
						|
                        </svg>
 | 
						|
                      </button>
 | 
						|
 | 
						|
                      <ul class="flex print:hidden flex-wrap gap-2" aria-label="Technologies used">
 | 
						|
                        {experience.skills && experience.skills.map(skill => {
 | 
						|
                          const iconName = skill.toLowerCase();
 | 
						|
                          return (
 | 
						|
                            <li class="bg-steel/20 border-steel/20 text-neutral-800 dark:bg-bermuda/20 dark:border-bermuda/20 dark:text-neutral-200 flex gap-1 items-center border-solid  border rounded-md px-2 py-0.5 text-xs">
 | 
						|
                              <Icon name={`mdi:${iconName}`} /> <span>{skill}</span>
 | 
						|
                            </li>
 | 
						|
                          )
 | 
						|
                        })}
 | 
						|
                      </ul>
 | 
						|
                    )}
 | 
						|
                  </div>
 | 
						|
                </div>
 | 
						|
              </div>
 | 
						|
            </li>
 | 
						|
          );
 | 
						|
        }
 | 
						|
      )
 | 
						|
    }
 | 
						|
  </ul>
 | 
						|
</section>
 | 
						|
 | 
						|
<!-- Alpine Plugins -->
 | 
						|
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/collapse@3.x.x/dist/cdn.min.js"></script>
 | 
						|
 | 
						|
<!-- Alpine Core -->
 | 
						|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 |