mirror of
https://github.com/shaulascr/ecommerce_serang.git
synced 2025-08-13 10:42:21 +00:00
Merge branch 'master' into gracia
This commit is contained in:
26
.idea/appInsightsSettings.xml
generated
Normal file
26
.idea/appInsightsSettings.xml
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AppInsightsSettings">
|
||||||
|
<option name="tabSettings">
|
||||||
|
<map>
|
||||||
|
<entry key="Firebase Crashlytics">
|
||||||
|
<value>
|
||||||
|
<InsightsFilterSettings>
|
||||||
|
<option name="connection">
|
||||||
|
<ConnectionSetting>
|
||||||
|
<option name="appId" value="PLACEHOLDER" />
|
||||||
|
<option name="mobileSdkAppId" value="" />
|
||||||
|
<option name="projectId" value="" />
|
||||||
|
<option name="projectNumber" value="" />
|
||||||
|
</ConnectionSetting>
|
||||||
|
</option>
|
||||||
|
<option name="signal" value="SIGNAL_UNSPECIFIED" />
|
||||||
|
<option name="timeIntervalDays" value="THIRTY_DAYS" />
|
||||||
|
<option name="visibilityType" value="ALL" />
|
||||||
|
</InsightsFilterSettings>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
395
.idea/other.xml
generated
Normal file
395
.idea/other.xml
generated
Normal file
@ -0,0 +1,395 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="direct_access_persist.xml">
|
||||||
|
<option name="deviceSelectionList">
|
||||||
|
<list>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="27" />
|
||||||
|
<option name="brand" value="DOCOMO" />
|
||||||
|
<option name="codename" value="F01L" />
|
||||||
|
<option name="id" value="F01L" />
|
||||||
|
<option name="manufacturer" value="FUJITSU" />
|
||||||
|
<option name="name" value="F-01L" />
|
||||||
|
<option name="screenDensity" value="360" />
|
||||||
|
<option name="screenX" value="720" />
|
||||||
|
<option name="screenY" value="1280" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="OPPO" />
|
||||||
|
<option name="codename" value="OP573DL1" />
|
||||||
|
<option name="id" value="OP573DL1" />
|
||||||
|
<option name="manufacturer" value="OPPO" />
|
||||||
|
<option name="name" value="CPH2557" />
|
||||||
|
<option name="screenDensity" value="480" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2400" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="28" />
|
||||||
|
<option name="brand" value="DOCOMO" />
|
||||||
|
<option name="codename" value="SH-01L" />
|
||||||
|
<option name="id" value="SH-01L" />
|
||||||
|
<option name="manufacturer" value="SHARP" />
|
||||||
|
<option name="name" value="AQUOS sense2 SH-01L" />
|
||||||
|
<option name="screenDensity" value="480" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2160" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="Lenovo" />
|
||||||
|
<option name="codename" value="TB370FU" />
|
||||||
|
<option name="id" value="TB370FU" />
|
||||||
|
<option name="manufacturer" value="Lenovo" />
|
||||||
|
<option name="name" value="Tab P12" />
|
||||||
|
<option name="screenDensity" value="340" />
|
||||||
|
<option name="screenX" value="1840" />
|
||||||
|
<option name="screenY" value="2944" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="31" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="a51" />
|
||||||
|
<option name="id" value="a51" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy A51" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2400" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="akita" />
|
||||||
|
<option name="id" value="akita" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 8a" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2400" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="b0q" />
|
||||||
|
<option name="id" value="b0q" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy S22 Ultra" />
|
||||||
|
<option name="screenDensity" value="600" />
|
||||||
|
<option name="screenX" value="1440" />
|
||||||
|
<option name="screenY" value="3088" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="32" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="bluejay" />
|
||||||
|
<option name="id" value="bluejay" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 6a" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2400" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="caiman" />
|
||||||
|
<option name="id" value="caiman" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 9 Pro" />
|
||||||
|
<option name="screenDensity" value="360" />
|
||||||
|
<option name="screenX" value="960" />
|
||||||
|
<option name="screenY" value="2142" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="comet" />
|
||||||
|
<option name="id" value="comet" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 9 Pro Fold" />
|
||||||
|
<option name="screenDensity" value="390" />
|
||||||
|
<option name="screenX" value="2076" />
|
||||||
|
<option name="screenY" value="2152" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="29" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="crownqlteue" />
|
||||||
|
<option name="id" value="crownqlteue" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy Note9" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="2220" />
|
||||||
|
<option name="screenY" value="1080" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="dm2q" />
|
||||||
|
<option name="id" value="dm2q" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="S23 Plus" />
|
||||||
|
<option name="screenDensity" value="450" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2340" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="dm3q" />
|
||||||
|
<option name="id" value="dm3q" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy S23 Ultra" />
|
||||||
|
<option name="screenDensity" value="600" />
|
||||||
|
<option name="screenX" value="1440" />
|
||||||
|
<option name="screenY" value="3088" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="e1q" />
|
||||||
|
<option name="id" value="e1q" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy S24" />
|
||||||
|
<option name="screenDensity" value="480" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2340" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="e3q" />
|
||||||
|
<option name="id" value="e3q" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy S24 Ultra" />
|
||||||
|
<option name="screenDensity" value="450" />
|
||||||
|
<option name="screenX" value="1440" />
|
||||||
|
<option name="screenY" value="3120" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="eos" />
|
||||||
|
<option name="id" value="eos" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Eos" />
|
||||||
|
<option name="screenDensity" value="320" />
|
||||||
|
<option name="screenX" value="384" />
|
||||||
|
<option name="screenY" value="384" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="felix" />
|
||||||
|
<option name="id" value="felix" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel Fold" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="2208" />
|
||||||
|
<option name="screenY" value="1840" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="felix" />
|
||||||
|
<option name="id" value="felix" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel Fold" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="2208" />
|
||||||
|
<option name="screenY" value="1840" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="felix_camera" />
|
||||||
|
<option name="id" value="felix_camera" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel Fold (Camera-enabled)" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="2208" />
|
||||||
|
<option name="screenY" value="1840" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="motorola" />
|
||||||
|
<option name="codename" value="fogona" />
|
||||||
|
<option name="id" value="fogona" />
|
||||||
|
<option name="manufacturer" value="Motorola" />
|
||||||
|
<option name="name" value="moto g play - 2024" />
|
||||||
|
<option name="screenDensity" value="280" />
|
||||||
|
<option name="screenX" value="720" />
|
||||||
|
<option name="screenY" value="1600" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="gts8uwifi" />
|
||||||
|
<option name="id" value="gts8uwifi" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy Tab S8 Ultra" />
|
||||||
|
<option name="screenDensity" value="320" />
|
||||||
|
<option name="screenX" value="1848" />
|
||||||
|
<option name="screenY" value="2960" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="husky" />
|
||||||
|
<option name="id" value="husky" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 8 Pro" />
|
||||||
|
<option name="screenDensity" value="390" />
|
||||||
|
<option name="screenX" value="1008" />
|
||||||
|
<option name="screenY" value="2244" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="30" />
|
||||||
|
<option name="brand" value="motorola" />
|
||||||
|
<option name="codename" value="java" />
|
||||||
|
<option name="id" value="java" />
|
||||||
|
<option name="manufacturer" value="Motorola" />
|
||||||
|
<option name="name" value="G20" />
|
||||||
|
<option name="screenDensity" value="280" />
|
||||||
|
<option name="screenX" value="720" />
|
||||||
|
<option name="screenY" value="1600" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="komodo" />
|
||||||
|
<option name="id" value="komodo" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 9 Pro XL" />
|
||||||
|
<option name="screenDensity" value="360" />
|
||||||
|
<option name="screenX" value="1008" />
|
||||||
|
<option name="screenY" value="2244" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="lynx" />
|
||||||
|
<option name="id" value="lynx" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 7a" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2400" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="motorola" />
|
||||||
|
<option name="codename" value="maui" />
|
||||||
|
<option name="id" value="maui" />
|
||||||
|
<option name="manufacturer" value="Motorola" />
|
||||||
|
<option name="name" value="moto g play - 2023" />
|
||||||
|
<option name="screenDensity" value="280" />
|
||||||
|
<option name="screenX" value="720" />
|
||||||
|
<option name="screenY" value="1600" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="31" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="oriole" />
|
||||||
|
<option name="id" value="oriole" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 6" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2400" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="panther" />
|
||||||
|
<option name="id" value="panther" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 7" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2400" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="q5q" />
|
||||||
|
<option name="id" value="q5q" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy Z Fold5" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1812" />
|
||||||
|
<option name="screenY" value="2176" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="samsung" />
|
||||||
|
<option name="codename" value="q6q" />
|
||||||
|
<option name="id" value="q6q" />
|
||||||
|
<option name="manufacturer" value="Samsung" />
|
||||||
|
<option name="name" value="Galaxy Z Fold6" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1856" />
|
||||||
|
<option name="screenY" value="2160" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="30" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="r11" />
|
||||||
|
<option name="id" value="r11" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel Watch" />
|
||||||
|
<option name="screenDensity" value="320" />
|
||||||
|
<option name="screenX" value="384" />
|
||||||
|
<option name="screenY" value="384" />
|
||||||
|
<option name="type" value="WEAR_OS" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="30" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="redfin" />
|
||||||
|
<option name="id" value="redfin" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 5" />
|
||||||
|
<option name="screenDensity" value="440" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2340" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="shiba" />
|
||||||
|
<option name="id" value="shiba" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 8" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2400" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="33" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="tangorpro" />
|
||||||
|
<option name="id" value="tangorpro" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel Tablet" />
|
||||||
|
<option name="screenDensity" value="320" />
|
||||||
|
<option name="screenX" value="1600" />
|
||||||
|
<option name="screenY" value="2560" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="34" />
|
||||||
|
<option name="brand" value="google" />
|
||||||
|
<option name="codename" value="tokay" />
|
||||||
|
<option name="id" value="tokay" />
|
||||||
|
<option name="manufacturer" value="Google" />
|
||||||
|
<option name="name" value="Pixel 9" />
|
||||||
|
<option name="screenDensity" value="420" />
|
||||||
|
<option name="screenX" value="1080" />
|
||||||
|
<option name="screenY" value="2424" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
2
.idea/vcs.xml
generated
2
.idea/vcs.xml
generated
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,6 +1,10 @@
|
|||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
alias(libs.plugins.jetbrains.kotlin.android)
|
alias(libs.plugins.jetbrains.kotlin.android)
|
||||||
|
id("kotlin-kapt")
|
||||||
|
id ("androidx.navigation.safeargs")
|
||||||
|
id("kotlin-parcelize")
|
||||||
|
// id("com.google.dagger.hilt.android")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
@ -9,7 +13,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.alya.ecommerce_serang"
|
applicationId = "com.alya.ecommerce_serang"
|
||||||
minSdk = 24
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0"
|
versionName = "1.0"
|
||||||
@ -19,21 +23,26 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
buildConfigField("String", "BASE_URL", "\"http://192.168.1.13:3000/\"")
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = false
|
||||||
proguardFiles(
|
proguardFiles(
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
debug {
|
||||||
|
buildConfigField("String", "BASE_URL", "\"http://192.168.1.13:3000/\"")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "1.8"
|
jvmTarget = "11"
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
|
buildConfig = true
|
||||||
viewBinding = true
|
viewBinding = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,7 +54,31 @@ dependencies {
|
|||||||
implementation(libs.material)
|
implementation(libs.material)
|
||||||
implementation(libs.androidx.activity)
|
implementation(libs.androidx.activity)
|
||||||
implementation(libs.androidx.constraintlayout)
|
implementation(libs.androidx.constraintlayout)
|
||||||
|
implementation(libs.androidx.legacy.support.v4)
|
||||||
|
implementation(libs.androidx.lifecycle.livedata.ktx)
|
||||||
|
implementation(libs.androidx.lifecycle.viewmodel.ktx)
|
||||||
|
implementation(libs.androidx.fragment.ktx)
|
||||||
|
implementation(libs.androidx.navigation.fragment.ktx)
|
||||||
|
implementation(libs.androidx.navigation.ui.ktx)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
androidTestImplementation(libs.androidx.junit)
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
|
||||||
|
//retrofit
|
||||||
|
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||||
|
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||||
|
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
|
||||||
|
|
||||||
|
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||||
|
implementation("androidx.paging:paging-runtime:3.2.1")
|
||||||
|
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||||
|
|
||||||
|
|
||||||
|
// implementation(libs.hilt.android)
|
||||||
|
// kapt("com.google.dagger:hilt-compiler:2.48")
|
||||||
|
//
|
||||||
|
// // For ViewModel injection (if needed)
|
||||||
|
// implementation(libs.androidx.hilt.lifecycle.viewmodel)
|
||||||
|
// kapt("androidx.hilt:hilt-compiler:1.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
@ -11,7 +13,9 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Ecommerce_serang"
|
android:theme="@style/Theme.Ecommerce_serang"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31"
|
||||||
|
android:usesCleartextTraffic="true"
|
||||||
|
android:networkSecurityConfig="@xml/network_security_config">
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.TokoSayaActivity"
|
android:name=".ui.TokoSayaActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
7
app/src/main/java/com/alya/ecommerce_serang/app/App.kt
Normal file
7
app/src/main/java/com/alya/ecommerce_serang/app/App.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package com.alya.ecommerce_serang.app
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
|
||||||
|
//@HiltAndroidApp
|
||||||
|
class App : Application(){
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.api.dto
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class Category(
|
||||||
|
val id: String,
|
||||||
|
val image: String,
|
||||||
|
val title: String
|
||||||
|
): Parcelable
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.api.dto
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class DetailProduct(
|
||||||
|
val category: String,
|
||||||
|
val description: String,
|
||||||
|
val discount: Double?,
|
||||||
|
@SerializedName("favorite")
|
||||||
|
val wishlist: Boolean,
|
||||||
|
val id: String,
|
||||||
|
val images: List<String>,
|
||||||
|
@SerializedName("in_stock")
|
||||||
|
val inStock: Int,
|
||||||
|
val price: Double,
|
||||||
|
val rating: Double,
|
||||||
|
val related: List<Product>,
|
||||||
|
val reviews: Int,
|
||||||
|
val title: String,
|
||||||
|
@SerializedName("free_delivery")
|
||||||
|
val freeDelivery:Boolean
|
||||||
|
)
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.api.dto
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class Product (
|
||||||
|
val id: String,
|
||||||
|
val discount: Double?,
|
||||||
|
@SerializedName("favorite")
|
||||||
|
var wishlist: Boolean,
|
||||||
|
val image: String,
|
||||||
|
val price: Double,
|
||||||
|
val rating: Double,
|
||||||
|
@SerializedName("rating_count")
|
||||||
|
val ratingCount: Int,
|
||||||
|
val title: String,
|
||||||
|
)
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.api.response
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class AllProductResponse(
|
||||||
|
|
||||||
|
@field:SerializedName("message")
|
||||||
|
val message: String,
|
||||||
|
|
||||||
|
@field:SerializedName("products")
|
||||||
|
val products: List<ProductsItem>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class ProductsItem(
|
||||||
|
|
||||||
|
@field:SerializedName("store_id")
|
||||||
|
val storeId: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("image")
|
||||||
|
val image: String,
|
||||||
|
|
||||||
|
@field:SerializedName("rating")
|
||||||
|
val rating: String,
|
||||||
|
|
||||||
|
@field:SerializedName("description")
|
||||||
|
val description: String,
|
||||||
|
|
||||||
|
@field:SerializedName("weight")
|
||||||
|
val weight: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("is_pre_order")
|
||||||
|
val isPreOrder: Boolean,
|
||||||
|
|
||||||
|
@field:SerializedName("category_id")
|
||||||
|
val categoryId: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("price")
|
||||||
|
val price: String,
|
||||||
|
|
||||||
|
@field:SerializedName("name")
|
||||||
|
val name: String,
|
||||||
|
|
||||||
|
@field:SerializedName("id")
|
||||||
|
val id: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("min_order")
|
||||||
|
val minOrder: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("total_sold")
|
||||||
|
val totalSold: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("stock")
|
||||||
|
val stock: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("status")
|
||||||
|
val status: String
|
||||||
|
)
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.api.response
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class ProductResponse(
|
||||||
|
|
||||||
|
@field:SerializedName("product")
|
||||||
|
val product: Product,
|
||||||
|
|
||||||
|
@field:SerializedName("message")
|
||||||
|
val message: String
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Product(
|
||||||
|
|
||||||
|
@field:SerializedName("store_id")
|
||||||
|
val storeId: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("image")
|
||||||
|
val image: String,
|
||||||
|
|
||||||
|
@field:SerializedName("rating")
|
||||||
|
val rating: String,
|
||||||
|
|
||||||
|
@field:SerializedName("description")
|
||||||
|
val description: String,
|
||||||
|
|
||||||
|
@field:SerializedName("weight")
|
||||||
|
val weight: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("product_name")
|
||||||
|
val productName: String,
|
||||||
|
|
||||||
|
@field:SerializedName("is_pre_order")
|
||||||
|
val isPreOrder: Boolean,
|
||||||
|
|
||||||
|
@field:SerializedName("duration")
|
||||||
|
val duration: Any,
|
||||||
|
|
||||||
|
@field:SerializedName("category_id")
|
||||||
|
val categoryId: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("price")
|
||||||
|
val price: String,
|
||||||
|
|
||||||
|
@field:SerializedName("product_id")
|
||||||
|
val productId: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("min_order")
|
||||||
|
val minOrder: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("total_sold")
|
||||||
|
val totalSold: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("stock")
|
||||||
|
val stock: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("product_category")
|
||||||
|
val productCategory: String
|
||||||
|
)
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.api.retrofit
|
||||||
|
|
||||||
|
import com.alya.ecommerce_serang.BuildConfig
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
|
|
||||||
|
class ApiConfig {
|
||||||
|
companion object{
|
||||||
|
fun getApiService(): ApiService {
|
||||||
|
val loggingInterceptor =
|
||||||
|
HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
|
||||||
|
val client = OkHttpClient.Builder()
|
||||||
|
.addInterceptor(loggingInterceptor)
|
||||||
|
.build()
|
||||||
|
val retrofit = Retrofit.Builder()
|
||||||
|
.baseUrl(BuildConfig.BASE_URL)
|
||||||
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
|
.client(client)
|
||||||
|
.build()
|
||||||
|
return retrofit.create(ApiService::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.api.retrofit
|
||||||
|
|
||||||
|
import com.alya.ecommerce_serang.data.api.response.AllProductResponse
|
||||||
|
import com.alya.ecommerce_serang.data.api.response.ProductResponse
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Header
|
||||||
|
import retrofit2.http.Path
|
||||||
|
|
||||||
|
interface ApiService {
|
||||||
|
@GET("product")
|
||||||
|
fun getAllProduct(
|
||||||
|
@Header("Authorization") token: String = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzEsIm5hbWUiOiJhbHlhIiwiZW1haWwiOiJha3VuYmVsYWphci5hbHlhQGdtYWlsLmNvbSIsInJvbGUiOiJ1c2VyIiwiaWF0IjoxNzM4NDg0OTc0LCJleHAiOjE3NDEwNzY5NzR9.0JyXJQ_6CKiZEi0gvk1gcn-0ILu3a9lOr3HqjhJXbBE"
|
||||||
|
): Call<AllProductResponse>
|
||||||
|
|
||||||
|
|
||||||
|
@GET("product/detail/{id}")
|
||||||
|
fun getDetailProduct (
|
||||||
|
@Header("Authorization") token: String,
|
||||||
|
@Path("id") productId: Int
|
||||||
|
): Call<ProductResponse>
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.model
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
data class Product(
|
||||||
|
|
||||||
|
@field:SerializedName("store_id")
|
||||||
|
val storeId: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("image")
|
||||||
|
val image: String,
|
||||||
|
|
||||||
|
@field:SerializedName("rating")
|
||||||
|
val rating: String,
|
||||||
|
|
||||||
|
@field:SerializedName("description")
|
||||||
|
val description: String,
|
||||||
|
|
||||||
|
@field:SerializedName("weight")
|
||||||
|
val weight: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("product_name")
|
||||||
|
val productName: String,
|
||||||
|
|
||||||
|
@field:SerializedName("is_pre_order")
|
||||||
|
val isPreOrder: Boolean,
|
||||||
|
|
||||||
|
@field:SerializedName("duration")
|
||||||
|
val duration: Any,
|
||||||
|
|
||||||
|
@field:SerializedName("category_id")
|
||||||
|
val categoryId: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("price")
|
||||||
|
val price: String,
|
||||||
|
|
||||||
|
@field:SerializedName("product_id")
|
||||||
|
val productId: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("min_order")
|
||||||
|
val minOrder: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("total_sold")
|
||||||
|
val totalSold: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("stock")
|
||||||
|
val stock: Int,
|
||||||
|
|
||||||
|
@field:SerializedName("product_category")
|
||||||
|
val productCategory: String
|
||||||
|
)
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.model
|
||||||
|
|
||||||
|
data class User(
|
||||||
|
val username: String,
|
||||||
|
val avatar:String?,
|
||||||
|
val email:String,
|
||||||
|
val firstName:String?,
|
||||||
|
val lastName:String?
|
||||||
|
)
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.alya.ecommerce_serang.data.repository
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import com.alya.ecommerce_serang.data.api.response.ProductsItem
|
||||||
|
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class ProductRepository(private val apiService: ApiService) {
|
||||||
|
suspend fun getAllProducts(): Result<List<ProductsItem>> =
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
Log.d("ProductRepository", "Attempting to fetch products")
|
||||||
|
val response = apiService.getAllProduct().execute()
|
||||||
|
Log.d("ProductRepository", "Response received. Success: ${response.isSuccessful}")
|
||||||
|
Log.d("ProductRepository", "Response code: ${response.code()}")
|
||||||
|
Log.d("ProductRepository", "Response message: ${response.message()}")
|
||||||
|
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
Result.success(response.body()?.products ?: emptyList())
|
||||||
|
} else {
|
||||||
|
Result.failure(Exception("Failed to fetch products"))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Result.failure(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// suspend fun getCategories():List<Category>
|
||||||
|
//
|
||||||
|
// fun getProducts(query: ProductQuery) : Flow<PagingData<Product>>
|
||||||
|
// fun getRecentSearchs(): Flow<List<String>>
|
||||||
|
// suspend fun clearRecents()
|
||||||
|
// suspend fun addRecents(search:String)
|
||||||
|
// suspend fun getProduct(id:String):DetailProduct
|
||||||
|
}
|
@ -1,31 +1,57 @@
|
|||||||
package com.alya.ecommerce_serang.ui
|
package com.alya.ecommerce_serang.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import com.alya.ecommerce_serang.R
|
import com.alya.ecommerce_serang.R
|
||||||
import com.alya.ecommerce_serang.databinding.ActivityMainBinding
|
import com.alya.ecommerce_serang.databinding.ActivityMainBinding
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
||||||
|
|
||||||
|
|
||||||
|
//@AndroidEntryPoint
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
|
private val navController by lazy {
|
||||||
|
(supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController
|
||||||
|
}
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
enableEdgeToEdge()
|
setupBottomNavigation()
|
||||||
setContentView(R.layout.activity_main)
|
observeDestinationChanges()
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
|
||||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
|
||||||
insets
|
|
||||||
}
|
|
||||||
|
|
||||||
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_navigation)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupBottomNavigation() {
|
||||||
|
binding.bottomNavigation.setupWithNavController(navController)
|
||||||
|
|
||||||
|
binding.bottomNavigation.setOnItemSelectedListener { menuItem ->
|
||||||
|
when (menuItem.itemId) {
|
||||||
|
R.id.home_item_fragment -> {
|
||||||
|
navController.navigate(R.id.homeFragment)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.chat_item_fragment -> {
|
||||||
|
navController.navigate(R.id.chatFragment)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.profile_item_fragment -> {
|
||||||
|
navController.navigate(R.id.profileFragment)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeDestinationChanges() {
|
||||||
|
navController.addOnDestinationChangedListener { _, destination, _ ->
|
||||||
|
binding.bottomNavigation.isVisible = when (destination.id) {
|
||||||
|
R.id.homeFragment, R.id.chatFragment, R.id.profileFragment -> true
|
||||||
|
else -> false // Bottom Navigation tidak terlihat di layar lain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.chat
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import com.alya.ecommerce_serang.R
|
||||||
|
|
||||||
|
class ChatFragment : Fragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = ChatFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val viewModel: ChatViewModel by viewModels()
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
// TODO: Use the ViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
return inflater.inflate(R.layout.fragment_chat, container, false)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.chat
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
||||||
|
class ChatViewModel : ViewModel() {
|
||||||
|
// TODO: Implement the ViewModel
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.home
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.alya.ecommerce_serang.data.api.dto.Category
|
||||||
|
import com.alya.ecommerce_serang.databinding.ItemCategoryHomeBinding
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
|
||||||
|
class HomeCategoryAdapter(
|
||||||
|
private val categories:List<Category>,
|
||||||
|
//A lambda function that will be invoked when a category item is clicked.
|
||||||
|
private val onClick:(category:Category) -> Unit
|
||||||
|
): RecyclerView.Adapter<HomeCategoryAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
ViewHolder is responsible for caching and managing the view references for each item in
|
||||||
|
the RecyclerView.It binds the Category data to the corresponding views within the item layout.
|
||||||
|
*/
|
||||||
|
inner class ViewHolder(private val binding: ItemCategoryHomeBinding): RecyclerView.ViewHolder(binding.root){
|
||||||
|
fun bind(category: Category) = with(binding){
|
||||||
|
Glide.with(root).load(category.image).into(image)
|
||||||
|
name.text = category.title
|
||||||
|
root.setOnClickListener{
|
||||||
|
onClick(category)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder (
|
||||||
|
ItemCategoryHomeBinding.inflate(LayoutInflater.from(parent.context),parent,false)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getItemCount() = categories.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
holder.bind(categories[position])
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.home
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.alya.ecommerce_serang.R
|
||||||
|
import com.alya.ecommerce_serang.data.api.response.ProductsItem
|
||||||
|
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||||
|
import com.alya.ecommerce_serang.data.repository.ProductRepository
|
||||||
|
import com.alya.ecommerce_serang.databinding.FragmentHomeBinding
|
||||||
|
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||||
|
import com.alya.ecommerce_serang.utils.HorizontalMarginItemDecoration
|
||||||
|
import com.alya.ecommerce_serang.utils.setLightStatusBar
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
//@AndroidEntryPoint
|
||||||
|
class HomeFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentHomeBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
private lateinit var viewModel: HomeViewModel
|
||||||
|
private var productAdapter: HorizontalProductAdapter? = null
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val repository = ProductRepository(ApiConfig.getApiService())
|
||||||
|
viewModel = ViewModelProvider(
|
||||||
|
this,
|
||||||
|
// Pass a lambda that creates the ViewModel
|
||||||
|
BaseViewModelFactory {
|
||||||
|
HomeViewModel(repository)
|
||||||
|
}
|
||||||
|
)[HomeViewModel::class.java]
|
||||||
|
|
||||||
|
initUi()
|
||||||
|
setupRecyclerView()
|
||||||
|
observeData()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupRecyclerView() {
|
||||||
|
productAdapter = HorizontalProductAdapter(
|
||||||
|
products = emptyList(),
|
||||||
|
onClick = { product -> handleProductClick(product) }
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.newProducts.apply {
|
||||||
|
adapter = productAdapter
|
||||||
|
layoutManager = LinearLayoutManager(
|
||||||
|
context,
|
||||||
|
LinearLayoutManager.HORIZONTAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeData() {
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
viewModel.uiState.collect { state ->
|
||||||
|
when (state) {
|
||||||
|
is HomeUiState.Loading -> {
|
||||||
|
binding.loading.root.isVisible = true
|
||||||
|
binding.error.root.isVisible = false
|
||||||
|
binding.home.isVisible = false
|
||||||
|
}
|
||||||
|
is HomeUiState.Success -> {
|
||||||
|
binding.loading.root.isVisible = false
|
||||||
|
binding.error.root.isVisible = false
|
||||||
|
binding.home.isVisible = true
|
||||||
|
productAdapter?.updateProducts(state.products)
|
||||||
|
}
|
||||||
|
is HomeUiState.Error -> {
|
||||||
|
binding.loading.root.isVisible = false
|
||||||
|
binding.error.root.isVisible = true
|
||||||
|
binding.home.isVisible = false
|
||||||
|
binding.error.errorMessage.text = state.message
|
||||||
|
binding.error.retryButton.setOnClickListener {
|
||||||
|
viewModel.retry()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initUi() {
|
||||||
|
// For LightStatusBar
|
||||||
|
setLightStatusBar()
|
||||||
|
val banners = binding.banners
|
||||||
|
banners.offscreenPageLimit = 1
|
||||||
|
|
||||||
|
val nextItemVisiblePx = resources.getDimension(R.dimen.viewpager_next_item_visible)
|
||||||
|
val currentItemHorizontalMarginPx =
|
||||||
|
resources.getDimension(R.dimen.viewpager_current_item_horizontal_margin)
|
||||||
|
val pageTranslationX = nextItemVisiblePx + currentItemHorizontalMarginPx
|
||||||
|
|
||||||
|
banners.setPageTransformer { page, position ->
|
||||||
|
page.translationX = -pageTranslationX * position
|
||||||
|
page.scaleY = 1 - (0.25f * kotlin.math.abs(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
banners.addItemDecoration(
|
||||||
|
HorizontalMarginItemDecoration(
|
||||||
|
requireContext(),
|
||||||
|
R.dimen.viewpager_current_item_horizontal_margin
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun handleProductClick(product: ProductsItem) {
|
||||||
|
// Navigate to product detail
|
||||||
|
// findNavController().navigate(
|
||||||
|
// HomeFragmentDirections.actionHomeToDetail(product.id)
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showLoading(isLoading: Boolean) {
|
||||||
|
if (isLoading) {
|
||||||
|
binding.progressBar.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.progressBar.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.home
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.alya.ecommerce_serang.data.api.response.AllProductResponse
|
||||||
|
import com.alya.ecommerce_serang.data.api.response.ProductsItem
|
||||||
|
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||||
|
import com.alya.ecommerce_serang.data.repository.ProductRepository
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class HomeViewModel (
|
||||||
|
private val productRepository: ProductRepository
|
||||||
|
): ViewModel() {
|
||||||
|
private val _uiState = MutableStateFlow<HomeUiState>(HomeUiState.Loading)
|
||||||
|
val uiState: StateFlow<HomeUiState> = _uiState.asStateFlow()
|
||||||
|
val home = MutableLiveData<AllProductResponse?>(null)
|
||||||
|
constructor() : this(ProductRepository(ApiConfig.getApiService()))
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
loadProducts()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadProducts() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
_uiState.value = HomeUiState.Loading
|
||||||
|
productRepository.getAllProducts()
|
||||||
|
.onSuccess { products ->
|
||||||
|
_uiState.value = HomeUiState.Success(products)
|
||||||
|
}
|
||||||
|
.onFailure { error ->
|
||||||
|
_uiState.value = HomeUiState.Error(error.message ?: "Unknown error")
|
||||||
|
Log.e("ProductViewModel", "Products fetch failed", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun retry() {
|
||||||
|
loadProducts()
|
||||||
|
}
|
||||||
|
|
||||||
|
// fun toggleWishlist(product: Product) = viewModelScope.launch {
|
||||||
|
// try {
|
||||||
|
// productRepository.toggleWishlist(product.id,product.wishlist)
|
||||||
|
// }catch (e:Exception){
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class HomeUiState {
|
||||||
|
object Loading : HomeUiState()
|
||||||
|
data class Success(val products: List<ProductsItem>) : HomeUiState()
|
||||||
|
data class Error(val message: String) : HomeUiState()
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.home
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.alya.ecommerce_serang.data.api.response.ProductsItem
|
||||||
|
import com.alya.ecommerce_serang.databinding.ItemProductHorizontalBinding
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
|
||||||
|
class HorizontalProductAdapter(
|
||||||
|
private var products: List<ProductsItem>,
|
||||||
|
private val onClick: (ProductsItem) -> Unit
|
||||||
|
) : RecyclerView.Adapter<HorizontalProductAdapter.ProductViewHolder>() {
|
||||||
|
|
||||||
|
inner class ProductViewHolder(private val binding: ItemProductHorizontalBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
fun bind(product: ProductsItem) = with(binding) {
|
||||||
|
itemName.text = product.name
|
||||||
|
itemPrice.text = product.price
|
||||||
|
rating.text = product.rating
|
||||||
|
// productSold.text = "${product.totalSold} sold"
|
||||||
|
|
||||||
|
// Load image using Glide
|
||||||
|
Glide.with(itemView)
|
||||||
|
// .load("${BuildConfig.BASE_URL}/product/${product.image}")
|
||||||
|
// .load("${BuildConfig.BASE_URL}/${product.image}")
|
||||||
|
.load(product.image)
|
||||||
|
.into(image)
|
||||||
|
|
||||||
|
root.setOnClickListener { onClick(product) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
|
||||||
|
val binding = ItemProductHorizontalBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context), parent, false
|
||||||
|
)
|
||||||
|
return ProductViewHolder(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = products.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
|
||||||
|
holder.bind(products[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateProducts(newProducts: List<ProductsItem>) {
|
||||||
|
products = newProducts
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.product
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.alya.ecommerce_serang.R
|
||||||
|
import com.alya.ecommerce_serang.data.api.dto.Product
|
||||||
|
import com.alya.ecommerce_serang.databinding.ItemProductHorizontalBinding
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
|
||||||
|
class ProductViewHolder(private val binding: ItemProductHorizontalBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(
|
||||||
|
product: Product,
|
||||||
|
onClick: (product: Product) -> Unit,
|
||||||
|
) = with(binding) {
|
||||||
|
Glide.with(root).load(product.image).into(image)
|
||||||
|
|
||||||
|
// discount.isVisible = product.discount != null
|
||||||
|
// product.discount?.let {
|
||||||
|
// val discount = (product.discount / product.price * 100).roundToInt()
|
||||||
|
// binding.discount.text =
|
||||||
|
// root.context.getString(R.string.fragment_item_product_discount, discount)
|
||||||
|
// }
|
||||||
|
|
||||||
|
itemName.text = product.title
|
||||||
|
rating.text = String.format("%.1f", product.rating)
|
||||||
|
|
||||||
|
// val current = product.price - (product.discount ?: 0.0)
|
||||||
|
val current = product.price
|
||||||
|
itemPrice.text = root.context.getString(R.string.item_price_txt, current)
|
||||||
|
|
||||||
|
root.setOnClickListener {
|
||||||
|
onClick(product)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.profile
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import com.alya.ecommerce_serang.R
|
||||||
|
|
||||||
|
class ProfileFragment : Fragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = ProfileFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val viewModel: ProfileViewModel by viewModels()
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
// TODO: Use the ViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
return inflater.inflate(R.layout.fragment_profile, container, false)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.alya.ecommerce_serang.ui.profile
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
||||||
|
class ProfileViewModel : ViewModel() {
|
||||||
|
// TODO: Implement the ViewModel
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.alya.ecommerce_serang.utils
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
|
||||||
|
typealias Inflate<T> = (LayoutInflater, ViewGroup?, Boolean) -> T
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.alya.ecommerce_serang.utils
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
|
||||||
|
class BaseViewModelFactory<VM : ViewModel>(
|
||||||
|
private val creator: () -> VM
|
||||||
|
) : ViewModelProvider.Factory {
|
||||||
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return creator() as T
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.alya.ecommerce_serang.utils
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import android.view.View
|
||||||
|
import android.view.WindowInsetsController
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
|
||||||
|
fun Fragment.setLightStatusBar(){
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
requireActivity().window.insetsController?.setSystemBarsAppearance(
|
||||||
|
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
|
||||||
|
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS)
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
requireActivity().window.decorView.systemUiVisibility = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
||||||
|
} else {
|
||||||
|
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.alya.ecommerce_serang.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.view.View
|
||||||
|
import androidx.annotation.DimenRes
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
||||||
|
class HorizontalMarginItemDecoration(context: Context, @DimenRes horizontalMarginInDp: Int) :
|
||||||
|
RecyclerView.ItemDecoration() {
|
||||||
|
|
||||||
|
private val horizontalMarginInPx: Int =
|
||||||
|
context.resources.getDimension(horizontalMarginInDp).toInt()
|
||||||
|
|
||||||
|
override fun getItemOffsets(
|
||||||
|
outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State
|
||||||
|
) {
|
||||||
|
outRect.right = horizontalMarginInPx
|
||||||
|
outRect.left = horizontalMarginInPx
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.alya.ecommerce_serang.utils
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import com.alya.ecommerce_serang.data.api.dto.Category
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class ProductQuery (
|
||||||
|
val category: Category? = null,
|
||||||
|
val search:String? = null,
|
||||||
|
val range:Pair<Float,Float> = 0f to 10000f,
|
||||||
|
val rating:Int? = null,
|
||||||
|
val discount:Int? = null,
|
||||||
|
val sort:List<Sort> = emptyList(),
|
||||||
|
val favorite:Boolean = false
|
||||||
|
): Parcelable
|
||||||
|
|
||||||
|
enum class Sort{
|
||||||
|
disconunt, voucher, shipping, delivery
|
||||||
|
}
|
BIN
app/src/main/res/drawable/banner_default.jpg
Normal file
BIN
app/src/main/res/drawable/banner_default.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.9 KiB |
5
app/src/main/res/drawable/baseline_account_circle_24.xml
Normal file
5
app/src/main/res/drawable/baseline_account_circle_24.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#489EC6" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,6c1.93,0 3.5,1.57 3.5,3.5S13.93,13 12,13s-3.5,-1.57 -3.5,-3.5S10.07,6 12,6zM12,20c-2.03,0 -4.43,-0.82 -6.14,-2.88C7.55,15.8 9.68,15 12,15s4.45,0.8 6.14,2.12C16.43,19.18 14.03,20 12,20z"/>
|
||||||
|
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/baseline_arrow_back_24.xml
Normal file
5
app/src/main/res/drawable/baseline_arrow_back_24.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#489EC6" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||||
|
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/baseline_chat_24.xml
Normal file
5
app/src/main/res/drawable/baseline_chat_24.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#489EC6" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM6,9h12v2L6,11L6,9zM14,14L6,14v-2h8v2zM18,8L6,8L6,6h12v2z"/>
|
||||||
|
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/baseline_home_24.xml
Normal file
5
app/src/main/res/drawable/baseline_home_24.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#489EC6" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
|
||||||
|
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/baseline_search_24.xml
Normal file
5
app/src/main/res/drawable/baseline_search_24.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#E8ECF2" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@color/soft_gray" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||||
|
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/baseline_star_24.xml
Normal file
5
app/src/main/res/drawable/baseline_star_24.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#FFE86D" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
|
||||||
|
|
||||||
|
</vector>
|
BIN
app/src/main/res/drawable/makanan_ringan.jpg
Normal file
BIN
app/src/main/res/drawable/makanan_ringan.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
8
app/src/main/res/drawable/outline_notifications_24.xml
Normal file
8
app/src/main/res/drawable/outline_notifications_24.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#489EC6" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zM18,16v-5c0,-3.07 -1.63,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.64,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2zM16,17L8,17v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5v6z"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/outline_shopping_cart_24.xml
Normal file
5
app/src/main/res/drawable/outline_shopping_cart_24.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#489EC6" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M15.55,13c0.75,0 1.41,-0.41 1.75,-1.03l3.58,-6.49c0.37,-0.66 -0.11,-1.48 -0.87,-1.48L5.21,4l-0.94,-2L1,2v2h2l3.6,7.59 -1.35,2.44C4.52,15.37 5.48,17 7,17h12v-2L7,15l1.1,-2h7.45zM6.16,6h12.15l-2.76,5L8.53,11L6.16,6zM7,18c-1.1,0 -1.99,0.9 -1.99,2S5.9,22 7,22s2,-0.9 2,-2 -0.9,-2 -2,-2zM17,18c-1.1,0 -1.99,0.9 -1.99,2s0.89,2 1.99,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
||||||
|
|
||||||
|
</vector>
|
7
app/src/main/res/drawable/rating_background.xml
Normal file
7
app/src/main/res/drawable/rating_background.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<stroke android:width="1dp"
|
||||||
|
android:color="#33B8BBC6"/>
|
||||||
|
<corners android:radius="11dp"/>
|
||||||
|
</selector>
|
6
app/src/main/res/drawable/search_background.xml
Normal file
6
app/src/main/res/drawable/search_background.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<stroke android:width="1dp"
|
||||||
|
android:color="@color/soft_gray"/>
|
||||||
|
<corners android:radius="15dp"/>
|
||||||
|
</shape>
|
8
app/src/main/res/drawable/selector_account.xml
Normal file
8
app/src/main/res/drawable/selector_account.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:state_checked="true"
|
||||||
|
android:drawable="@drawable/baseline_account_circle_24" />
|
||||||
|
<item
|
||||||
|
android:drawable="@drawable/outline_account_circle_24" />
|
||||||
|
</selector>
|
8
app/src/main/res/drawable/selector_chat.xml
Normal file
8
app/src/main/res/drawable/selector_chat.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:state_checked="true"
|
||||||
|
android:drawable="@drawable/baseline_chat_24" />
|
||||||
|
<item
|
||||||
|
android:drawable="@drawable/outline_chat_24" />
|
||||||
|
</selector>
|
8
app/src/main/res/drawable/selector_home.xml
Normal file
8
app/src/main/res/drawable/selector_home.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:state_checked="true"
|
||||||
|
android:drawable="@drawable/baseline_home_24" />
|
||||||
|
<item
|
||||||
|
android:drawable="@drawable/outline_home_24" />
|
||||||
|
</selector>
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
@ -8,25 +8,36 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.MainActivity">
|
tools:context=".ui.MainActivity">
|
||||||
|
|
||||||
|
<!-- NavHostFragment -->
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@+id/nav_host_fragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
|
||||||
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
|
app:defaultNavHost="true"
|
||||||
|
app:navGraph="@navigation/nav_graph" />
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.divider.MaterialDivider
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/divider"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:text="Hello World!"
|
android:layout_height="1dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:dividerColor="@color/gray_1"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintBottom_toTopOf="@id/bottom_navigation" />
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
<!-- BottomNavigationView -->
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
android:id="@+id/bottom_navigation"
|
android:id="@+id/bottom_navigation"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
style="@style/Widget.Material3.BottomNavigationView"
|
style="@style/Widget.Material3.BottomNavigationView"
|
||||||
app:menu="@menu/bottom_navigation_menu"
|
app:menu="@menu/bottom_navigation_menu"
|
||||||
app:itemIconTint="#489EC6"
|
app:itemIconTint="#489EC6"
|
||||||
app:itemIconSize="@dimen/m3_comp_navigation_bar_active_indicator_height" />
|
app:itemIconSize="@dimen/m3_comp_navigation_bar_active_indicator_height" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
||||||
|
13
app/src/main/res/layout/fragment_chat.xml
Normal file
13
app/src/main/res/layout/fragment_chat.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".ui.chat.ChatFragment">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="Hello" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
145
app/src/main/res/layout/fragment_home.xml
Normal file
145
app/src/main/res/layout/fragment_home.xml
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
tools:context=".ui.home.HomeFragment">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/home"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/searchContainer"
|
||||||
|
layout="@layout/view_search"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="19dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
style="?android:attr/progressBarStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
android:id="@+id/banners"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="132dp"
|
||||||
|
android:layout_marginTop="23dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/searchContainer"
|
||||||
|
tools:layout_editor_absoluteX="16dp" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/categoriesText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="@string/fragment_home_categories"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="22sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/banners" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/showAll"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:text="@string/show_all"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/blue1"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@id/categoriesText"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/categories"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="19dp"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/categoriesText"
|
||||||
|
tools:layout_editor_absoluteX="0dp"
|
||||||
|
tools:listitem="@layout/item_category_home" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/new_products_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="@string/new_products_text"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="22sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/categories" />
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/productshowAll"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:text="@string/show_all"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/blue1"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@id/new_products_text"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/new_products"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/new_products_text"
|
||||||
|
tools:itemCount="5"
|
||||||
|
tools:listitem="@layout/item_section_horizontal" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/loading"
|
||||||
|
layout="@layout/view_loading"/>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/error"
|
||||||
|
layout="@layout/view_error"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <com.zhpan.indicator.IndicatorView-->
|
||||||
|
<!-- android:id="@+id/indicator"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_marginTop="20dp"-->
|
||||||
|
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||||
|
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||||
|
<!-- app:layout_constraintTop_toBottomOf="@+id/banners" />-->
|
13
app/src/main/res/layout/fragment_profile.xml
Normal file
13
app/src/main/res/layout/fragment_profile.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".ui.profile.ProfileFragment">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="Hello" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
6
app/src/main/res/layout/item_category.xml
Normal file
6
app/src/main/res/layout/item_category.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
36
app/src/main/res/layout/item_category_home.xml
Normal file
36
app/src/main/res/layout/item_category_home.xml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="88dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:id="@+id/imageLayout"
|
||||||
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
app:cardCornerRadius="14dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:strokeColor="@color/gray_1">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:src="@drawable/makanan_ringan"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/name"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:text="@string/fragment_home_item_categories"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/imageLayout"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:layout_marginTop="12dp"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
68
app/src/main/res/layout/item_product_horizontal.xml
Normal file
68
app/src/main/res/layout/item_product_horizontal.xml
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="185dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/imageLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:cardCornerRadius="14dp"
|
||||||
|
app:layout_constraintDimensionRatio="272:218"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:cardElevation="0dp"
|
||||||
|
app:strokeColor="@color/gray_1"
|
||||||
|
app:strokeWidth="1dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@color/blue1" />
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/item_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="17dp"
|
||||||
|
android:text="Banana"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/dmsans_medium"
|
||||||
|
android:textSize="18sp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/imageLayout" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/item_price"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/item_price_txt"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="18sp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/item_name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/rating"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/rating_background"
|
||||||
|
android:drawablePadding="4dp"
|
||||||
|
android:paddingStart="7dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingEnd="11dp"
|
||||||
|
android:paddingBottom="3dp"
|
||||||
|
android:text="@string/rating"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:fontFamily="@font/dmsans_regular"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:gravity="center"
|
||||||
|
app:drawableStartCompat="@drawable/baseline_star_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/item_price" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
46
app/src/main/res/layout/item_section_horizontal.xml
Normal file
46
app/src/main/res/layout/item_section_horizontal.xml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_marginVertical="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:text="All grocery"
|
||||||
|
android:textSize="22sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/showAll"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:text="@string/show_all"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/blue1"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@id/title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/products"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="23dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:clipChildren="false"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/title"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
tools:listitem="@layout/item_product_horizontal"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
46
app/src/main/res/layout/item_section_vertical.xml
Normal file
46
app/src/main/res/layout/item_section_vertical.xml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginVertical="20dp"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:text="All grocery"
|
||||||
|
android:textSize="22sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/showAll"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:text="@string/show_all"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@color/blue1"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@id/title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/products"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingVertical="25dp"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/title"
|
||||||
|
tools:itemCount="5"
|
||||||
|
tools:layout_editor_absoluteX="16dp"
|
||||||
|
tools:listitem="@layout/item_product_horizontal" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
31
app/src/main/res/layout/view_error.xml
Normal file
31
app/src/main/res/layout/view_error.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/errorMessage"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/retryButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/retryButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="Retry"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/errorMessage" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
6
app/src/main/res/layout/view_loading.xml
Normal file
6
app/src/main/res/layout/view_loading.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
49
app/src/main/res/layout/view_search.xml
Normal file
49
app/src/main/res/layout/view_search.xml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/search"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@drawable/search_background"
|
||||||
|
android:hint="@string/fragment_home_search"
|
||||||
|
android:textColor="@color/soft_gray"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:paddingHorizontal="25dp"
|
||||||
|
android:imeOptions="actionSearch"
|
||||||
|
android:inputType="text"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/btn_notification"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:drawableStart="@drawable/baseline_search_24" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_notification"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:backgroundTint="@color/white"
|
||||||
|
android:src="@drawable/outline_notifications_24"
|
||||||
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/search"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/btn_cart"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/search"/>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_cart"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:backgroundTint="@color/white"
|
||||||
|
android:src="@drawable/outline_shopping_cart_24"
|
||||||
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/search"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/search"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,18 +1,18 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/page_1"
|
android:id="@+id/home_item_fragment"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:icon="@drawable/outline_home_24"
|
android:icon="@drawable/selector_home"
|
||||||
android:title="Beranda" />
|
android:title="Beranda" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/page_2"
|
android:id="@+id/chat_item_fragment"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:icon="@drawable/outline_chat_24"
|
android:icon="@drawable/selector_chat"
|
||||||
android:title="Pesan" />
|
android:title="Pesan" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/page_3"
|
android:id="@+id/profile_item_fragment"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:icon="@drawable/outline_account_circle_24"
|
android:icon="@drawable/selector_account"
|
||||||
android:title="Profil" />
|
android:title="Profil" />
|
||||||
</menu>
|
</menu>
|
23
app/src/main/res/navigation/nav_graph.xml
Normal file
23
app/src/main/res/navigation/nav_graph.xml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/nav_graph"
|
||||||
|
app:startDestination="@id/homeFragment">
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/homeFragment"
|
||||||
|
android:name="com.alya.ecommerce_serang.ui.home.HomeFragment"
|
||||||
|
android:label="fragment_home"
|
||||||
|
tools:layout="@layout/fragment_home" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/profileFragment"
|
||||||
|
android:name="com.alya.ecommerce_serang.ui.profile.ProfileFragment"
|
||||||
|
android:label="fragment_profile"
|
||||||
|
tools:layout="@layout/fragment_profile" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/chatFragment"
|
||||||
|
android:name="com.alya.ecommerce_serang.ui.chat.ChatFragment"
|
||||||
|
android:label="fragment_chat"
|
||||||
|
tools:layout="@layout/fragment_chat" />
|
||||||
|
</navigation>
|
@ -36,4 +36,8 @@
|
|||||||
<color name="darkblue_700">#1f2652</color>
|
<color name="darkblue_700">#1f2652</color>
|
||||||
<color name="darkblue_800">#181e40</color>
|
<color name="darkblue_800">#181e40</color>
|
||||||
<color name="darkblue_900">#121731</color>
|
<color name="darkblue_900">#121731</color>
|
||||||
|
|
||||||
|
<color name="gray_1">#E8ECF2</color>
|
||||||
|
<color name="soft_gray">#7D8FAB</color>
|
||||||
|
<color name="blue1">#489EC6</color>
|
||||||
</resources>
|
</resources>
|
@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<dimen name="viewpager_current_item_horizontal_margin">32dp</dimen>
|
||||||
|
<dimen name="viewpager_next_item_visible">16dp</dimen>
|
||||||
<dimen name="horizontal_safe_area">16dp</dimen>
|
<dimen name="horizontal_safe_area">16dp</dimen>
|
||||||
<dimen name="vertical_safe_area">6dp</dimen>
|
<dimen name="vertical_safe_area">6dp</dimen>
|
||||||
</resources>
|
</resources>
|
@ -1,3 +1,16 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">ecommerce_serang</string>
|
<string name="app_name">ecommerce_serang</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Placeholder-->
|
||||||
|
<string name="fragment_home_search">Cari produk</string>
|
||||||
|
<string name="fragment_home_categories">Kategori Produk</string>
|
||||||
|
<string name="fragment_home_item_categories">Makanan Ringan</string>
|
||||||
|
<string name="show_all">Lainnya</string>
|
||||||
|
|
||||||
|
<string name="item_price_txt">Rp%.1f</string>
|
||||||
|
<string name="retry">Coba lagi\n</string>
|
||||||
|
<string name="error_loading">Terdapat error...</string>
|
||||||
|
<string name="new_products_text">Produk Terbaru</string>
|
||||||
|
<string name="rating">4.5</string>
|
||||||
</resources>
|
</resources>
|
@ -1,6 +1,6 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="Theme.Ecommerce_serang" parent="Theme.AppCompat.Light.NoActionBar">
|
<style name="Theme.Ecommerce_serang" parent="Theme.Material3.Light.NoActionBar">
|
||||||
<!-- Customize your light theme here. -->
|
<!-- Customize your light theme here. -->
|
||||||
<item name="colorPrimary">@color/blue_500</item>
|
<item name="colorPrimary">@color/blue_500</item>
|
||||||
<item name="colorPrimaryDark">@color/white</item>
|
<item name="colorPrimaryDark">@color/white</item>
|
||||||
|
13
app/src/main/res/xml/network_security_config.xml
Normal file
13
app/src/main/res/xml/network_security_config.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<network-security-config>
|
||||||
|
<base-config cleartextTrafficPermitted="true">
|
||||||
|
<trust-anchors>
|
||||||
|
<certificates src="system" />
|
||||||
|
<certificates src="user" />
|
||||||
|
</trust-anchors>
|
||||||
|
</base-config>
|
||||||
|
<domain-config cleartextTrafficPermitted="true">
|
||||||
|
<domain includeSubdomains="true">192.168.1.13</domain>
|
||||||
|
<domain includeSubdomains="true">localhost</domain>
|
||||||
|
</domain-config>
|
||||||
|
</network-security-config>
|
@ -1,4 +1,11 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
buildscript {
|
||||||
|
dependencies {
|
||||||
|
classpath ("androidx.navigation:navigation-safe-args-gradle-plugin:2.5.1")
|
||||||
|
// classpath("com.google.dagger:hilt-android-gradle-plugin:2.55")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application) apply false
|
alias(libs.plugins.android.application) apply false
|
||||||
alias(libs.plugins.jetbrains.kotlin.android) apply false
|
alias(libs.plugins.jetbrains.kotlin.android) apply false
|
||||||
|
@ -1,17 +1,27 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.7.3"
|
agp = "8.5.2"
|
||||||
|
hiltAndroid = "2.51"
|
||||||
|
hiltLifecycleViewmodel = "1.0.0-alpha03"
|
||||||
kotlin = "1.9.0"
|
kotlin = "1.9.0"
|
||||||
coreKtx = "1.15.0"
|
coreKtx = "1.10.1"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
junitVersion = "1.2.1"
|
junitVersion = "1.2.1"
|
||||||
espressoCore = "3.6.1"
|
espressoCore = "3.6.1"
|
||||||
appcompat = "1.7.0"
|
appcompat = "1.7.0"
|
||||||
material = "1.12.0"
|
material = "1.12.0"
|
||||||
activity = "1.10.0"
|
activity = "1.9.2"
|
||||||
constraintlayout = "2.2.0"
|
constraintlayout = "2.1.4"
|
||||||
|
legacySupportV4 = "1.0.0"
|
||||||
|
lifecycleLivedataKtx = "2.8.7"
|
||||||
|
lifecycleViewmodelKtx = "2.8.7"
|
||||||
|
fragmentKtx = "1.5.6"
|
||||||
|
navigationFragmentKtx = "2.8.5"
|
||||||
|
navigationUiKtx = "2.8.5"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
|
androidx-hilt-lifecycle-viewmodel = { module = "androidx.hilt:hilt-lifecycle-viewmodel", version.ref = "hiltLifecycleViewmodel" }
|
||||||
|
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
|
||||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||||
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||||
@ -19,6 +29,12 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version
|
|||||||
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||||
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
||||||
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||||
|
androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" }
|
||||||
|
androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
|
||||||
|
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
||||||
|
androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragmentKtx" }
|
||||||
|
androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigationFragmentKtx" }
|
||||||
|
androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
Reference in New Issue
Block a user