Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Fajrian Aidil Pratama

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ The site integrates with PICO SulTeng API:
- **Base URL**: `https://pico-api.banuacoder.com/api/v1`
- **Documentation**: `https://pico-api.banuacoder.com/swagger/index.html`
- **Health Check**: `https://pico-api.banuacoder.com/api/v1/health`
- **Source Code**: `https://github.com/banua-coder/pico-api-go`

## Available Scripts

Expand Down Expand Up @@ -154,9 +155,11 @@ pnpm run vue-tsc # Type check without emit

## License

This project is licensed under the ISC License.
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

---

**Created for PICO SulTeng API**
Banua Coders • Central Sulawesi COVID-19 Data API
[Banua Coder](https://banuacoder.com) • Central Sulawesi COVID-19 Data API

**Developer**: [Fajrian Aidil Pratama](https://github.com/ryanaidilp)
4 changes: 2 additions & 2 deletions public/api-down.html
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,13 @@ <h3 class="text-xl font-semibold text-gray-900 mb-4">Need immediate access?</h3>
</p>

<div class="flex flex-col sm:flex-row gap-4 justify-center items-center">
<a href="https://banuacoders.com"
<a href="https://banuacoder.com"
target="_blank"
class="inline-flex items-center px-6 py-3 bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white font-medium rounded-xl transition-all duration-300 shadow-lg hover:shadow-xl transform hover:-translate-y-1">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2-2v2m8 0V6a2 2 0 012 2v6a2 2 0 01-2 2H8a2 2 0 01-2-2V8a2 2 0 012-2h8z"></path>
</svg>
Contact Banua Coders
Contact Banua Coder
</a>

<a href="https://banuacoders.com/app/pico/"
Expand Down
59 changes: 59 additions & 0 deletions src/components/DataSources.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<template>
<div class="mt-16 md:mt-20 text-center">
<p class="text-sm font-medium text-gray-500 uppercase tracking-wide mb-6 md:mb-8">
{{ $t('dataSources.trustedBy') }}
</p>
<div
class="flex flex-wrap items-center justify-center gap-6 md:gap-8 lg:gap-12 opacity-60 hover:opacity-80 transition-opacity duration-300">
<div v-for="source in dataSources" :key="source.alt"
class="flex items-center justify-center h-12 w-28 md:w-32 grayscale hover:grayscale-0 transition-all duration-300 group">
<a :href="source.url" target="_blank" rel="noopener noreferrer"
class="flex w-full h-full items-center justify-center hover:scale-110 transition-transform duration-300"
:title="source.alt">
<img :src="source.image" :alt="source.alt" class="max-h-6 md:max-h-8 w-auto object-contain" loading="lazy">
</a>
</div>
</div>
</div>
</template>

<script setup lang="ts">
interface DataSource {
image: string
alt: string
url: string
}

const dataSources: DataSource[] = [
{
image: '/inacovid.webp',
alt: 'INACOVID-19',
url: 'https://covid19.go.id/peta-sebaran'
},
{
image: '/dinkes-sulteng.webp',
alt: 'Dinkes Sulteng',
url: 'https://dinkes.sultengprov.go.id/category/covid-19/'
},
{
image: '/sulteng-lawan-covid.webp',
alt: 'Sulteng Lawan COVID',
url: 'https://www.instagram.com/sultenglawancovid/'
},
{
image: '/detexi.webp',
alt: 'Detexi',
url: 'https://detexi.id'
},
{
image: '/banua-coder.webp',
alt: 'Banua Coder',
url: 'https://banuacoder.com'
},
{
image: '/ethical-hacker-indonesia.webp',
alt: 'Ethical Hacker Indonesia',
url: 'https://hack.co.id'
}
]
</script>
218 changes: 218 additions & 0 deletions src/components/Navigation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
<template>
<nav ref="navbar" class="fixed w-full top-0 z-50 transition-all duration-500 ease-out" :class="navbarClass">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<div class="flex items-center">
<div class="flex-shrink-0 flex items-center space-x-3">
<img src="/pico-api-logo.webp" alt="PICO API Logo" class="h-10 w-auto">
<router-link to="/" class="text-2xl font-bold gradient-text">PICO SulTeng</router-link>
</div>
</div>

<!-- Desktop Navigation -->
<div class="hidden md:block">
<div class="ml-10 flex items-baseline space-x-4">
<router-link
to="/"
class="text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium transition-colors"
:class="{ 'text-gray-900': $route.path === '/' }"
>
{{ t('nav.home') }}
</router-link>
<router-link
to="/docs"
class="text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium transition-colors"
:class="{ 'text-gray-900': $route.path === '/docs' }"
>
{{ t('nav.documentation') }}
</router-link>
<router-link
to="/api"
class="text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium transition-colors"
:class="{ 'text-gray-900': $route.path === '/api' }"
>
{{ t('nav.apiReference') }}
</router-link>
<a href="https://pico-api.banuacoder.com/api/v1" target="_blank" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md text-sm font-medium transition-colors">
{{ t('nav.liveApi') }}
</a>
<!-- Language Toggle -->
<div class="flex items-center space-x-2 ml-4">
<button
@click="toggleLanguage"
class="flex items-center space-x-2 px-3 py-2 rounded-lg border border-gray-200 hover:border-blue-300 transition-colors bg-white/80 backdrop-blur-sm"
>
<svg class="w-4 h-4 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"></path>
</svg>
<span class="text-sm font-medium text-gray-700">{{ locale === 'en' ? 'ID' : 'EN' }}</span>
</button>
</div>
</div>
</div>

<!-- Mobile menu button -->
<div class="md:hidden flex items-center space-x-2">
<!-- Language Toggle for Mobile -->
<button
@click="toggleLanguage"
class="flex items-center space-x-1 px-2 py-1.5 rounded-lg border border-gray-200 hover:border-blue-300 transition-colors bg-white/80 backdrop-blur-sm"
>
<svg class="w-3 h-3 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"></path>
</svg>
<span class="text-xs font-medium text-gray-700">{{ locale === 'en' ? 'ID' : 'EN' }}</span>
</button>

<!-- Hamburger button -->
<button
@click="toggleMobileMenu"
type="button"
class="inline-flex items-center justify-center p-2 rounded-md text-gray-600 hover:text-blue-600 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500 transition-colors"
:aria-expanded="mobileMenuOpen"
>
<span class="sr-only">Open main menu</span>
<!-- Hamburger icon -->
<svg
class="block h-5 w-5 transition-transform duration-200"
:class="{ 'rotate-90': mobileMenuOpen }"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
:d="mobileMenuOpen ? 'M6 18L18 6M6 6l12 12' : 'M4 6h16M4 12h16M4 18h16'"
/>
</svg>
</button>
</div>
</div>
</div>

<!-- Mobile menu overlay -->
<div
v-if="mobileMenuOpen"
class="fixed inset-0 z-40 bg-black bg-opacity-50 transition-opacity duration-200 md:hidden"
@click="closeMobileMenu"
></div>

<!-- Mobile menu -->
<div
class="fixed top-0 right-0 z-50 w-64 h-full bg-white shadow-lg transform transition-transform duration-300 ease-in-out md:hidden"
:class="mobileMenuOpen ? 'translate-x-0' : 'translate-x-full'"
>
<div class="p-6 pt-20">
<div class="space-y-4">
<router-link
to="/"
@click="closeMobileMenu"
class="block text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-base font-medium border-b border-gray-100 transition-colors"
:class="{ 'text-gray-900': $route.path === '/' }"
>
{{ t('nav.home') }}
</router-link>
<router-link
to="/docs"
@click="closeMobileMenu"
class="block text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-base font-medium border-b border-gray-100 transition-colors"
:class="{ 'text-gray-900': $route.path === '/docs' }"
>
{{ t('nav.documentation') }}
</router-link>
<router-link
to="/api"
@click="closeMobileMenu"
class="block text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-base font-medium border-b border-gray-100 transition-colors"
:class="{ 'text-gray-900': $route.path === '/api' }"
>
{{ t('nav.apiReference') }}
</router-link>
<a
href="https://pico-api.banuacoder.com/api/v1"
target="_blank"
@click="closeMobileMenu"
class="block bg-blue-600 hover:bg-blue-700 text-white px-4 py-3 rounded-lg text-base font-medium transition-colors text-center"
>
{{ t('nav.liveApi') }}
</a>
</div>
</div>
</div>
</nav>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n()

// Props for styling variants
interface Props {
variant?: 'transparent' | 'solid'
}

const props = withDefaults(defineProps<Props>(), {
variant: 'transparent'
})

// Navigation scroll behavior
const navbar = ref<HTMLElement | null>(null)
const scrollY = ref(0)
const isScrolled = ref(false)

// Mobile menu state
const mobileMenuOpen = ref(false)

const navbarClass = computed(() => {
if (props.variant === 'solid') {
return 'bg-white shadow-sm'
}

return isScrolled.value
? 'bg-white/95 backdrop-blur-lg shadow-lg border-b border-gray-200/50'
: 'bg-transparent'
})

// Scroll handler
const handleScroll = () => {
scrollY.value = window.scrollY
isScrolled.value = scrollY.value > 50
}

// Toggle language function
const toggleLanguage = () => {
const newLocale = locale.value === 'en' ? 'id' : 'en'
locale.value = newLocale
localStorage.setItem('pico-language', newLocale)
}

// Mobile menu functions
const toggleMobileMenu = () => {
mobileMenuOpen.value = !mobileMenuOpen.value
// Prevent body scroll when menu is open
document.body.style.overflow = mobileMenuOpen.value ? 'hidden' : 'auto'
}

const closeMobileMenu = () => {
mobileMenuOpen.value = false
document.body.style.overflow = 'auto'
}

onMounted(() => {
if (props.variant === 'transparent') {
window.addEventListener('scroll', handleScroll, { passive: true })
}
})

onUnmounted(() => {
if (props.variant === 'transparent') {
window.removeEventListener('scroll', handleScroll)
}
// Restore body scroll on component unmount
document.body.style.overflow = 'auto'
})
</script>
26 changes: 4 additions & 22 deletions src/views/ApiReference.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
<template>
<div class="min-h-screen bg-gray-50">
<!-- Navigation (same as home) -->
<nav class="bg-white shadow-sm sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<div class="flex items-center">
<router-link to="/" class="text-2xl font-bold gradient-text">PICO SulTeng</router-link>
</div>
<div class="hidden md:block">
<div class="ml-10 flex items-baseline space-x-4">
<router-link to="/" class="text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium">Home</router-link>
<router-link to="/docs" class="text-gray-600 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium">Documentation</router-link>
<router-link to="/api" class="text-gray-900 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium">API Reference</router-link>
<a href="https://pico-api.banuacoder.com/api/v1" target="_blank" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md text-sm font-medium transition-colors">
Live API
</a>
</div>
</div>
</div>
</div>
</nav>
<!-- Navigation -->
<Navigation variant="solid" />

<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 pt-20">
<div class="prose prose-lg max-w-none">
<h1>API Reference</h1>
<p class="lead">Complete API endpoint reference for PICO SulTeng</p>
Expand Down Expand Up @@ -50,5 +32,5 @@
</template>

<script setup lang="ts">
// API Reference page component
import Navigation from '@/components/Navigation.vue'
</script>
Loading