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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ temp/

# Claude Code specific
.claude
CLAUDE.md
CLAUDE.mdimage.png
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,4 @@ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file
**Created for PICO SulTeng API**
[Banua Coder](https://banuacoder.com) • Central Sulawesi COVID-19 Data API

**Developer**: [Fajrian Aidil Pratama](https://github.com/ryanaidilp)
**Developer**: [Fajrian Aidil Pratama](https://github.com/ryanaidilp)
Binary file added image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
},
"dependencies": {
"aos": "^2.3.4",
"katex": "^0.16.22",
"vue": "^3.5.21",
"vue-i18n": "^9.14.5",
"vue-i18n": "9",
"vue-router": "^4.5.1"
}
}
2 changes: 1 addition & 1 deletion postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ export default {
tailwindcss: {},
autoprefixer: {},
},
}
}
2 changes: 1 addition & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
#app {
min-height: 100vh;
}
</style>
</style>
2 changes: 1 addition & 1 deletion src/components/DataSources.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ const dataSources: DataSource[] = [
url: 'https://hack.co.id'
}
]
</script>
</script>
37 changes: 37 additions & 0 deletions src/components/MathFormula.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<span v-html="renderedMath" class="katex-formula"></span>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import katex from 'katex'
import 'katex/dist/katex.min.css'

interface Props {
formula: string
displayMode?: boolean
}

const props = withDefaults(defineProps<Props>(), {
displayMode: true
})

const renderedMath = computed(() => {
try {
return katex.renderToString(props.formula, {
displayMode: props.displayMode,
throwOnError: false
})
} catch (error) {
console.error('KaTeX rendering error:', error)
return props.formula
}
})
</script>

<style scoped>
.katex-formula {
display: block;
text-align: center;
}
</style>
2 changes: 1 addition & 1 deletion src/components/Navigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,4 @@ onUnmounted(() => {
// Restore body scroll on component unmount
document.body.style.overflow = 'auto'
})
</script>
</script>
66 changes: 66 additions & 0 deletions src/components/documentation/AuthenticationSection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<template>
<section v-show="isActive" id="authentication" class="mb-16">
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900 mb-4">{{ t('documentation.authentication.title') }}</h1>
<p class="text-lg text-gray-600">{{ t('documentation.authentication.subtitle') }}</p>
</div>

<div class="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
<div class="bg-gradient-to-r from-yellow-600 to-orange-600 px-8 py-6">
<h2 class="text-2xl font-bold text-white mb-2">{{ t('documentation.authentication.title') }}</h2>
<p class="text-yellow-100">{{ t('documentation.authentication.subtitle') }}</p>
</div>

<div class="p-8">
<div class="bg-green-50 border-l-4 border-green-400 p-6 mb-8">
<div class="flex items-center">
<svg class="w-6 h-6 text-green-400 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<div>
<h3 class="text-lg font-semibold text-green-800 mb-1">{{ t('documentation.authentication.noAuthRequired') }}</h3>
<p class="text-green-700">{{ t('documentation.authentication.noAuthDescription') }}</p>
</div>
</div>
</div>

<div class="grid md:grid-cols-2 gap-8">
<div class="bg-blue-50 rounded-xl p-6">
<h3 class="text-xl font-semibold text-gray-900 mb-4">{{ t('documentation.authentication.rateLimiting') }}</h3>
<ul class="space-y-2 text-gray-600">
<li v-for="(detail, index) in $tm('documentation.authentication.rateLimitDetails')" :key="index" class="flex items-center">
<svg class="w-4 h-4 text-blue-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
{{ detail }}
</li>
</ul>
</div>

<div class="bg-purple-50 rounded-xl p-6">
<h3 class="text-xl font-semibold text-gray-900 mb-4">{{ t('documentation.authentication.bestPractices') }}</h3>
<ul class="space-y-2 text-gray-600">
<li v-for="(practice, index) in $tm('documentation.authentication.practiceDetails')" :key="index" class="flex items-center">
<svg class="w-4 h-4 text-purple-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4"></path>
</svg>
{{ practice }}
</li>
</ul>
</div>
</div>
</div>
</div>
</section>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'

interface Props {
isActive: boolean
}

defineProps<Props>()
const { t, tm: $tm } = useI18n()
</script>
122 changes: 122 additions & 0 deletions src/components/documentation/ErrorHandlingSection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<template>
<section v-show="isActive" id="error-handling" class="mb-16">
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900 mb-4">{{ t('documentation.errorHandling.title') }}</h1>
<p class="text-lg text-gray-600">{{ t('documentation.errorHandling.subtitle') }}</p>
</div>

<div class="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
<div class="bg-gradient-to-r from-red-600 to-rose-600 px-8 py-6">
<h2 class="text-2xl font-bold text-white mb-2">{{ t('documentation.errorHandling.title') }}</h2>
<p class="text-red-100">{{ t('documentation.errorHandling.subtitle') }}</p>
</div>

<div class="p-8">
<!-- Status Codes -->
<div class="mb-8">
<h3 class="text-xl font-semibold text-gray-900 mb-4">{{ t('documentation.errorHandling.httpStatusCodes') }}</h3>
<div class="grid gap-4">
<div class="flex items-center p-4 bg-green-50 border border-green-200 rounded-lg">
<div class="w-16 h-8 bg-green-500 text-white text-sm font-bold rounded flex items-center justify-center mr-4">200</div>
<div>
<div class="font-semibold text-gray-900">{{ t('documentation.errorHandling.statusCodes.200.title') }}</div>
<div class="text-sm text-gray-600">{{ t('documentation.errorHandling.statusCodes.200.description') }}</div>
</div>
</div>

<div class="flex items-center p-4 bg-red-50 border border-red-200 rounded-lg">
<div class="w-16 h-8 bg-red-500 text-white text-sm font-bold rounded flex items-center justify-center mr-4">400</div>
<div>
<div class="font-semibold text-gray-900">{{ t('documentation.errorHandling.statusCodes.400.title') }}</div>
<div class="text-sm text-gray-600">{{ t('documentation.errorHandling.statusCodes.400.description') }}</div>
</div>
</div>

<div class="flex items-center p-4 bg-red-50 border border-red-200 rounded-lg">
<div class="w-16 h-8 bg-red-500 text-white text-sm font-bold rounded flex items-center justify-center mr-4">404</div>
<div>
<div class="font-semibold text-gray-900">{{ t('documentation.errorHandling.statusCodes.404.title') }}</div>
<div class="text-sm text-gray-600">{{ t('documentation.errorHandling.statusCodes.404.description') }}</div>
</div>
</div>

<div class="flex items-center p-4 bg-yellow-50 border border-yellow-200 rounded-lg">
<div class="w-16 h-8 bg-yellow-500 text-white text-sm font-bold rounded flex items-center justify-center mr-4">429</div>
<div>
<div class="font-semibold text-gray-900">{{ t('documentation.errorHandling.statusCodes.429.title') }}</div>
<div class="text-sm text-gray-600">{{ t('documentation.errorHandling.statusCodes.429.description') }}</div>
</div>
</div>

<div class="flex items-center p-4 bg-red-50 border border-red-200 rounded-lg">
<div class="w-16 h-8 bg-red-600 text-white text-sm font-bold rounded flex items-center justify-center mr-4">500</div>
<div>
<div class="font-semibold text-gray-900">{{ t('documentation.errorHandling.statusCodes.500.title') }}</div>
<div class="text-sm text-gray-600">{{ t('documentation.errorHandling.statusCodes.500.description') }}</div>
</div>
</div>
</div>
</div>

<!-- Error Response Format -->
<div>
<h3 class="text-xl font-semibold text-gray-900 mb-4">{{ t('documentation.errorHandling.errorResponseFormat') }}</h3>
<div class="bg-gray-50 rounded-xl p-6">
<div class="grid lg:grid-cols-2 gap-6">
<div>
<h4 class="font-semibold text-gray-900 mb-3">{{ t('documentation.errorHandling.errorResponse') }}</h4>
<div class="bg-gray-900 rounded-lg p-4 font-mono text-sm">
<div class="text-blue-400">{</div>
<div class="ml-2">
<div><span class="text-yellow-400">"status"</span>: <span class="text-red-300">"error"</span>,</div>
<div><span class="text-yellow-400">"error"</span>: {</div>
<div class="ml-2">
<div><span class="text-yellow-400">"code"</span>: <span class="text-orange-400">400</span>,</div>
<div><span class="text-yellow-400">"message"</span>: <span class="text-green-300">"Invalid page parameter"</span>,</div>
<div><span class="text-yellow-400">"details"</span>: <span class="text-green-300">"Page must be a positive integer"</span></div>
</div>
<div>}</div>
</div>
<div class="text-blue-400">}</div>
</div>
</div>

<div>
<h4 class="font-semibold text-gray-900 mb-3">{{ t('documentation.errorHandling.errorFields') }}</h4>
<div class="space-y-3 text-sm">
<div class="flex">
<code class="bg-white px-2 py-1 rounded text-blue-600 mr-3 font-mono">status</code>
<span class="text-gray-600">{{ t('documentation.errorHandling.fieldDescriptions.status') }}</span>
</div>
<div class="flex">
<code class="bg-white px-2 py-1 rounded text-blue-600 mr-3 font-mono">code</code>
<span class="text-gray-600">{{ t('documentation.errorHandling.fieldDescriptions.code') }}</span>
</div>
<div class="flex">
<code class="bg-white px-2 py-1 rounded text-blue-600 mr-3 font-mono">message</code>
<span class="text-gray-600">{{ t('documentation.errorHandling.fieldDescriptions.message') }}</span>
</div>
<div class="flex">
<code class="bg-white px-2 py-1 rounded text-blue-600 mr-3 font-mono">details</code>
<span class="text-gray-600">{{ t('documentation.errorHandling.fieldDescriptions.details') }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'

interface Props {
isActive: boolean
}

defineProps<Props>()
const { t } = useI18n()
</script>
Loading